Система разделения прав доступа в веб-приложении — часть 1, теория

    В данный момент моя небольшая команда из двух человек, занята разработкой CMS. Я представляю примерно сколько их уже существует, но хочется внести свою лепту.

    Ниже я хочу поделиться мыслями о системе разделения прав доступа в CMS. Кажется она получается весьма оригинальной и интересной.


    Думая о реализации, я поставил следующие цели:
    • единый API для всех модулей;
    • просто и удобно для разработчиков;
    • просто и удобно для пользователей;
    • приемлемая скорость и объем данных;
    • гибкость возможностей.

    В итоге, я пришел к выводу, что самый подходящий аналог — мандатная система доступа к файлам в unix-е. Та самая, которая 777. :) Естественно с поправками на веб-ориентацию — вместо каталогов у нас будут категории, вместо файлов — разные веб-объекты, и т.д. Обо всем ниже.

    В самом общем приближении — система будет хранить таблицу, в которой будут содержаться идентификаторы всех объектов, и права доступа к ним.

    Технические проблемы (к примеру разнотипность ключей объектов, использование системы на усмотрение разработчика), а также оптимизацию — обсудим позже. Пока идем по стратегии.

    У каждого объекта будет владелец-пользователь, владелец-группа и число, которое будет описывать, что с этим объектом делать. В unix-системах, такое число содержит 3 цифры для описания прав
    1. владельца — пользователя;
    2. владельца — группы;
    3. остальных пользователей.


    У нас будет больше на одну цифру:
    1. владельца — пользователя;
    2. владельца — группы;
    3. остальные зарегистрированные пользователи;
    4. остальные незарегистрированные пользователи.


    Теперь о более интересном. В операционной системе, как правило, хватает контроля всего над тремя операциями — чтение, запись, исполнение. Плюс пара дополнительных флагов.

    У нас ситуация сложнее — может быть много других операций, которые надо контролировать. Описание прав на чтение/запись/исполнение не хватит. К примеру, на сайте с объявлениями, пользователь может изменять свое объявление, но не может загружать в него фотографии. Эта возможность открывается после оплаты. Или возможность скачать приложенные файлы — ее тоже надо контролировать.

    Получается, что в отличии, от ОС, где всего три операции — у нас количество этих операций — потенциально неограниченно. Их много, и кроме того, они могут меняться от приложения к приложению. И все же этому есть красивое решение.

    Каждую цифру можно разбить на верхние байты — самые стандартные операции для всех объектов, а также какая-то часть зарезервированная на будущее. И нижние байты, которые сможет определять само приложение. Если ему конечно не хватит стандартных.

    Необходимости во флагах как в unix-е я не вижу, т.к. флаги посути лишь добавляют разрядность, когда надо. У нас флаги будут в самой маске доступа (надеюсь этот термин подходит).

    В итоге, допустим для статьи, мы получим маску доступа, которая будет выглядеть примерно так:
    image

    Что эта она означает и кому, что разрешено — думаю понятно из рисунка.

    В каждой группе — две подгруппы. Первая подгруппа из 4х бит — зарезервированные для наиболее стандартных. Вторая подгруппа — определяется отдельно каждым модулем. У нас, там к примеру, будет описана возможность размещения файлов.

    В базе данных эта маска будет записана как число 3 633 352 832.

    В примере разрядность — 32 бита — тип данных INT. Это для примера. В реальной жизни я наверное воспользуюсь BIGINT размером в 64 бита. Соответственно все группы и подгруппы будет больше в 2 раза.

    Как я предполагаю использование — при попытке доступа к объекту — модуль должен будет запросить права доступа на объект. Система вытащит это число из базы, разберет по битам и вернет модулю в каком-то красивом виде. Допустим в виде удобно обрабатываемого массива. Дальше модулю следует поступить как полагается.

    Количество записей в таблице прав будет расти прямолинейно от количества объектов в системе. В принципе это терпимо, но можно сделать еще красивее — выделить стандартные для модулей маски. И в таблицу записывать объекты только с нестандартными правами — количество записей сократится на порядок.

    Нельзя принудить разработчиков пользоваться этой системой. Но, при ее использовании они получат следующие плюсы:
    все сделано — бери и пользуйся;
    меньше шансов допустить ошибку в коде;
    у пользователя на все модули и их объекты будет один универсальный и привычный интерфейс.

    Использование этой системы, кстати, не исключает и другие способы контроля доступа. Такие, как списки доступа.

    Если статья понравится сообществу — появится статья Система разделения прав доступа в веб-приложении — практика. :)

    P.S. В теории безопасности не очень силен — поправьте, если ошибся где в терминах.

    P.P.S. Подобную систему в вебе не встречал, хотя возможно где-то далеко, а может и близко — она есть. Если так — киньте ссылку.

    P.P.P.S. Первый пост на хабр — возможны «детские» ошибки, укажите на них — быстро поправлю.

    UPDATE: Теперь пост в блоге о CMS и на главной странице хабра. Спасибо, хабралюди! :)
    Отдельное спасибо mexxv за карму для перемещения поста и metamorph за ссылку на хорошую статью идейно крайне близкую ко мне.

    Порадовался в своем блоге попаданию на главную хабра. Инфу там не публикую пока, боюсь он не выдержит хабра-эффекта — надо готовить заранее. :)

    А теперь по делу. Комменты помогли понять основную проблему предложенной системы — гибкости все же недостаточно. Надо больше. Может быть используя гибрид с ACL, может быть за счет больших возможностей наследования. Постараюсь все обмысленные итоге подвести к завтрашнему дню.

    UPDATE: mephius говорит что предложенная мной идея с приправой из ALC работает на мега-крутом сайте.

    Кстати, я заработал первый хабраинвайт. :)))
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 228
      –13
      А зачем нужна новая CMS? Чего не хватает в старых?
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          А почему просто не обновить старые?
          Своим кодом, если уж на то пошло.
            –1
            Никакую инновацию в старый скелет не запихнуть.
              +2
              Ох как вы замучаетесь с битами в MySQL, плюс ко всему при разборке маски битов СУБД плюнет на индексы.
              При иерархии, лучше использовать дополнительную таблицу прав доступа к иерархическим объектам через группы пользователей. Т.е. не изобретая велосипед.
              Только для групп ставить tinyint(1), где разрешено «1», а не разрешено «0», тогда не надо будет использовать OR-ы. Можно просто g1+g2+g3>0 т.е. если пользователь для объекта состоит в одной из этих групп, он получит управление над объектом
          +6
          Если коротко — мерцает надежда привнести что-то хорошее в этот мир от себя. Шансов мало, но попробовать стоит, так как даже процесс приятен.

          По ошибке сперва ответил не туда.
            +1
            А зачем новый мерс есть ведь старый запорожец :)
              +4
              Только вот все новые cms только на бумажке и в теории мерцедесы, а на практике — тот же запорожец в разной обертке.
                0
                Я больше хотел сказать сказать зачем выпускать новые модели машин если есть старые :)
                  0
                  Видимо затем, что все таки иногда — да да, случается и такое, что мерцедес на бумаге, становица вполне себе и реальным мерцедесом и в реальной жизни, пользоватся которым можно сказать — одно сплошное удовольствие
                0
                из Comedy Club в миниатюре. Герои говорят про запорожец:
                «Да… Лучше этого вряд ли что-нибудь придумают»
                  0
                  Там про «москвич» 412 речь шла ;-)
                    0
                    А, ну да :)

                    Но смысл остается.
                0
                Мне, например, в старых не хватает гибкости и расширяемости :)
                  +4
                  Я всегда пишу новую для себе. Для мне написать свой ЦМС как наркотика для наркомана!
                  + Мне легко свой написать для своей нужды, чем днями чужой код изучать.
                  ++ Не найдешь такой ЦМС, там где все есть или же все функции нужные.
                    +1
                    может тогда стоит взглянуть на CMF, половину ручками до идеала, половина работы низкоуровневой — давно уже сделано. А изучать чужой код иногда бывает очень полезно.
                      0
                      — А изучать чужой код иногда бывает очень полезно

                      Согласен. Но когда есть свободное время. А когда надо свою НовуЮ идею реализовать быстро, то можно не успеть изучаю другие ЦМС-ы.

                      — может тогда стоит взглянуть на CMF

                      Framework-ы все ровно использую.Но и у себя накопился много проверенные селф классы, которые можно всегда использовать вместо FM. Практику набирать исправляя свои ошибки даже Полезно.
                      Если использовать только копи паст и ФМ -ы тогда откуда брать «кайф»? =)
                        0
                        Когда мне надо реализовать новую идею\проект и прочее, в ограниченный срок — я беру свой любимный фреймворк, потому что достаточно хорошо с ним знаком и понимаю, что эта чтука сохранит не только мое время, но и мои нервы.

                        Кайф получается от нового проекта, который не похож на предыдущий, который нельзя реализовать обычным копипастом. А таких проектов еще огромное количество, и думаю, что будет еще больше.
                    0
                    Ведь практика всегда важна, а если есть умные идеи, почему бы не поделиться?
                    +2
                    Если коротко — мерцает надежда привнести что-то хорошее в этот мир от себя. Шансов мало, но попробовать стоит, так как даже процесс приятен.
                      +3
                      В сторону ACL посмотрите, перед изобретением велосипеда ;)
                        0
                        Я знаю про ACL. Эта система — ее аналог. Велосипед я не изобретаю, а пытаюсь адаптировать под наши веб-рельсы.
                          0
                          Я так понял у вас получается иерархическая система.
                          1-е забудьте про биты и бытовые маски.
                          Сделайте так: доступ к модулям -ACL. Доступ к объектам через обычные группы пользователей, где джойнится дополнительная таблица с установкой для каждой группы своего поля в 1 или 0. Всё.
                          Посредством доступа к объекту вы получаете видимость этого объекта разными группами и обработкой модулями с доступом для групп по ACL. Т.е. не надо изобретать велосипед ;)
                      +1
                      Ну вот такое битовое разделение прав — это было первое, что мне пришло в голову, когда встала подобная задача. :)
                      Другое дело, что специфика той задачи не требовала разделения на группы, поэтому такой «код доступа» был у каждого пользователя свой, без наследований и так далее. Но, опять же, повторюсь, потому что просто не было такой цели.
                        +1
                        >> Подобную систему в вебе не встречал

                        Например, вот тут описание есть.
                        www.xaprb.com/blog/2006/08/16/how-to-build-role-based-access-control-in-sql/
                          +5
                          Почитайте документацию по Zend Framework — Acl ( одна из первых ). Может оттуда немного возьмете для себя. Я даже не говорю о коде, а о принципах решения проблеммы. Если не найдете — напишите мне — я вам скину. Ваш метод немного неуютный в работе. Если ваша ЦМС будет жить и развиваться — ваша маска доступа будет расти до коллосальных размеров. И будет такое, что для того, чтобы прочитать доступ к одной опции — надо будет парсить весь конфиг. Также плохо в плане обратной совместимости. С таким подходом ее у вас просто не будет. Пишите. Авось и получится. Знайте, что идеальной цмс на сегодня нет. Может у вас получится ;)
                            0
                            Спасибо за инфу про зенд — прочитаю в течении дня.

                            Насчет роста маски — я не согласен, у большинства приложений не так много операция для контроля. Даже если BIGINT'а не хватит — можно сделать поле бинарным и указывать маску произвольной длинный. Главное, чтоб ее длинна была кратна N*4, где N — количество бит на каждую группу.

                            Вопрос только один — насколько это уменьшит производительность СУБД. Сходу гадать не хочется — надо бы протестировать.

                            Обратная совместимость тоже будет между масками различной длинны — просто в некоторых масках, где необходимо, будет больше бит в конце. Но базовая структура будет одинаковая.

                            Надеюсь относительно ясно сформулировал что хотел.
                              0
                              И вам кажется это удобным?
                                0
                                Что именно?

                                Для программеров — будет API, которое красиво вернет все права для работы с объектом.

                                Для пользователя — универсальный интерфейс и функции для разграничения доступа.

                                Реализация будет весьма простая — делается за сутки-двое неторопливого кодинга. Это только при чтении она может показаться страшной. Но в кодинге на уровне бит я хорошо потренировался, когда занимался стеГАнографией. Прятал информацию в bmp'шниках, внешне оставляя их неизменными.

                                Мне и правда это кажется удобным.
                                  +1
                                  Мне не нравится, к примеру вот что. Сейчас у меня в системе, такая ситуация — есть по сути пара контроллов и под полтинник объектов, с которыми можно выполнять с десяток действий. Причем для каких-то объектов может быть всего лишь 4 действия (CRUD), для других — в три-четыре раза больше (у нас уже получаеца по 2 байта на каждый объект), при том, что права доступа в зависимости от некоторых факторов могут очень сильно менятся к примеру от источника данных (к примеру тестовый\продакшн) или от времени (некоторые действия могут совершатся людьми только в определенное время).

                                  И это не первый проект, где просто обойтись несколькими стандартыми действиями для всего-всего что у нас есть в системе — или невозможно, или очень проблематично (костыльная реализация).
                                    +1
                                    права доступа в зависимости от некоторых факторов могут очень сильно менятся к примеру от источника данных (к примеру тестовый\продакшн)


                                    В зависимости от домена моя CMS использует разные конфиги — в них можно обозначить разные дефолтные права. Права на конкретные объекты — придется менять при переносе базы с теста на продакшн. Если надо много часто — можно в рамках системы прописать в инициализацию проверку и смену прав.

                                    от времени (некоторые действия могут совершатся людьми только в определенное время)


                                    Динамический параметр типа времени не вписывается в статичную модель. Но его можно дописать сверху в самом модуле очень красиво. Как сделать иначе — пока не знаю.

                                    Если у вас очень специфичный проект — тогда конечно забот будет меньше. Если не секрет — какая тематика проекта?
                                0
                                Думаю, вам действительно не стоит слишком заморачиваться на конкретных этих методиках и масках.
                                Как участник команды, придумавшей немало «повторных велосипедов», заявляю — это все давно придумано. Если хочется максимальной универсальности — рассмотрите концепцию ACL (Access Control Lists).
                                Но реально для веб-сайтов, как выяснилось, это просто не нужно. Достаточно чуть более простой реализации RBAC (Role Based Access Control). Ибо никогда в практике пока не нужно было ограничивать доступ к разным частям кода, причем еще и давать конечным пользователям выбирать, кто будет иметь к ним доступ, а кто нет.
                                  0
                                  Да, и чуть не забыл. Именно в контексте веб-проектов, мы пришли к выводу, что роли — это вообще некоторые объекты контекста (т.е. могут быть по сути «прошиты» в конкретную подсистему), и других ролей может не быть вообще, что сильно упрощает реализацию конечного продукта.
                                    +1
                                    RBAC действительно чудная вещь. Особенно в сочетании с MVC, где различным действиям можно назначать пермисии/роли, определяющие права доступа.
                                      0
                                      Совершенно верно. Можно, конечно, и комбинацию всех возможных методов ограничения доступа к объектам использовать и еще сами объекты сделать максимально атомарными (что мы в свое время и сделали), но на практике это не пригодится. Лучшее — враг хорошего. Не нужно делать «сверхуниверсально» — это нецелесообразно усложнит систему, а использоваться в 99% проектов не будет.
                                0
                                Для видимости объекта в иерархической системе одной ACL становится мало ;)
                                zend fw не заточен под иерархические системы, к сожалению :\
                                  0
                                  Почему же? Обьясните, пожалуйста. Свойства наследуются от родителям к потомкам. Любой обьект можно расширить с помощью своего функционала. Для построения иерархической модели функций больше чем достаточно. Иногда даже много бывает. Я уже много раз использовал ACL. Обычно обьекты создаются у меня автоматом по тем данным, что имеются в базе, и в сочетании с паттерном MVC, который имеет место быть в ZF — получается довольно сильная система.
                                0
                                Пользователь — это тот, которому принадлежит объект. А группа это группа пользователей (или тип), которому принадлежит объект.
                                А если, допустим, это сайт, для которого нужно сделать следующее: 2 человека (журналисты) могут редактировать и добавлять новость, директор может удалять новость, зарегистрированные пользователи комментировать.
                                Тогда объект должен проходить проверку по двум группам: журналисты и директора. Что делать в этом случае?
                                  0
                                  Если нужно сделать права у директора такие же, как у журналистов, что наиболее реально — надо создать группу «редакция» и сделать ее владельцем объекта.

                                  Если надо чтоб у журналистов были одни права — у директора другие — тогда только если через «другие зарегистрированные» можно сделать.

                                  Конфузные ситуации для такой системы будут, но они будут весьма редки. Их необходимо будет решать с помощью использования другой системы доступа, что полностью допустимо.
                                    0
                                    Доступ для групп и мультиюзер access ;)
                                    Так сделано у многих cms и cmf
                                    +1
                                    Хм, интересно, я раньше не видел такого подхода. Сейчас пишу единую админку для группы корпоратиивных сайтов и как раз думал о том как реализовать деление прав. Так что плюсую =)
                                    0
                                    такая система со временем станет очень ограниченной ибо веб-объект не файл и его можно не только читать/записать/исполнить. если говорить в терминах MVC то вам нужно будет по 4 бита на каждое действие контроллера. плюс ко всему права доступа могут зависеть на локали и Бог знает на чем еще.
                                      0
                                      Про рост маски я написал выше

                                      Я тоже согласен с тем, что количество операций может быть значительным. Но даже самые крупные приложения типа форума уложатся в несколько десятков операций для каждого объекта. С избытком. Попробуйте написать список объектов на форуме (или более крупном веб-приложении) и количество операций которые надо контролировать — сами все увидите.

                                      А когда привилегии зависят от локали — это называется «рассовая дискриминация», и об этом надо рассказать в прокуратуру. :)

                                      Конечно все фантастические случаи мы охватить не сможем, но абсолютное большинство реальных ситуаций вполне можно так описать.
                                        0
                                        как быть с объектами которыми можно манипулировать с нескольких контроллеров? как знать какой бит отвечает за какое действие? выходит нужно в каждый объект писать маску которая вместит все действия всех контроллеров. 40 контроллеров по 10 действий вот вам 400 бит. и это далеко не предел.

                                        насчет расовой дискриминации — слив не засчитан :) подумайте лучше как реализовать ибо это абсолютно реальная ситуация.
                                          0
                                          Насколько я понимаю — контроллер это модуль, который оперирует своими объектами. Так? Тогда Одним типом объектов может манипулировать только один модуль. Обычно бывает так.

                                          Какой бит за что отвечает — у каждого модуля будет что-то типа «карты атрибутов доступа», в которой будет прописано название действия и бит, отвечающий за него. Если вы хотите что-то сделать с объектом — вы ведь в любом случае знаете что вы с ним делаете? Т.е. название известно, бит узнается из карты.

                                          Приведите пример, когда локаль влияет на привилегии — тогда я постараюсь аргументированно ответить. Сейчас я не представляю себе такую ситуацию.
                                            0
                                            Есть пример когда время влияет на привилегии пользователей.
                                              0
                                              Этот вариант я бы вывел в исключения и обрабатывал средствами модуля. Т.е. сперва получал значение от системы. Если она позволяет — делал бы +1 проверку в модуле на время и в зависимости от этого — менял бы права.

                                              Как тут красивее сделать — не знаю. Статическая модель для таких динамических параметров не подходит.
                                                0
                                                В модуле не думаю что хорошо, все таки эта одно из нестандартных условий, которое может отменить\изменить права для пользователя. А таких может быть несколько… а если они еще и будут накладыватся друг на друга — «только в определенное время и только с определенных ip и только в определенном состоянии объекта» — конечно пример этот надуман, но, что-то подобное может появиться… То у нас получается что нам придется делать несколько исключений во всех модулях которые работают с данными сущностями. А это уже хороший такой кусок логики, которая по сути к делу не относится…

                                                Сейчас для таких целей используются Assertions, в Zend_Acl
                                                  0
                                                  Если есть некая сущность, для которой нужны такие вещи хитрые — их надо будет прописать в 1 модуль, который работает с ней. Допустим при хитрых условиях регистрации — все изменения и по времени, и по ip — будут в модуле пользователя.

                                                  Сейчас для таких целей используются Assertions, в Zend_Acl

                                                  Добавил в список для ознакомления.
                                              0
                                              в MVC один контроллер чаще всего оперирует с одним типом объектов но совсем не обязательно обратное — что с одним типом объектов работает только один контроллер.

                                              а разве сложно придумать пример с локалью? есть многоязыковый сайт и нужно некоторым пользователям(локальным администраторам) дать доступ редактировать лишь объекты созданные для конкретной локали.
                                                0
                                                в MVC один контроллер чаще всего оперирует с одним типом объектов но совсем не обязательно обратное — что с одним типом объектов работает только один контроллер


                                                Можно с примерами, чтоб мне было проще понять вашу аргументацию. Спасибо.

                                                а разве сложно придумать пример с локалью? есть многоязыковый сайт и нужно некоторым пользователям(локальным администраторам) дать доступ редактировать лишь объекты созданные для конкретной локали.


                                                С ходу вижу только вариант — на каждый язык (коих обычно больше десятка только на сайтах-монстрах) создавать группу. У все документы метить как принадлежащие этой группе. Хотя это исключает дальнейшее использование других групп.

                                                Чуствую что эта критика подведет меня к хорошим конструктивным доработкам. :)
                                                  0
                                                  > Можно с примерами, чтоб мне было проще понять вашу аргументацию. Спасибо.
                                                  пример: есть сайт где комментировать можно все и вся. статью, параграф, другие комментарии, пользователей, фотки итд. большинство обработок берет на себя контроллер комментариев но бывают исключения, и комментарии нужно добавлять в других контроллерах. икс контроллеров и один тип объекта — комментарий.

                                                  другой пример: административная часть сайта работает с теми же объектами что и сам сайт но контроллеры свои — снова несколько контроллеров на один тип объекта.

                                                  > Чуствую что эта критика подведет меня к хорошим конструктивным доработкам. :)
                                                  критика подведет вас к использованию уже готовой системы ACL
                                                  не теряйте время ;)
                                                    0
                                                    другой пример: административная часть сайта работает с теми же объектами что и сам сайт но контроллеры свои — снова несколько контроллеров на один тип объекта


                                                    Т.е. дублируется код доступа к сущности в UI и в админке? Можно еще ближе к жизни пример. А то этот кажется космическим.
                                                      0
                                                      код доступа в сущности описан в модели а код управления сущностью описан в контроллере. так с чего бы управление сущностью в админке и на сайте было одинаковым?

                                                      а как же пример с коментами?

                                                      я вам не просто так примеры придумываю, это реальные ситуации из реального большого и серьёзного проекта.
                                                        0
                                                        код доступа в сущности описан в модели а код управления сущностью описан в контроллере. так с чего бы управление сущностью в админке и на сайте было одинаковым?


                                                        Прошу прощения, но я кажется уже запутался. Откуда здесь упоминание про одинаковое управление? Можно мысль подробнее.
                                                          0
                                                          код доступа в сущности описан в модели а код управления сущностью описан в контроллере. так с чего бы управление сущностью в админке и на сайте было одинаковым?


                                                          Прошу прощения, но я кажется уже запутался. Откуда здесь упоминание про одинаковое управление? Можно мысль подробнее.
                                                            0
                                                            > Т.е. дублируется код доступа к сущности в UI и в админке
                                                            не дублируется ничего, ибо код «доступа» к сущности не есть одинаковым на сайте и в админке. два разные контроллера делают разные вещи с одним и тем же обьектом.
                                                              0
                                                              И чем это в мою модель не вписывается? Главное чтоб оба контролера имели доступ к одной карте атрибутов доступа — знали какой бит что обозначает.
                                                                0
                                                                да совсем не вписывается… два контроллера = два набора совсем разных действий. вы же не мапите функциональность сайта прямо на абстракцию от базы данных? есть промежуточный уровень. удаление топика тянет за собой удаление коментов. далеко не всегда это можно прописать в самой СУБД.

                                                                ну а если вы решили в эту вашу карту атрибутов запихнуть все действия обоих контроллеров то я вам привел пример неограниченного роста карты атрибутов, что в общем и требовалось.

                                                                а что делать если действие из контроллера удалили? пробегать по объектах и удалять бит? совсем не тривиальная операция.
                                                                  0
                                                                  да совсем не вписывается… два контроллера = два набора совсем разных действий.


                                                                  Каждому контроллеру будет свой кусок бит в маске объекта.

                                                                  ну а если вы решили в эту вашу карту атрибутов запихнуть все действия обоих контроллеров то я вам привел пример неограниченного роста карты атрибутов, что в общем и требовалось


                                                                  Возможно в крупном мега проекте так и будет. Но! На абсолютном большинстве сайтов, у любого объекта будет в край десяток-два действий.

                                                                  а что делать если действие из контроллера удалили? пробегать по объектах и удалять бит? совсем не тривиальная операция.


                                                                  Удалить надо только из карты атрибутов. В СУБД — надо обнулить этот бит у всех объектов, что делается одним запросом. ;)
                                                                    0
                                                                    Блин, да вы отжигаете.

                                                                    Битовые операции с записями в СУБД?
                                                                    Вы умножать/делить все решили? Зачем?
                                                                      0
                                                                      Зачем умножать и делить? Есть логические функции.

                                                                      Зачем я на уровне битов работаю?

                                                                      1. мне хватает их для передачи информации;
                                                                      2. это быстро;
                                                                      3. для меня это удобно, я понимаю что делаю;
                                                                      4. разработчики, которые будут это пользовать — не увидят этого и не смогут испугаться;
                                                                      5. занимает мало места.

                                                                      А зачем мне больше?
                                                                      0
                                                                      если вы удалите действие из карты атрибутов то размер карты атрибутов уменьшится на 1 и битовая маска каждого объекта будет неправильной(кроме наверное варианта когда удаляется последнее действие из карты)

                                                                      подсуммируем минусы:

                                                                      1. невозможность динамически вычислять привелегии
                                                                      2. неограниченный рост битовой маски
                                                                      3. накопление неиспользуемых битов или же геморройное удаление этих битов из базы данных

                                                                      для меня этого было бы достаточно чтобы сделать выбор в пользу готовой реализации ACL ;)
                                                                        0
                                                                        если вы удалите действие из карты атрибутов то размер карты атрибутов уменьшится на 1 и битовая маска каждого объекта будет неправильной(кроме наверное варианта когда удаляется последнее действие из карты)


                                                                        Я удалю действие из карты, но бит останется. Просто он будет неиспользованным. Во всех масках он будет обнулен.

                                                                        неограниченный рост битовой маски


                                                                        ограниченный — посмотрите на запросы 99% веб-приложение, приведите список операций больше нескольких десятков над одним объектом

                                                                        накопление неиспользуемых битов или же геморройное удаление этих битов из базы данных


                                                                        Удаления нет, накопления нет, есть некое количество битов, среди которых — часть 1, часть 0.

                                                                        Вы много утверждаете. Попробуйте больше спрашивать — меньше будет недопонимания. Я готов подробно расписать каждый пункт.
                                                                          +1
                                                                          я уже привел достаточно аргументов против такого решения главный из которых — неудобность работы с битовой маской как таковой. вот сделаете несколько рефакторингов, погемороитесь с перегенерацией масок для объектов и поймете об чем я. думаю на этом можно нашу дискуссию закончить :)
                                                                            0
                                                                            Последнее слово оставлю за собой. :)

                                                                            Я работал с данными на уровне битов в разных языках. Это ОЧЕНЬ просто. Требуются только логические операции (and,or,xor) и две функции сдвига бит влево и вправо.

                                                                            Я уже «гемороился» с этим — я к этому отношусь спокойно.

                                                                            Это на самую малость сложнее чем работать с массивом в php. Зато имеет плюсы в виде скорости и объема.
                                                0
                                                форум — это далеко не крупное приложение…
                                                  0
                                                  По моему более чем крупное — большое количество разнотипных объектов, большое количество контролируемых процессов.
                                                    0
                                                    Большое это сколько? Не думаю что на весь форум средней руки наберется и с десяток сущностей, которыми необходимо оперировать, и они очень разношорстны. В любой цмске, с ее парой связей между различными объектами и то можно будет назвать раза в два больше этих самых сущностей и они будут разнообразнее.
                                              +2
                                              и того, по вашей системе можно будет назначить не более 4 различных видов доступа для пользователей. Не изобретайте велосипед — реализуйте ACL.
                                                0
                                                не более 4 различных видов доступа для пользователей

                                                Что такое «вид доступа»?
                                                  0
                                                  вид доступа это совокупность прав, которыми владеет субъект по отношению к данному объекту. Поясню на примере юникс-модели — у вас не получится в ней назначить 4 вида доступа. То есть к примеру кому-то чтение, кому-то запись, кому-то чтение и запись, кому-то чтение и исполнение. В этом заключается невыразительность модели никсов.
                                                    0
                                                    Кажется вы невнимательно читали.

                                                    Теперь о более интересном. В операционной системе, как правило, хватает контроля всего над тремя операциями — чтение, запись, исполнение. Плюс пара дополнительных флагов.

                                                    У нас ситуация сложнее — может быть много других операций, которые надо контролировать. Описание прав на чтение/запись/исполнение не хватит. К примеру, на сайте с объявлениями, пользователь может изменять свое объявление, но не может загружать в него фотографии. Эта возможность открывается после оплаты. Или возможность скачать приложенные файлы — ее тоже надо контролировать.

                                                    Получается, что в отличии, от ОС, где всего три операции — у нас количество этих операций — потенциально неограниченно. Их много, и кроме того, они могут меняться от приложения к приложению. И все же этому есть красивое решение.


                                                    И дальше по тексту.
                                                      0
                                                      Либо я вас не понял, либо вы меня не внимательно читали:)

                                                      Вот допустим у вас есть 5 пользователей разных пользователей, которым нужно назначить права — одному разрешить только комментировать, другомут только читать, еще одному только прикреплять файлы, четвертому — писать, пятому — еще какое-то гипотетически возможное право. Как это будет реализовано по вашей модели?
                                                        0
                                                        И все это к одному объекту? Вы себе такое на реальном сайте представляете?
                                                          0
                                                          Конечно к одному. А вы гарантируете, что такая ситуация никогда не возникнет? Знаете, информационная безопасность очень тонкая штука и тут нужно учитывать все ньюансы. Проще то что вы предложили реализовать с использование ACL — там таких проблем не будет, и можно место для маски сэкономить, т.е. для резерва.
                                                        0
                                                        зачем 4 группы? Есть стандартная никсовая реализация.
                                                        1. пользователь;!!!
                                                        2. группа;
                                                        3. остальные зарегистрированные пользователи;??? пользователи входящие в группу users и что значет зарегистрированные пользователи(почитайте повнимательнее про распределение прав linux)? у меня система где кроме админов и модераторов есть зарегистрированные менеджеры и зарегистрированные дилеры, с возможностями прямо противоположными.
                                                        4. остальные незарегистрированные пользователи.Все остальные.

                                                        А вобще это уже не раз пытались деалть до вас, только подводных камней многовато, простейший — это назначение модератора из пользователей на отдельную тему форума, как вы это осуществите в вашей системе без костылей? И таких моментов много. Мой совет, не изобретайте велосипед, посмотрите лучше в сторону ACL zend ,limb, cack и прочие.
                                                  +1
                                                  Интересно. Продолжайте!
                                                    0
                                                    Заряжайте батареи плюсами, наш танк идет на взлет! :)
                                                    –1
                                                    Я у себя реализовал другую систему прав доступа:
                                                    {Group}+{Actions}

                                                    Group — набор имен страниц. В своей системе использую:
                                                    1) Имена пользователей — например 'User'. Все личные страницы/сообщения пользователя, к которым этот пользователь причастен. (User1+DE — удаление и редактирование своих сообщений на форуме)
                                                    2) Имена страниц (групп пользователей), к которым возможно дать право на обращение. (Users+V — просмотр страницы любым пользователем. Любой пользователь состоит в группе Users)
                                                    3) Дополнительные свойства. Тут всё ясно — некоторые являются администраторами, супермодераторами и др.

                                                    Для пользователей — у них в правах есть только Group.

                                                    Action — набор действий, которые пользователи с имеющимся {Group} могут делать. В своей системе использую:
                                                    N — добавлять новый
                                                    D — удалять
                                                    E — редактировать
                                                    V — видеть

                                                    Например, комментарии имеют права:
                                                    User1+VED, Users+V, Moderator+DE, Admin+DE
                                                    (это немного не логичный пример, так как лучше проверять права (редактирование, просмотр, удаление) модератора не для отдельного сообщения, а для страницы)
                                                    Пользователь имеет права:
                                                    User2, Users, -User1

                                                    Это значит, что пользователь не будет видеть (при запросе V) сообщения от User1 (например, ignore).
                                                      0
                                                      А когда действий будет больше 26? Что тогда?
                                                        0
                                                        Тогда виноват программист, который плохо продумал реализацию своей задумки.

                                                        Для моих решений хватало 26.
                                                          0
                                                          Хорошо, а что будет, скажем так:

                                                          Есть ресурс — новость (заголовок, предпросмотр, полный текст, теги).
                                                          Есть действия:
                                                          — Редактировать заголовок
                                                          — Редактирвоать предпросмотр
                                                          — Редактировать теги

                                                          Как права будете назначать? :)
                                                            +1
                                                            Это, кстати, легко решить если есть сущность «значение свойства». к каждой такой сущности можно прописать свои права.
                                                            Т.е. на всю «Новость» свои права, а так же права на каждое свойство этой новости. по-умолчанию (при создании), например, разрешаем владельцу и группе владельца.
                                                            а дальше юзверь может расставить права как считает нужным вплоть до каждого свойства
                                                              0
                                                              Думаю, что вам ответили на ваш вопрос :)

                                                              Я лишь добавлю, что если вас интересует распостранить права глобально, то есть на все новости — то это делается добавлением нескольких групп прав на страницу.

                                                              Например, глобально ко всей странице:
                                                              NewsPage:
                                                                headers_rights — Users+V, Moderator+E
                                                                preview_rights — Users+VN, Moderator+E
                                                                tags_rights — Users+V, Moderator+E
                                                              Или локально, к сообщению:
                                                              NewsMessage:
                                                                headers — Users+V, Moderator+E, User1+E
                                                                preview — Users+VN, Moderator+E, User1+E
                                                                tags — Users+V, Moderator+E, User1+E
                                                              Или — ещё более локально, к каждому полю:
                                                              Header:
                                                                rights — Users+V, Moderator+E, User1+E
                                                              Preview:
                                                                rights — Users+VN, Moderator+E, User1+E
                                                              Tags:
                                                                rights — Users+V, Moderator+E, User1+E

                                                              Я уже писал, что это всё образно. У меня, на деле, движек автоматически позволяет к глобальным правам добавлять локальные. Программа лишь смотрит (отсуммированный) tags_rights для конкретного тега и решает позволять или нет действие пользователю. :)
                                                                0
                                                                А как вы на конкретный объект устанавливаете права? Выделяете в отдельную группу? Без наследований. За которой надо не забывать следить.
                                                                  0
                                                                  Я выше обратил на это внимание, что наследования автоматически производятся.

                                                                  Вообще — это всё сугубо зависит от поставленной задачи. Например, для простого редактора новостей, я использую:
                                                                  NewsPage:
                                                                    news_rights — Users+V, Moderator+NED, Admin+NED
                                                                    comments_rights — Users+NV, Moderator+NED, Admin+NED
                                                                  Message:
                                                                    news_rights — User1+ED (в принципе не нужно, если добавлять могут только модераторы)
                                                                    comments_rights — User1+D
                                                                  Comment:
                                                                    rights — User2+ED
                                                                    0
                                                                    Если необходимо добиться, чтобы пользователь не оставлял комментарии в сообщении — делается всё очень просто:
                                                                    Message:
                                                                      comments_rights — Users-N
                                                                      0
                                                                      А если нельзя оставлять сообщения на конкретный пост? В отдельную группу его? А потом надо постоянно помнить об этом аппендиксе.
                                                                        0
                                                                        Пример выше как раз и показывает, как реализовать сообщения БЕЗ комментариев. Вы о каких аппендиксах?

                                                                        Для большего понимания, суммарные права для данного сообщения будут:
                                                                        Comments_rights — Users+NV, Moderator+NED, Admin+NED, Users-N = Users+V, Moderator+NED, Admin+NED
                                                                      0
                                                                      Кстати на счёт голосования.
                                                                      Message:
                                                                        vote_rights — Users+VN

                                                                      V — просмотр голосования
                                                                      N — возможность проголосовать

                                                                      Если пользователь 1 проголосовал, то в vote_rights данного сообщения добавляется новое право User1-N и он автоматически не сможет снова голосовать.

                                                                      Или, например, если только проголосовавший пользователь имеет право на просмотр голосов:
                                                                      Message:
                                                                        vote_rights — Users+N, User1-N+V, User2-N+V, итд.

                                                                      То-же самое можно использовать (не переписывая совсем код), если требуется возможность оставлять лишь один комментарий от каждого пользователя.
                                                                        0
                                                                        Если пользователь 1 проголосовал, то в vote_rights данного сообщения добавляется новое право User1-N и он автоматически не сможет снова голосовать.


                                                                        Как же у меня база распухнет, если на каждое из 10'000 сообщений будет ставиться право каждого из хотя бы 1'000 пользователей. Очень распухнет. Как и голова у тезх, кто будет поддерживать.

                                                                        Скорость работы с такими строковыми массивами будет очень низкой.
                                                                          0
                                                                          БД прав доступа, где около 5000 сообщений занимает меньше 1 Mb. Работает — моментально.

                                                                          Бинарные маски, будут выигрывать, если пользователей будет мало. Когда их количество приблизится к тысячи, динамические списки будут работать быстрее и занимать меньше памяти :)
                                                                            0
                                                                            Вот в чем в чем, а в скорости и объеме они будут впереди 100% ;)
                                                                              0
                                                                              Когда сущностей 20, пользователей входящих в различные группы — десятки тысяч, возможных действий с сущностями — по десятку на каждую, то можно логически посчитать какого размера у нас будет длинна этого поля, и как долго мы будем выдергивать оттуда данные, по какой-то маске. А если надо что-то подправить или изменить… Ох…
                                                                –1
                                                                А вообще — моя реализация очень сильно отличается от того, что я здесь описсал. Здесь — чисто на русском, чтобы было ясно для любого человека. :)

                                                                У меня вообще используется свой оптимизированный «словарь» для Group и Action.
                                                                0
                                                                В чистом виде ACL. :)

                                                                Для веба она по моему не совсем подходит. Я скорее согласен использовать гибрид ACL + мандатная система. Думаю они могли бы помочь друг другу избавиться от минусов.
                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                    –1
                                                                    Проблемы возникают, когда один пользователь может входить в разные группы. Кроме того, количество прав ограничено, причём, довольно сильно. Для небольших сайтов это подходит, а для больших уже нет.


                                                                    Проблемы скорее не в том, что пользователь входит в разные группы, а в том, чтоб дать разным группам разные права.

                                                                    Наконец, нет параметризированных прав доступа (условно говоря, на форуме есть 3 подфорума, которые модерируют Mr. Foo, Mr. Bar и Mr. Baz — в этом случае мы не можем просто сказать «Mr. Foo имеет права модератора», нужно указать, для какого форума).


                                                                    Тут все просто — записываем Mr. Foo в группу модераторов, если надо просто дать права модера. Если надо для конкретного форума дать — по любому придется его указывать.
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                        0
                                                                        Битовая маска объекта — это ярлык для объекта. Что с ним можно делать. Кроме маски, объект имеет информацию о владельце. Зная данные текущего пользователя — мы сравниваем их с данными объекта, его владельцем и маской описывающей поведение для владельца/невладельца и решаем что делать.
                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                      –1
                                                                      Расширяемость. Допустим, я и Петя захотели написать модули для вашей CMS. Мы взяли первые свободные биты и используем. Я не знаю про Петю, Петя про меня, потому наши модули не могут работать совместно.


                                                                      Не понял, откуда такие выводы. Они смогу работать совместно. У каждого объекта будет пространство для стандартных прав (первая подгруппа на рисунке) и пространство прав определяемых модулем (вторая подгруппа).
                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                      0
                                                                      Не понял зачем на комментирование и загрузку файлов заводить типы доступа. Фундаментальнее можно взять.

                                                                      Есть права на чтение, запись, удаление, и изменение прав доступа.

                                                                      Если гость создает новую сущность то все: гости и пользователи могут с ней взаимодействовать.

                                                                      Если пользователь создает сущность, то только он может управлять ей не решил измененить права доступа.
                                                                      Например, если пользователь решил расшарить объект (например на чтение), то он расшаривает по полю чтение записываю туда к примеру "*" (открыть для всех пользователей). А остальные поля оставляет без изменений (в них по умолчанию идентификатор пользователя, который создал данную сущность).
                                                                        0
                                                                        Опять же, подходит для примитивной работы с правами на уровне — вот тут комментить можно всем, тут никем, а вооон там — только с разрешения пользователя.

                                                                        А если у нас идет полноценная работа с десятками различных взаимодейтсвующих между собой сущностях, различными людьми — то тремя галками мы уже врядли обойдемся…
                                                                          0
                                                                          Так речь идет о оперировании идентификаторами сущностей. А не о просто разрешить для всех или запретить для всех. Этого хватит для реализации политики доступа любой сложности и под любой проект.
                                                                            0
                                                                            Сейчас политика доступа у меня в проекте еще завязанна на некоторую нестатичную величину — время. Может просвятите, как с помощью трех галок мне можно реализовать поддержку блокирования около трети операций с некоторыми сущностьями после 9 часов вечера и до 9 утра?
                                                                              0
                                                                              А вы сумели реализовать это тремя галками? Значит права у вас очень жестко заточены под три галки.
                                                                                0
                                                                                Я сумел это реализовать с помощью acl
                                                                                  0
                                                                                  И в модуле стоит проверка на текущее время. В любом случае. И в ACL вы тремя галками тоже ничего нового не пропишите. В данном случае разница небольшая.
                                                                                    0
                                                                                    в модуле стоит одна проверка — может ли текущий юзер выполнить данную операцию. Все проверки лежат в ввиде assert-ов, где собсна им и место
                                                                                      0
                                                                                      Я с зендом работал почти никак. Можно в личку кусок скрипта с минимальными комментариями? Чтобы сразу в жизни эти ассерты увидеть.
                                                                                        +1
                                                                                        Да, кину сразу сюда:
                                                                                        $acl = new Zend_Acl();
                                                                                        
                                                                                        // добавляем роль менеджера и какой-то ресурс, допустим сущность myentity
                                                                                        $acl->addRole(new Zend_Acl_Role('manager'));
                                                                                        $acl->add(new Zend_Acl_Resource('myentity'));
                                                                                        
                                                                                        // утверждаем, что манагер, может апдейтить сущность myentity, только если проходит TimeAssert
                                                                                        $acl->allow('manager', 'myentity', 'update', new TimeAssert());
                                                                                        
                                                                                        // проверяем, а можем ли мы....
                                                                                        if ($acl->isAllowed('manager', 'myentity', 'update')) {
                                                                                            var_dump('is allowed!!!');
                                                                                        } else {
                                                                                            var_dump('is not allowed!!!');
                                                                                        }
                                                                                        
                                                                                        

                                                                                        Это наш «клиентский код», по сути, немного выглядит раздутым и монстрообразным, из за того, что назначаем ресурсы и права, в реальности, в большинстве случаем используется уже в контроллерах\модулях и всем остальном только метод проверки — isAllowed(...).

                                                                                        А чуть ниже сам код утверждения, собстна в данном случае — одна небольшая и нужная нам строчка, с жестко заданными данными:
                                                                                        class TimeAssert implements Zend_Acl_Assert_Interface
                                                                                        {
                                                                                        
                                                                                            /**
                                                                                             * Returns true if and only if the assertion conditions are met
                                                                                             *
                                                                                             * @param  Zend_Acl                    $acl
                                                                                             * @param  Zend_Acl_Role_Interface     $role
                                                                                             * @param  Zend_Acl_Resource_Interface $resource
                                                                                             * @param  string                      $privilege
                                                                                             * @return boolean
                                                                                             */
                                                                                            public function assert (Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null, $privilege = null)
                                                                                            {
                                                                                                // проверяем необходимые условия
                                                                                                return (date('H') > 9 && date('H') < 21);
                                                                                            }
                                                                                        }
                                                                                        
                                                                                          0
                                                                                          Та же самая проверка времени в модуле, о которой я и говорил. Просто называется иначе.
                                                                                            0
                                                                                            А вы хотите проверить время как-то иначе? Проверка на какое-то условие есть, но где она будет находится — уже совершенно другой вопрос. Одно дело она жестко зашита в модуле и поэтому что бы перенести в другой модуль — придеца или копипастить, или выносить в либы (как что-то такое отдельное юзаемое между модулями), другое — когда эта проверка принаджелит утверждениям, которые используются по всему приложению и мне нужно только спросить у acl — а вообще могу я сделать то, что хочу или нет…
                                                                                –1
                                                                                После 9 вечера «пробегаемся» по всем тем видам сущностей которые нужно заблокировать и выставляем в полях на чтение, запись, удаление запрет на проведение таких операций с данной сущностью. В 9 утра снова пробегаем по этим сущностям и снимаем запрет.

                                                                                Можно ввести даже что то типа карт политик доступа (где будет ид/имя сущностей и их права доступа). Одна карта загружается в 9 вечера, вторая карта в 9 утра.
                                                                                  0
                                                                                  Зачем править код (подгрузка схем) и так жутко дергать базу? Если все можно прописать несколькими строками в коде (проверка времени).
                                                                                    –1
                                                                                    Все зависит от требуемой задачи. Мне нужна гибкая структура поэтому предложил свой вариант.
                                                                                      0
                                                                                      Дергать базу — не вариант, ее нету, прописать несколькими строками в коде — тоже н вариант, потилики прав могут менятся. Может проверка по времени вообще уже нахрен не будет нужна, а будет авторизировать по еще какой-то схеме, или же понадобится еще одна проверка. Вместо того, что бы напрягать меня девелопера, бегать по всему и так ен маленькому проекту, переписывая все что только можно — я пропишу это в одном месте и буду счастлив
                                                                                      0
                                                                                      У меня для этого есть assertion, где я просто прописываю нужное мне условие. А настолько усложнять права доступа. Тем более что у меня еще вполне могут происходить проверки на белые ip адреса, с которых может осуществляться операция, в совокупности с той же проверкой по времени.
                                                                                0
                                                                                Не понял зачем на комментирование и загрузку файлов заводить типы доступа. Фундаментальнее можно взять.

                                                                                Есть права на чтение, запись, удаление, и изменение прав доступа.


                                                                                Мой скромный жизненный опыт показывает, что этого не хватит.
                                                                                  +2
                                                                                  Комментирование это Запись текста в объект.
                                                                                  Скачать файл это Чтение пути этого файла из объекта.
                                                                                    0
                                                                                    Ага. Мне сразу же испортят запись (ведь на нее нужны права записи), и скачают бесплатно файл, который должен отдаваться только после отправки смс и установки бита на скачивание. Полный Абзац. :)
                                                                                      –1
                                                                                      В чем проблема выставлять флаг права на чтение для файла, который нужно скачать, после того как будет отослана смс?
                                                                                        0
                                                                                        Файл — относится к посту. Права ставить надо на пост, что приложенные файлы можно скачать. А там read уже занят. И означает не то.
                                                                                          –1
                                                                                          Значит надо разделить сущности. За отдачу файла я так понимаю отвечает некоторый модуль, которые дайет линк. Вот к этому и привязывать право чтения.
                                                                                            0
                                                                                            Зачем разделять? У меня все четко по концептуальной схеме реализовано. Очень удобно. Мне теперь все сущности придется дробить ради использования такой схемы?
                                                                                              0
                                                                                              Вы завязываете все на конкретные случаи — это не универсально, не гибко.
                                                                                                –1
                                                                                                красивое слово — «концептуальная схема».

                                                                                                Разделять и наследовать нужно за тем, чтобы облегчить разработку и понимание написанного кода.
                                                                                                Затем, чтобы потом — при добавлении нового функционала — не было мучительно больно за свою «концептуальную» схему.
                                                                                                  0
                                                                                                  Вы предлагаете разбивать сущности для того чтоб обойти ограничения вашей системы разделения прав доступа. Иных причин для разбития я не вижу.
                                                                                      +1
                                                                                      Просто приведите любой пример и он сведется к Созданию, Чтению, Записи, Удалению. Любой пример, потому что это фундаментальные действия.
                                                                                        0
                                                                                        Резать — законное действие. Фундаментальное. Тем не менее резка колбасы не попадает в УК, в отличии от резки людей. Хотя действие одно и тоже с вашей точки зрения.
                                                                                          +1
                                                                                          люди это сущность с одним идентификатором (например A)
                                                                                          колбаса cущность с другим идентификатором (например B)

                                                                                          для действия Резать с идентификатором A один результат
                                                                                          для действия Резать с идентификатором B другой результат
                                                                                            0
                                                                                            Вы думаете я не найду примера? :)

                                                                                            Хирург режет человека и убийца режет человека. Фундаментально они делают однотипные вещи.
                                                                                              +2
                                                                                              Хирург и Убийца пользователи нашей системы. Хирург зарегился с ид 1, убийца с ид 2.

                                                                                              Для всех пользователей системы предоставляются права Резать и Подарить цветы.

                                                                                              В системе есть сущность Человек (у данной сущности для поля Резать содержится ид 1, для поля Подарить цветы ид 1 и 2)

                                                                                              Т.е. Хирург у нас может резать Человека и дарить ему Цветы, а Убийце разрешено только дарить цветы.
                                                                                                +2
                                                                                                Да, именно такая система прав наиболее гибкая и логически правильная, согласен на все 100%
                                                                                                  +2
                                                                                                  Если забыть про конкретных Хирурго-человеков и грамотно разбить архитектуру на сущности и для каждой использовать систему прав RWCD, то получится очень гибко, можно покрыть практически все задачи
                                                                                                    0
                                                                                                    Нельзя этого. Действия то разные. Абсолютно разные могут быть. Допустим голосование в конкретном посте — это и не read поста, и не write поста.
                                                                                                      +1
                                                                                                      Это запись голоса (int значения) в базу данных, в поле привязанное к посту
                                                                                                        0
                                                                                                        Таким образом у нас есть право голосавать, которое на более низком урове выглядит как право записи в некоторый объект, и ещё на более низком, право на запись в определенное поле БД.
                                                                                                        +1
                                                                                                        Можно все.

                                                                                                        Сущность Поста связана с сущностью Голосования где хранится рейтинг. Запись/чтение сущности Голосования можно также определить политикой доступа.
                                                                                                          0
                                                                                                          И как же вы запишете возможность НАЧАТЬ голосование? И куда? В несуществующую до начала функцию голосования?
                                                                                                            0
                                                                                                            Ну так возможность «Начать голосование» это как раз-таки право на чтение для определенных групп-юзверей, насколько я понимаю… Ну или в крайнем случае «видимость» сущности «Голосование»
                                                                                                              +2
                                                                                                              В том то и проблема, что Вы отталкиваетесь от конкретных задач. Так ничего не получится, нужно сделать «общее решение» для любых сущностей.
                                                                                                              Иначе вы обрастете кучей флагов и будет путаница…
                                                                                                                0
                                                                                                                Давайте. Сделайте мне общее решение для контроля десяти типов операций над объектом используя четыре атрибута доступа.

                                                                                                                Именно десять типов операций. Т.е. нельзя свести в 4 типа, как предлагаете вы.
                                                                                                                  +2
                                                                                                                  Давайте без давайте, платите деньги и вам сделают решение.
                                                                                                                0
                                                                                                                Нет, право на чтение — это право на чтение. Оно означает что человек может читать. А право начать голосование — это совсем другое право.

                                                                                                                Про крайний случай, который уже наступил, я не понял. Можно подробней.
                                                                                                                  +2
                                                                                                                  Вы смотрите на проблему с точки зрения конечного пользователя, а не с точки зрения работающей системы. Для пользователя это право голосования, комментариев, отправки открыток, скачивания файлов и тд. Но для системы это запись, чтение, удаление…
                                                                                                                    0
                                                                                                                    Ну понятие «видимость» — это что-то вроде «Опубликован» (хотя это тоже решается правами, что-то вроде «разрешено читать группе пользователей с правами „Админ“).
                                                                                                                    Я просто подумал, что возможность «Начать голосование» — это и есть „публикация“ голосования на фронтэнде.
                                                                                                                    Вобщем, я не совсем понял что имелось ввиду)

                                                                                                                    Как правильно написал m007 чуть ниже:
                                                                                                                    >Возможность НАЧАТЬ голосование это значит разрешить Запись в сущность Голосования.
                                                                                                                  +2
                                                                                                                  Возможность НАЧАТЬ голосование это значит разрешить Запись в сущность Голосования.
                                                                                                                    0
                                                                                                                    Нет, Запись в сущность Голосования = проголосовать в уже идущем голосовании.
                                                                                                                      0
                                                                                                                      Пример на псевдо языке:

                                                                                                                      НашПост = МассивСущностей.ВзятьСущностьПост();
                                                                                                                      НашеГолосование = НашПост.ВзятьСущностьГолосования();

                                                                                                                      // Проверяем было ли добавлено голосование к этому посту.
                                                                                                                      Если(НашеГолосование == СУЩНОСТЬ_СУЩЕСТВУЕТ) {

                                                                                                                      Если(НашеГолосование.ПравоНаЗапись == РАЗРЕШЕНО_ВСЕМ) {
                                                                                                                      // Голосование разрешено
                                                                                                                      } Иначе {
                                                                                                                      // Голосование запрещено
                                                                                                                      }
                                                                                                                      }
                                                                                                                        –1
                                                                                                                        Самого важного нет. Вот я и спрашиваю — как определить что к этому посту можно добавить голосование?
                                                                                                                          0
                                                                                                                          Автор, вы точно уверены, что пишете ЦМС?

                                                                                                                          Голосование кто и где добавляет? Дядя Вася в Хацапетовке?

                                                                                                                          Вот там и будете проверять есть ли у сущности добавляющей голосование (допустим эта сущность == пользователь) права на добавление голосования вообще или к данному конкретному посту в частности.
                                                                                                                            0
                                                                                                                            Так откуда я возьму информацию, можно ли к ЭТОМУ посту добавлять голосование? Где у поста это будет прописано? :)
                                                                                                                              0
                                                                                                                              Уф. Вы совсем запутались?

                                                                                                                              У вас есть пост, который может иметь право на наличие голосования а может и не иметь.
                                                                                                                              И у вас есть пользователь, который может иметь право, а может и не иметь.

                                                                                                                              В первом случае это свойство поста (может/не может иметь голосования).
                                                                                                                              Во втором случае это права пользователя (может/не может добавить голосование к данному конкретному посту)
                                                                                                                                –1
                                                                                                                                Постойте. Ваши коллеги по мысле ведь говорили
                                                                                                                                Просто приведите любой пример и он сведется к Созданию, Чтению, Записи, Удалению. Любой пример, потому что это фундаментальные действия.


                                                                                                                                Где тут «Голосование»? Его нету. Только создание, чтение, запись, удаление. ;)

                                                                                                                                Я и спрашиваю (последний раз) — откуда я возьму информацию о наличии права создать голосование в посте? (не путайте с отдачей голоса)
                                                                                                                                  –1
                                                                                                                                  блин, ваши голосования, это логический слой, модель, которая передает данные уже в слой, который работает с БД, вот на последнем уровне и определяются права… незнаю уже как сказать проще =))
                                                                                                                                    –1
                                                                                                                                    Простите, но у меня уже терпения не хватает.
                                                                                                                                    Вы дурак или да?

                                                                                                                                    Цитирую самого себя
                                                                                                                                    «В первом случае это свойство поста (может/не может иметь голосования).
                                                                                                                                    Во втором случае это права пользователя (может/не может добавить голосование к данному конкретному посту)»

                                                                                                                                    Голосование это сущность в вашей системе. Сообщение это сущность в вашей системе.
                                                                                                                                    Это абстрактные сущности.

                                                                                                                                    При создании конкретного сообщения, мы:
                                                                                                                                    1) смотрим (ЧИТАЕМ) свойства сообщения, может ли оно иметь (свойство) голосования.
                                                                                                                                    2) смотрим (ЧИТАЕМ) в права Пользователя создающего Сообщение, может ли он добавить(ЗАПИСАТЬ в одной из свойств Сообщения) Голосование.

                                                                                                                                    Вы еще не поняли откуда вы возьмете информацию о наличии права?

                                                                                                                                    Повторяю, в списке прав конкретного пользователя, который создает сообщение.

                                                                                                                                    Где он(список) может хранится? Где угодно.
                                                                                                                              +1
                                                                                                                              Сущность Поста может содержать поля:

                                                                                                                              ид поста
                                                                                                                              ид автора
                                                                                                                              название
                                                                                                                              содержание
                                                                                                                              дата создания
                                                                                                                              ид сущности комментариев
                                                                                                                              ид сущности голосования

                                                                                                                              Для каждого поля можно задать права доступа (чтение, запись)

                                                                                                                              Нас интересует голосование.
                                                                                                                              Для поля «ид сущности голосования» выставляем следующие права:

                                                                                                                              Запись разрешаем группе пользователей или просто перечисляем ид пользователей которым можно записывать в это поле или разрешить всем запись или запрещаем всем (тогда голосование невозможно для данного поста).

                                                                                                                              Чтение разрешаем всем, для того чтобы определить возможность/невозможность прикрепления голосования.

                                                                                                                              Далее просто проверяется разрешено ли такому то пользователю с таким то ид (ид узнается на основе идентификатора сессии) записывать в сущность Поста, в поле с именем «ид сущности голосования». Если разрешено то он может прикрепить голосование. Для конечного пользователя это будет отображено в интерфейсе.
                                                                                                                                0
                                                                                                                                Для каждого поля можно задать права доступа (чтение, запись)


                                                                                                                                Права на каждое поле у каждой сущности? Небольшой сайт с 1'000 объявлений и 30 полями превращается в 30'000 записей о возможности доступа. О-о-о-о…

                                                                                                                                Заканчиваю диалог. :)
                                                                                                                                  +3
                                                                                                                                  Учите ООП и наследование. Тогда у вас не будет дурацких замечаний о 30к записей для 1к объявлений.

                                                                                                                                  У вас будет одна запись на каждую «абстрактную» сущность (объявление, пользователь)
                                                                                                                                  И по одной записи для каждой «конкретной» сущности (конкретное объявление, конкретный пользователь), где имеются отличия в правах от предка.
                                                                                                                                  И да, посмотрите еще как организованы таблицы прав доступа в MySQL к примеру — будет поучительно.

                                                                                                                                  P.S. Рано вам еще писать CMS.
                                                                                                                                    0
                                                                                                                                    Вы скатились на оскорбления. Дурной тон.

                                                                                                                                    Всего лишь стоило процитировать ваших коллег. Виртуалы?
                                                                                                                                      0
                                                                                                                                      Согласен, давайте не будем обсуждать кому рано, а кому поздно писать CMS.
                                                                                                                                      Человек написал статью и хочет услышать критику / мнение хабра. Довольно интересное обсуждение получается, кстати…
                                                                                                                                        0
                                                                                                                                        Очень дурной тон. Но я крайне плохо переношу глупость помноженную на необоснованное самомнение.

                                                                                                                                        Простите.
                                                                                                                                      +1
                                                                                                                                      Ну это уже проблема реализации… Уверяю, что не превратится, если подумать хорошо )
                                                                                                                                        +1
                                                                                                                                        Все зависит от архитектуры. Вы даже не пытаетесь разобраться до конца, что права доступа можно хранить в самой сущности, а можно для конкретного пользователя.

                                                                                                                                        Заканчивайте и делайте как считаете нужным. Я остался при своем мнении.
                                                                                                                    0
                                                                                                                    Вы говорили, что вы сможете описать все фундаментальными действиями. А теперь — отказываетесь. Так как описать лечение и убийство, которое сводится к одному действию — нельзя.
                                                                                                                      0
                                                                                                                      От фундаментальных действий не отказывался. Не совсем понятен вопрос.
                                                                                                              0
                                                                                                              это физические действия, crud он и в африке crud, но поверх него есть еще и нефондументальные логические (связывание, развязывание, изменение конкретных полей которое требует дополнительного подверждения аутефикации -это все к примеру одна операция update), которых у меня может быть довольно много.

                                                                                                              Как быть в такой ситуации
                                                                                                                0
                                                                                                                Дробите объект контроля на более мелкие.

                                                                                                                На каком-то из этапов все сведется только к CRUD
                                                                                                                  0
                                                                                                                  а зачем мне это делать, если у меня есть полная подходящаа мне система прав на acl, в которой я могу реализовать все прихоти заказчика по распределению прав, не выстраивая еще с десятков объектов контроля, которые должны раздробить все операции на crud? Зачем мне столько гемороя то?
                                                                                                                    0
                                                                                                                    А настраивая acl вы делаете тот же самый геморрой, что и дробя на сущности.
                                                                                                                      0
                                                                                                                      Что-то я не припомню что бы я мог испытывать какой-то геморой с ними.
                                                                                                                        0
                                                                                                                        Значит и с наследованием и с дискретизацией сущностей не будете :)
                                                                                                                      0
                                                                                                                      Это действительно абсолютно лишний гемморой в любом случае.
                                                                                                            +1
                                                                                                            Помниться еще в школе мне сказали что каждый программист должен написать свой тетрис (или «удав и яблоки» или что то в этом духе). Теперь же тенденция в том, что каждый веб-программист должен написать свою CMS. И я не исключение. В основном новая (своя) CMS пишется для собственного же удобства, для оптимизации рутинных задачи веб-студии и т.д. + полная независимость от сторонних разработчиков и более полное понимание принципов работы этой самой CMS.
                                                                                                              0
                                                                                                              CMS это ещё нормально и в общем то правильно, ИМХО. Но вот последний год я наблюдаю такую тенденцию, что каждый php- программер «должен» написать свой фреймворк. Сам подпадаю под это, но это все же в большинстве случаев является своеобразным just for fun =)
                                                                                                              0
                                                                                                              В MODx очень удобно — создал роль, наделил её правами, поставив галочек и раздавай кому хочешь
                                                                                                                0
                                                                                                                Другой вопрос — кто, где и каким образом определяет эти самые «права».
                                                                                                                0
                                                                                                                Вопрос, использование битовых масок сделано чтобы усложнить себе жизнь?

                                                                                                                Или это насущная необходимость?
                                                                                                                  0
                                                                                                                  Насущная необходимость. Это абсолютно реализуемо и логически понятно. Кроме того быстро.
                                                                                                                    0
                                                                                                                    Поясните в чем эта необходимость?

                                                                                                                    Какие предпосылки заставили пользоваться битовой маской. А не, допустим, коллекцией или массивом.
                                                                                                                      0
                                                                                                                      Зачем мне массив? Это моя битовая маска умноженная на 8.

                                                                                                                +2
                                                                                                                В unix не мандатная система разграничения доступа, а дискреционная.

                                                                                                                Дискреционное управление доступом

                                                                                                                Мандатное управление доступом
                                                                                                                  0
                                                                                                                  И все же я ошибся в терминах.
                                                                                                                  +1
                                                                                                                  Прежде чем оценивать схему, надо ответить минимум на два вопроса:
                                                                                                                  1. Приведите примеры востребованных моделей сайтов, где ваша схема незаменима или сложнозаменима — в максимально полном ее виде. Смысл вопроса: а не получится ли так, что она будет нужна только в очень редких специфических случаях?
                                                                                                                  2. Визуализируйте управление правами, то есть сделайте в html-е прототип той части админки, где раздаются права пользователям/группам и определяются права для объектов. Учитывая универсальность и то, что «у нас количество этих операций — потенциально неограниченно». Смысл: понять, можно ли реализовать удобный и простой интерфейс, ведь даже самая универсальная система обречена на провал, если ей будет неудобно пользоваться.

                                                                                                                  Есть еще и человеческий фактор кстати.
                                                                                                                    0
                                                                                                                    Я, в свою очередь взял ACL за стандарт и теперь пользую только его, но у меня возник вопрос другого плана. Как сделать так что бы при добавлении новых модулей система сама распознавала новые объекты (сущности)? В принципе реализация которая есть сейчас меня не очень устраивает. Суть в том что как только появляется запрос на права доступа для определенного ресурса и его нет в списке, то создается правило на «только чтение» и записывается туда куда надо. Но мне кажется что такой метод не лучший
                                                                                                                      +3
                                                                                                                      Автор, таки прислушайтесь, к тому что вам говорят aprusov, zarincheq, m007, ashofthedream.

                                                                                                                      Ваша методология слишком узкоспециальна и будет иметь большие проблемы с расширением.
                                                                                                                      Мелочи вроде битовых операций в БД можно опустить.

                                                                                                                      ACL и работа с сущностями в рамках CRUD это разумное решение для расширяемой системы.
                                                                                                                        –2
                                                                                                                        А объяснить откуда голосование возьмете, так и не смогли. Ай-ай-ай…
                                                                                                                        0
                                                                                                                        В свое время тоже столкнулся с проблемой разделения прав доступа, получилось что-то похожее на след.:
                                                                                                                        Есть юзер[user_id], у него есть группа[group_id].
                                                                                                                        Так-же есть, само правило[rule], и его значение[value].
                                                                                                                        Если пользователь не авторизован, то выбираются все права которые назначены пользователю с id=0.
                                                                                                                        Для авторизованных схема такая:
                                                                                                                        Берутся все права для группы в которой находится пользователь, и идут назначения вида:
                                                                                                                        $ruleset[$rule]=$value;
                                                                                                                        Потом берутся все права именно для этого пользователя, по [id]. И опять выполняется $ruleset[$rule]=$value;
                                                                                                                        На практике часто идет что правила булевые + появляется некая структура для определенных видов доступа, допустим находимся мы в разделе с id=5, смотрим правило 'moder_5', если есть, уже можно посмотреть следующий виток правила, допустим 'moder_5_deletetask'.
                                                                                                                        Пока хватало.
                                                                                                                          0
                                                                                                                          И, да, я рассматриваю систему правил не к определенным объектам и сущностям, а строго заданных правил(с возможностью разрешить то, или иное действие, непосредственно нужному пользователю).
                                                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                            0
                                                                                                                            Могли бы вы привести пример системы управления контентом для разработчика, но не для пользователя?
                                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                0
                                                                                                                                Стив Макконел Комплит Коде
                                                                                                                                там тока говорилось про Понтиак Ацтек
                                                                                                                              0
                                                                                                                              для пользователя CMS имеет конечную функциональность, но для разработчика модификация и расширение приложения либо может быть гемороем, либо удобным инструментом. Делать систему чисто для пользователя можно и на «лапше», но какие возможности расширения в дальнейшем?
                                                                                                                              0
                                                                                                                              У меня сейчас на большом проекта работает схожая идея. Схожая в том, что я оставил юниксовые биты для базовых операций (read, write, execute) для владельца/группы/всех остальных, только у execute другой смысл (жалко бит терять было :) ). Все дополнительные права (там, где нужно) раздаются через ACL. Это позволяет сохранить скорость и удобство при базовых проверках прав, т.к. большинство из них ограничиваются проверкой базовых read/write, имея возможность при этом пользовать расширенные возможности по регулированию прав через ACL.
                                                                                                                              В базе около миллиона пользователей, в среднем 4-5 миллионов объектов, около 5 миллионов pageview в сутки, до 200 тысяч пользователей в сутки.
                                                                                                                                0
                                                                                                                                А можно чуть подробней — как организован ACL? Сколько в его таблицах записей?
                                                                                                                                0
                                                                                                                                Описываемый способ лучше использовать только для кэш значений, чтоб быстренько проверить доступ, а реальные взаимоотношения объектов с действиями, которые они (над ними) могут выполнять и кто может, реализовать на высокоуровневом принципе.
                                                                                                                                Это все равно что, реализовывая отношения между таблицами “один — ко многим”, у одиночных записей создавать поле с перечнем идентификаторов. Или при связи “многие — ко многим” не использовать третью связующую таблицу, а опускаться на низкоуровневый принцип.
                                                                                                                                — Во-первых, объекту должно быть по барабану, кто его может создавать или удалять, т.е. теоретически он не должен владеть информацией о правах. Другое дело, если объект, совершаемый действия (пользователь) будет владеть этой информацией.
                                                                                                                                Во-вторых, cms должна сама себя документировать (если так можно сказать) – т.е., действия, которые представляются битовыми значениями, по любому должны нести смысл даже для самой cms, для новых модулей и т.д. А так получается, что только Вы знаете, что это за действие. Выручит только некий стандарт. Вот у юникса – стандарт, а у Вас эта битовое значение динамическое, кто знает, что четвертый нулик запрещает комментировать? – только Вы.
                                                                                                                                  0
                                                                                                                                  Это правда зависит от желаемых возможносей cms. Но я думаю от cms все ждут гибкости и универсальности…
                                                                                                                                  +1
                                                                                                                                  О как много людей знают про ООП, ACL, оперируют словами «абстракция» и «наследование»…
                                                                                                                                  А на первом же собеседовании выясняется, что они понятия не имеют про битовые операций, про таблицу истинности XOR и тому подобное…

                                                                                                                                  Куда катится вебдев…

                                                                                                                                    0
                                                                                                                                    Это общеизвестная проблема кадров. Все толковые веб-разработчики уже где-то работают и уже сами выбирают место, куда бы они хотели пойти…
                                                                                                                                      +1
                                                                                                                                      Мне придти к вам на собеседование, что бы вы меня погоняли по битовым операциям и булевой логике :)?