Django основанные на роли представления?

Мороженое является правильным... и неправильно. Я нахожу, что это техническое описание имеет тенденцию представлять все замечательные особенности MiGLayout, входя во вшивые песчаные детали, которые мы редко были бы, если когда-либо, использовать... Бумага колеблется между тем, чтобы быть учебным руководством и ссылкой.

Теперь, предоставленные демонстрационные заявки (в Расположение МиГа основная страница MiG Java Components страницы и ) очень хорошо поданы: Вы видите компоненты и как они перемещаются / измененный, и можно смотреть на исходный код, используемый, чтобы сделать это расположение, которое является драгоценным источником конкретной реализации. Драгоценный, потому что я не нашел много проектов с открытым исходным кодом на самом деле с помощью этого расположения (возможно, я просто не искал правильно).

31
задан slypete 10 October 2009 в 00:29
поделиться

7 ответов

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

http://docs.djangoproject.com/en/dev/topics/auth/

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

Есть две части, на которые вам нужно обратить внимание.

  1. Убедитесь, что пользователь запрашивает страницу имеет на это разрешение.
  2. Отображать ссылки на пользователя, только если он имеет разрешение.

Для 1. вы можете проверить разрешения в декораторе как таковом:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def some_view(request):

Для 2. разрешения текущего авторизованного пользователя хранятся в переменной шаблона {{perms}}. Этот код проверяет то же разрешение, что и выше.

{% if perms.polls.can_vote %}
    <a href="/vote">vote</a>
{% endif %}

Чтобы создать список ссылок, вы можете выполнить итерацию по user.get_all_permissions () и получить ссылки (или функцию, которая генерирует ссылку) из dict:

def more_elaborate_list_of_links_for_a_perm(user):
    return ["/link1", ...]

_LINKS = {
    'polls.can_vote' : lambda u: ["/user/specific/link/" + u.id],
    'polls.can_close': lambda u: ['/static/link/1', 'static/link/2'],
    'polls.can_open' : more_elaborate_list_of_links_for_a_perm
}

def gen_links(user):
    # get_all_permissions also gets permissions for users groups
    perms = user.get_all_permissions()
    return sum((_LINKS[p](user) for p in perms if p in _LINKS), [])

Вероятно, много другие подходы.

43
ответ дан 27 November 2019 в 22:13
поделиться

Если вам не нужны реальные списки ACL для каждого объекта, вы можете просто использовать систему разрешений Django. Чтобы получить список всех доступных разрешений:

from django.contrib.auth.models import Permission
perms = Permission.objects.all()

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

Вы можете взломать эту систему Django чтобы соответствовать вашим потребностям с точки зрения этой модели авторизации (RBAC), или вы можете предложить решение, подобное ACL.

1
ответ дан 27 November 2019 в 22:13
поделиться

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

Краткая версия заключается в том, что вы можете создать класс (мы назвали их TokenBuckets, которые содержат токены) и каждый объект (на странице сведений или на странице списка, или что-то еще) может спросить у пользователя TokenBucket, разрешен ли определенный уровень доступа.

По сути, это странный вид системы ACL. Создать механику было несложно. Вся магия заключается в том, чтобы определить, при каких обстоятельствах какие жетоны попадают в ведро.

1
ответ дан 27 November 2019 в 22:13
поделиться

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

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

class Group( models.Model ):
    name = models.CharField( ... )
    parent = models.ForeignKey( 'self', blank=True, null=True)
    content_type = models.ForeignKey( ContentType )
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey( 'content_type', 'object_id' )
    ...

Чтобы заставить ее работать, мы также создали модель, которая будет служить профилем пользователя модели пользователя django. Все, что он содержал, было ManyToManyField, связанным с моделью Group выше. Это позволило нам предоставить пользователям доступ к нулю или более группам по мере необходимости. ( документация )

class UserProfile( models.Model ):
    user = models.ForeignKey( User, unique=True )
    groups = models.ManyToManyField( Group )
    ...

Это дало нам лучшее из обоих миров и удерживало от попыток втиснуть все в систему разрешений django. Я' m, используя эту базовую настройку для управления доступом пользователей к спортивному контенту (некоторые пользователи могут получить доступ ко всем лигам, некоторые только к одной или двум конференциям, некоторые имеют доступ только к отдельным командам), и это хорошо работает в этой ситуации. Вероятно, это могло бы быть достаточно обобщенным, чтобы соответствовать вашим потребностям.

2
ответ дан 27 November 2019 в 22:13
поделиться

Есть новый очень интересный проект о разрешениях на основе ролей в Django: http://bitbucket.org/nabucosound/django-rbac

5
ответ дан 27 November 2019 в 22:13
поделиться

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

Функции просмотра были украшены:

def needs_capability(capability,redirect_to="/cms/"):
   def view_func_wrapper(view_func):
       def wrapped_view_func(request,*args,**kwargs):
           if not request.role._can(capability):
              return HttpResponseRedirect(redirect_to)
           return view_func(request,*args,**kwargs)
       return wrapped_view_func
   return view_func_wrapper

Остальная часть магии находится внутри атрибута request.role , который получил устанавливается внутри контекстного процессора. Прошедшие проверку пользователи получили роль для немытых масс a DummyRole.

Доступ к информации был дополнительно ограничен внутри шаблонов:

 {% if not request.role.can.view_all_products %}
          Lots of products, yeah!
 {% endif %}

Не самое чистое решение, на мой взгляд, но работало, как ожидалось.

0
ответ дан 27 November 2019 в 22:13
поделиться

У нас была аналогичная проблема. Группы Django ДЕЙСТВИТЕЛЬНО не подходят для этого, но вы можете их использовать.

Мы сделали это следующим образом:

Каждый объект с контролируемым доступом имеет отношение ManyToMany к таблице групп. Каждая группа использовалась для определения определенного типа разрешений («может просматривать основные сведения о пациенте», «можно редактировать контактную информацию пациента» и т. Д.). Пользователи добавляются в группы, для которых у них должны быть разрешения (в вашем примере, когда вы видите только пациентов в этой больнице, у вас может быть группа «долина-вид-больница»).

Затем, когда вы переходите к отображению списка записи для пользователя, вы фильтруете на основе объединения двух групп. У пользователя должны быть все связанные разрешения группы для просмотра данного объекта.

Если ваша система требует этого, вы можете сохранить отдельные ManyToMany отрицательных разрешений или отдельные разрешения на чтение / запись. Вы также можете определить набор мета-групп (врач, медсестра), в результате чего ваш поисковый фильтр будет извлекать фактическое подмножество разрешений.

Что касается вашей проблемы с панелью ссылок, вы можете сгенерировать их программно, используя ту же систему - фильтровать по классам объектов, которые пользователь может просматривать или редактировать, а затем использовать функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекс каждого класса объектов.

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

или отдельные разрешения на чтение / запись. Вы также можете определить набор мета-групп (врач, медсестра), в результате чего ваш поисковый фильтр будет извлекать фактическое подмножество разрешений.

Что касается вашей проблемы с панелью ссылок, вы можете сгенерировать их программно, используя ту же систему - фильтровать по классам объектов, которые пользователь может просматривать или редактировать, а затем использовать функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекс каждого класса объектов.

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

или отдельные разрешения на чтение / запись. Вы также можете определить набор мета-групп (врач, медсестра), в результате чего ваш поисковый фильтр будет извлекать фактическое подмножество разрешений.

Что касается вашей проблемы с панелью ссылок, вы можете сгенерировать их программно, используя ту же систему - фильтровать по классам объектов, которые пользователь может просматривать или редактировать, а затем использовать функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекс каждого класса объектов.

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

медсестра), что приводит к тому, что ваш поисковый фильтр извлекает фактическое подмножество разрешений.

Что касается вашей проблемы с панелью ссылок, вы можете сгенерировать их программно, используя ту же систему - фильтр на основе классов объектов, которые пользователь может видеть или edit, а затем используйте функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекса каждого класса объектов.

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

медсестра), что приводит к тому, что ваш поисковый фильтр извлекает фактическое подмножество разрешений.

Что касается вашей проблемы с панелью ссылок, вы можете сгенерировать их программно, используя ту же систему - фильтр на основе классов объектов, которые пользователь может видеть или edit, а затем используйте функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекса каждого класса объектов.

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

вы можете сгенерировать их программно, используя ту же систему - фильтр на основе классов объектов, которые пользователь может видеть или редактировать, а затем использовать функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекса каждого класса объектов.

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

вы можете сгенерировать их программно, используя ту же систему - фильтр на основе классов объектов, которые пользователь может видеть или редактировать, а затем использовать функцию типа get_absolute_url () (можно назвать ее get_index_url () ), чтобы вернуть ссылки для индекса каждого класса объектов.

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

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

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

4
ответ дан 27 November 2019 в 22:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: