Комментарии 15
Спасибо за Вашу работу.
Если ли какие нибудь планы по поводу будущего функционала проекта?
Жаль нет реализации ABAC для django…
Во вторых, описанная система не ограничивает разработчика в сложности кода, регулирующего доступ.
Так, в примере, доступ к объекту SomeObject зависит от того, принадлежит ли пользователь к группе редакторов или просмотрщиков. В данном случае, бизнес-правило было установлено таким образом.
Система позволяет разработчику устанавливать практически любые, сколь угодно сложные, бизнес-правила для определения доступа к объектам. Фактически, задачей разработчика правил, является установление фильтра для списка объектов, на основании контекста, задаваемого объектом Request.
Да, для установления бизнес-правил в нашей системе используется код.
Однако, я прошу обратить внимание на DjangoAccessPlugin. Используя систему динамических правил, мы сделали плагин, реализующий обратно совместимый контроль доступа, с помощью 7 строк кода.
Думаю, желающие смогут легко прикрутить код плагина, ориентирующегося на хранимые правила, подобные описанным в приведенной статье.
upd да, если вы не поняли, приведенные в статье правила тоже являются кодом
Так уже есть Django-rules https://github.com/dfunckt/django-rules, который как раз предоставляет возможность управления доступами используя правила заданные в коде.
rules + guardian дают гибкую связку для доступов, просто не надо в guardian задавать явный доступ на все имеющиеся объекты.
Из статьи кажется, что ваш проект может управлять доступом на уровне полей модели, хотя это не так (поправьте, может ошибаюсь). В вашем примере, на странице проекта и в репозитории, вы используете стандартный рецепт с модифицированными get_list_display и get_fieldsets в UserAdmin именно для вашего случая:
def get_fieldsets(self, request, obj=None):
fieldsets = list(super(AccessUserAdmin, self).get_fieldsets(request, obj)) or []
if request.user.is_superuser:
return fieldsets
if not obj:
return fieldsets
if obj.pk != request.user.pk:
return self._fieldsets_exclude(fieldsets,['password', 'email'])
return self._fieldsets_exclude(fieldsets,['is_superuser'])
И зачем нужен AccessManager, когда джанго поддерживает в своём API проверку доступа на уровне объектов? Как в User.has_perm так и в has_perm для бэкендов аутентификации и авторизации (с версии Django 1.7).
https://docs.djangoproject.com/en/1.11/ref/contrib/auth/#django.contrib.auth.models.User.has_perm
https://docs.djangoproject.com/en/1.11/ref/contrib/auth/#django.contrib.auth.backends.ModelBackend.has_perm
Представьте себе базу, содержащую тысячу пользователей, каждый из которых управляет сотней объектов какой-нибудь модели. Вам нужно показывать пользователю только те объекты, которые он может видеть и которыми может управлять. Пользуясь Rules, вам придется получить весь список из 100000 объектов, а потом протестировать каждый из них на право доступа текущего пользователя. Это не эффективно, вы конечно, не будете так делать и вам придется писать фильтр, определяющий список доступных объектов — то есть, делать ровно то, что уже сделано в Access.
Попробуйте интегрировать Rules в админку, вы увидите, что она — сама по себе — не позволяет эффективно ограничить списки объектов.
Вы правы, Access (пока?) не позволяет контролировать доступ на уровне полей, такой контроль сделан в примере для того, чтобы обеспечить полноту защиты доступа при установленных с помощью Access правилах. Одновременно, пример показывает простоту интеграции кастомных админок и Access.
upd да, спасибо, что напомнили про Rules, в ней реализовано несколько полезных техник Джанго, которые можно было бы внедрить и в Access.
1. Реализован доступ «Видеть» с поддержкой в админке (чего я не нашел в своё время в уже готовых решениях).
2. Унифицировано решение для фильтрации объектов в ModelAdmin.changelist_view на основе доступов (через ModelAdmin.get_query_set).
Но настораживает ваше решение сделать свой слой управления доступами поверх стандартного механизма Джанго, механизм управления доступами Джанго подключается к вашему, а не наоборот. Это может привести к сложностями при использовании других готовых решений для Джанго… если стороннее приложение будет проверять доступ через has_perm Джанго, оно ведь пролетит мимо доступа заданного правилами в вашем решении?
Вниманию интересующихся, только что опубликован пакет django-access-tastypie предоставляющий бакенд авторизации (то есть проверки правил доступа), совместимый с django-access, для пакета django-tastypie
Это все прекрасно пока у вас 1 страница админки соответствует 1 объекту данных. А можете ли вы в рамках такой системы разруливать ситуации, когда у вас N объектов данных на странице, и доступ назначается не столько к данным, сколько к сценариям того, что можно выполнить с этими данными?
Например если на странице несколько объектов связанных в БД отношением класса M-N-K, и действия одного пользователя должны влиять на них всех, а другой пользователь части из них даже не видит, но может работать с видимой ему частью.
Насколько я знаю, для такого пока никто не придумал удобных решений. Это делают либо цепляя доступ к вьюхам, а не к моделям. Либо вообще выносят проверку доступа вместе с бизнес-логикой в интеграционную шину, а приложения и базы априори считают, что если им какая-то команда пришла от шины, значит шина 100% все проверила и разрешила.
Но управлять таким доступом все-равно ад в обоих этих решениях, для любой более-менее крупной и сложной системы.
А если туда ещё подвозят мандатные метки уровня ОС...
2. Если рассматривать именно сформулированную вами проблему, то с точки зрения например ООП, если говорить о едином сценарии, выполняемом именно над группой объектов (то есть не повторяющийся сценарий для каждого объекта из группы, а вот именно для группы, как единого целого), такой сценарий так или иначе, является методом некоторого объекта (как вариант, но не обязательный — только что сформированной группы объектов). Таким образом, разновидность права на доступ к выполнению сценария будет привязана к типу этого объекта, а само право — являться следствием некоторой связи между пользователем (или другим субъектом права) и этим объектом.
3. django-access как раз позволяет отложить решение о предоставлении доступа к тем или иным объектам на стадию интеграции различных приложений. Это является разумным решением, поскольку одно и то же приложение (в смысле «приложение Джанго» — пакет или подсистема), будучи использовано в разных проектах, может по-разному регулироваться в этих проектах в плане предоставления доступа к своим данным. В то же время, django-access не вносит своих собственных регулирующих элементов в проект, а опирается на существующую структуру данных. В подавляющем большинстве ситуаций, особенно что касается разделения доступа по горизонтали, порядок доступа к данным является следствием существующих отношений объектов, а не регулируется произвольно персоналом. Когда же предоставление доступа все же регулируется вручную (полностью или частично), не представляет сложности добавить в проект модели регулирующих доступ объектов и соответствующие связи: пакет позволяет легко адаптировать такие дополнительные сущности, как показывает пример плагина DjangoAccessPlugin.
Вниманию интересующихся, опубликовано обновление 0.0.2b3, содержащее обратно совместимый бакенд авторизации для адаптации пакетов третьих сторон, использующих вызов user.has_perm
.
Также, пересмотрен алгоритм обратно совместимого с джангой плагина, исправлены некоторые ошибки, выполнены небольшие оптимизации, добавлено немножко логирования.
Вниманию интересующихся, опубликован пакет Django-Access-Select2 внедряющий фильтрацию в пакет Django-Select2 в соответствие с назначенными правилами доступа.
Гибкая система управления доступом на уровне объектов-записей