Вывод списка при частичном ограничении прав доступа

gerasim

Новичок
Вывод списка при частичном ограничении прав доступа

Возник вопрос. Есть список документов. Есть группы юзеров. Юзерам из некоторых групп запрещен доступ к некотрым из документов. Как сделать корректный постраничный вывод этих документов(ссылок на них), с учетом наложенных на доступ ограничений?

Я пока остановился на варианте, когда при выводе постраничной порции ссылок поверяю права доступа на эту порцию(допустим, 20 штук) документов и не вывожу ссылки на доки, к которым доступ закрыт. Но тут возможен вариант, когда на странице выведется 1 а то и ноль ссылок. Хотя вероятность такой ситуации невысока, но возможна. Не очень хорошо.

Идеально - это если определять права доступа ко всем документам еще на уровне sql, но это, насколько я понимаю, будет очень тяжелая операция, особенно учитывая, что нам в т.ч. надо получить общее количество документов (для пейджинатора). Хотя, возможно, я где-то недодумал.

Кто уже имеет подобный опыт - поделитесь
 

dimagolov

Новичок
gerasim, начни с того, что раскажи, как у тебя организованы права доступа.
 

Grezz

Новичок
Re: Вывод списка при частичном ограничении прав доступа

Автор оригинала: gerasim Идеально - это если определять права доступа ко всем документам еще на уровне sql,
Угу.

Автор оригинала: gerasim но это, насколько я понимаю, будет очень тяжелая операция,
Качественный анализ сферических сущностей в вакууме не применим к суровой реальности. Для того что бы сделать выводы по данному вопросу нужно знать структуру БД.
 

gerasim

Новичок
Re: Re: Вывод списка при частичном ограничении прав доступа

То, что есть сейчас - первый мой опыт в строительстве списков доступа - он оказался неудачным (работает, но некоторые вещи, теперь уже мне очевидно, кривые). Новый же вариант - я как раз и думаю, как мне лучше его сделать.
Что есть сейчас (не выкладываю точную структуру, решил что так будет понятней, если нужно - скажите):
Таблицы:

Роли - рут, админ, гость, юзер и тп.
ЭлементарныеРоли - незарег.юзер, зарег.юзер, админ (всего 3)
Модули - Здесь для каждого модуля указан уровень прав ( в юникс стиле) элементарных ролей(плюс владельца_док-та) по отношению к этому модулю. Т.е. для элем.ролей: админ, незарег.юзер, зарег.юзер, владелец док-та в этом модуле.
ПраваРолей - таблица связей, показывает, какую элементарную роль играет обладатель роли по отношению к каждому модулю
ПользовательскаяГруппаДоступа(ПГД) - аналог роли, создается пользователем
ЧленыПГД - список юзеров, входящих в конкретную ПГД
ПраваЗаданныеПользователем - для каждого объекта (модуль, ID) создается несколько строк, указывающих уровень доступа членов ПГД (и/или роли) в данный объект

Собственно, мой вопрос не столько "как сделать, чтоб работало то что есть", сколько хочется понять, возможно ли в системах с ACL примерно описанной сложности (или даже более сложных), сделать "правильный" подход к постраничной выборке, так чтоб это не вызывало чрезмерно больших нагрузок на базу. Или это решается обходными путями.
Все-таки acl в полпинка не переделывается, хотелось бы второй раз обойтись без косяков.
Я понимаю, что вопрос от сферического коня недалеко ушел, но в данной ситуации сильно конкретнее написать не получается:)
 

dimagolov

Новичок
Что у тебя является объектом и как определяется надо или нет ограничивать к нему доступ? Из вышесказанного видно только что доступ определяется для модуля, но из общего изложения ясно, что есть более мелкие объекты со специфическими правами доступа.

ЭлементарныеРоли у тебя похожи на группы, но похоже являются прослойкой, которые имплементируют права на модуль. ИМХО мутно как-то.
 

korchasa

LIMB infected
При такой структуре отрисовать пейджер на более менее большом списке невозможно, из-за ПГД, ЧПГД и ПЗП (красотища!). Если ограничить их количество, то можно сделать маску доступа в базе. Остается только проблема ее перестроения при добавлении нового ПГД и т.д. ;)

-~{}~ 16.04.09 19:48:

Хм, а вообще все эти ПГД и прочие можно свести к user2document связи многие-ко-многим.
 

gerasim

Новичок
Объект - это запись в базе, идентифицируется принадлежностью к модулю и своим ID (новость, страница, запись в форуме и тп)
Доступ (без ПГД) организован так: деления на админсткую и неадминскую части нет. При каждом доступе к объекту проверяется право доступа. В эксшне явно указан тип требуемого доступа (read,write,edit и тп)
1) При авторизации у юзера имеем для него массив соответствий Модуль=> ЭлемРоль, т.е. какую эл.роль играет в общем случае (т.е. не будучи владельцем конкретного объекта) данный юзер в данном модуле.
2) При проверке доступа проверяем по этому массиву, кем (какая элем.роль) является юзер для объекта в данном модуле, либо он является владельцем.
3) Далее из табл Модули беррем уровень прав соответственно для эл.роли юзера в этом модуле. Сопоставляя с типом запрошенного действия (read,write,edit и тп) и, соответственно, с "весом" конкретного права, получаем да/нет

Если для модуля предусмотрено использование ПГД, то вместо п.2 делаем запрос на получение уровня доступа для юзера из таблиц пользовательских установок. Если таковых нет, то пошел п2.

-~{}~ 16.04.09 20:00:

korchasa
Да я уже и не хочу делать пейджинатор на том, что есть. Буду переделывать. Но в какую сторону?

Собственно, мой вопрос не столько "как сделать, чтоб работало то что есть", сколько хочется понять, возможно ли в системах с ACL примерно описанной сложности (или даже более сложных), сделать "правильный" подход к постраничной выборке, так чтоб это не вызывало чрезмерно больших нагрузок на базу. Или это решается обходными путями.
 

korchasa

LIMB infected
korchasa
Да я уже и не хочу делать пейджинатор на том, что есть. Буду переделывать. Но в какую сторону?
Зачем пользователям честный педжер? Они любят находить документы не запоминая номер страницы. Лучше уж сделать сдвиг по id, и добавить нужные пользователям сортировки и фильтрации.
 

gerasim

Новичок
Автор оригинала: korchasa
Лучше уж сделать сдвиг по id
Это как? не соображу...

Ну, иногда честный пейджинг нужен просто потому, что люди этого хотят:) Поэтому им надо или дать, или грамотно объяснить что это невозможно. Одно дело, если я начну лепетать, что acl кривая и я не могу сделать пейджинатор иначе. Другое дело - если буду знать и смогу уверенно поставленным голосом ответить, что сложная acl и честный пейджинг несовместимы:)

Либо (в идеале) - смогу сделать пейджинг при наличии acl
 

korchasa

LIMB infected
Автор оригинала: gerasim
Это как? не соображу...
where id > последний_id_на_странице
ну для других сортировок соотвественно передаются они и id

Ну, иногда честный пейджинг нужен просто потому, что люди этого хотят:)
Люди хотят не пейджер, а быстро находить нужное. Один из вариантов поиска - запоминать номер страницы. Вариант не самый хороший, особенно если наборы данных часто меняются.
 

korchasa

LIMB infected
Автор оригинала: gerasim
Не понимаю. Очень смущает "последний id"
Ты отрисовал на странице 20 объектов. У последнего объекта id = 11. Передаешь его GET параметром в ссылке на следующую страницу /documents/?from=11. В запросе используешь, как select что-то from что-то where id > 11.

-~{}~ 16.04.09 21:03:

Если, конечно сортировка по id, или времени добавления (id с автоинкрементом).
 

gerasim

Новичок
Теперь понял, спасибо. Согласен, в случае сортировки по времени создания - это вариант.
 

gerasim

Новичок
Автор оригинала: korchasa
Не только по нему, ну да ладно.
Нет уж, нет уж:) Просвети, пожалуйста:) Я пока не могу себе представить, в каком еще случае подобный подход можно применить. Сортировка "чисто по id" - имхо, бесполезна. Где еще?
 

Grezz

Новичок
Или мне кажется, или права дублируются
Автор оригинала: gerasim
...
Модули - Здесь для каждого модуля указан уровень прав ( в юникс стиле) элементарных ролей(плюс владельца_док-та) по отношению к этому модулю. Т.е. для элем.ролей: админ, незарег.юзер, зарег.юзер, владелец док-та в этом модуле.
...
ПраваЗаданныеПользователем - для каждого объекта (модуль, ID) создается несколько строк, указывающих уровень доступа членов ПГД (и/или роли) в данный объект
Если это дейтвительно так - то лучше оставить что-либо одно.

Автор оригинала: korchasa
При такой структуре отрисовать пейджер на более менее большом списке невозможно,
Пробовать надо, а потом выводы делать, мне например что-то подсказывает что модулей будет не более 1000, а это мелочи :)
 

gerasim

Новичок
Модули - системные права
ПраваЗаданныеПользователем - заданные пользователем
Если модуль позволяет юзеру задавать в своих объектах юзерские разрешения доступа, то сначала используется вторая таблица, а если там ничего не установлено, то следом первая.

Но это уже неважно. Я ищу ответ на вопрос не для описанной acl. Попробую переформулировать: можно ли спроектировать систему так, чтоб и acl позволяла задавать пользовательские настройки доступа к объектам, и при этом делать "честный" пейджинатор "без дырок" в виде ссылок на объекты к которым у конкретного юзера нет прав доступа (и чтоб запросы к базе для построения такого пейджинатора не перегружали базу).

Возможно я действительно хочу сферического коня, тогда извините. Но сейчас для меня ответ на этот вопрос имеет смысл потому, что или я буду знать, что "да" и есть к чему стремиться , либо "нет" , т.е. если есть acl, то для пейджинга нужны обходные пути.
 

Grezz

Новичок
Можно, я обычно делаю по типу пользователь<->таблица_связка<->объект для каждого типа объектов при построении каких-либо списков - иннер жоины или конструкция id_объекта in (выборка id_объекта из таблицы - связки по id_юзера)
собственно делается 2 запроса - один на получение кол-ва записей, второй - на получение ограниченного кол-ва записей для заданной страницы, работает "на ура"
 

korchasa

LIMB infected
Автор оригинала: gerasim
Нет уж, нет уж:) Просвети, пожалуйста:) Я пока не могу себе представить, в каком еще случае подобный подход можно применить. Сортировка "чисто по id" - имхо, бесполезна. Где еще?
Да, что угодно. Просто в случае неуникальных значений поля, по которому сортируем, придется вводить дополнительный индекс (например, цена * 10^6 + id) в виде еще одного поля в базе.

Но это уже неважно. Я ищу ответ на вопрос не для описанной acl. Попробую переформулировать: можно ли спроектировать систему так, чтоб и acl позволяла задавать пользовательские настройки доступа к объектам, и при этом делать "честный" пейджинатор "без дырок" в виде ссылок на объекты к которым у конкретного юзера нет прав доступа (и чтоб запросы к базе для построения такого пейджинатора не перегружали базу).
Пользовательская ACL, это по сути многие объекты ко многим субъектам. Т.е. имеем два списка - список документов и список разрешений(или запрещений, или и того и другого - не суть) документ-пользователь. Список разрешений/запрещений вряд ли будет большим, так что вполне можно. Хотя кое-кто из незримо присутствующих на форуме отказался от реляционной базы на этой задаче.

-~{}~ 17.04.09 11:43:

Извиняюсь за то, что напугал сразу. 20 часов за работой - сразу не въехал :)
 

gerasim

Новичок
Grezz
korchasa
Спасибо, значит есть куда стремиться:)

korchasa
Понял. Предположил нечто подобное, но до "например, цена * 10^6 + id)" не додумался.
Еще раз спасибо.
 
Сверху