Django AdminSite / ModelAdmin для конечных пользователей? - PullRequest
21 голосов
/ 03 апреля 2011

Не всем программам необходим интерфейс администратора для «производителей контента» слева и сайт для «посетителей / участников» справа.

Часто говорят, что «администратор неваше приложение "(см., например, принятый ответ (март 2009 г.) ).

Я не смог найти такое ограничение, упомянутое в документах Django.Кажется, есть основополагающее предположение выше - « мощный и готовый к работе интерфейс, который производители контента могут немедленно использовать, чтобы начать добавлять контент на сайт » - но разные уровни доступа, безусловно,ожидается, даже упоминается в FAQ .И какой другой вариант использования для нескольких экземпляров AdminSite в любом случае?

В настоящее время я работаю над программным обеспечением, которое в основном является интерфейсом CRUD.Каждый пользователь должен пройти проверку подлинности, и единственное различие между пользователями-администраторами и клиентами заключается в том, что последние могут работать только со «своими» объектами (и не имеют доступа к определенным моделям, таким как «Пользователь» и т. Д.). Между прочим, "их" в моем случае не связано с тем, кто создал объект, а с какой "Компанией" она связана с .

Есть ли веская причина не просто придерживатьсяинтерфейс администратора, и просто настроить правильный коктейль разрешений?Можно ли доверять разрешениям ModelAdmin?Почему бы просто не позвонить всем вошедшим в систему пользователям "staff"?

Для традиционных представлений без прав администратора я вижу, как я переписываю то, что, похоже, уже есть: ModelForm хорошзапуск, но функциональность CRUD и фильтры, зависящие от типа (включая детализацию по дате), не являются легкодоступными компонентами.Функциональность администратора уже обеспечивает подавляющее большинство функций, которые нужны конечным пользователям, и настройка полей / фильтров / шаблонов и т. Д. Достаточна для моих нужд.Очевидно, что когда я добавляю новую функцию, например, видимость ее кнопки и доступ к соответствующим представлениям, требуется проверка разрешения.Я не беспокоюсь об этом.Мне просто любопытно, как в этом случае функции Admin должным образом покрываются встроенным набором разрешений.Есть опыт?

ОБНОВЛЕНИЕ: Извините, основная часть этого вопроса кажется неясной.Я не беспокоюсь о своих настройках, я беспокоюсь о доверии существующему приложению admin и его реализации разрешений.Смотрите также комментарии Даниэля и FallenAngel.

Ответы [ 3 ]

10 голосов
/ 27 апреля 2011

У нас есть система, которая работает так, как вы просили.

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

Логика в том, что администраторы - это люди, работающие в компании, которые могут иметь все права доступа (суперпользователи, как сказал sjango) или ограниченный доступ.приложениям, но могут видеть все связанные записи БД из тех, к которым у них есть доступ.Клиенты - это люди, которым мы продаем нашу программу, они имеют ограниченный доступ к администратору и могут видеть только связанные с ними записи.пользователи являются клиентами наших клиентов ...

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

Для решения вместо приложения сайта usnig django (которым я никогда не пользовался и у меня мало информации) мы создали модель, расширяющую пользователя Django, имеющую полекак role это роль пользователя является системным администратором, тогда он может видеть все (если он суперпользователь, в противном случае он использует разрешения как обычно) ... Если нет, он может получить доступ к записям, относящимся к их веб-сайту (компания в вашей ситуации).

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

Таким образом, вы можете при необходимости фильтровать записи, принадлежащие определенной компании ...

В моих моделях у меня есть Kullanici, который наследует модель пользователя

class Kullanici(User):
    rol = SmallIntegerField()# 1 if system admin, 2 if cusotmer etc...

Затем я пишу несколько методов, которые переопределяют методы администратора, такие как ModelAdmin.save и modelAdmin.queryset, которые выполняют следующую проверку ...

#override admin queryset method
def override_queryset(obj, req):
    qs = super(type(obj), obj).queryset(req)
    kullanici = Kullanici.objects.get(id=req.user.id)
    if kullanici.rol == 10:
        return qs
    return qs.filter(site=kullanici.site)

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

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

Для дальнейшегоограничение я использовал функцию, чтобы показать / скрыть поля модели.В файле admin .py:

class SomeModelAdmin(ModelAdmin):
    exclude= []
    def changelist_view(self, request, extra_context=None):
        extra_context = {'exclude':['field1','field2']}
        return get_admin_listview(self, request, extra_context)


def get_admin_listview(obj, req, extra):
system_admin = Kullanici.objects.get(id=req.user.id).rol == 1
if not system_admin:
    if 'exclude' in extra.keys():
        for key in extra['exclude']:
            if key not in obj.exclude:
                obj.exclude.add(key)

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

Handycaps,Может вызвать кеширование админки django, что случалось со мной один или два раза за 8 месяцев.Другой важной частью является то, что вы не можете ограничивать фильтры администратора, поэтому, если у вас есть фильтр, требующий ограниченного доступа, вы не можете фильтровать ключи фильтра.Вы можете либо отобразить его со всеми параметрами, либо просто не использовать его.

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

ОБНОВЛЕНИЕ: Да, система разрешенийпрост и безопасен, если вы проверяете исходный код license_required decorator из последнего кода соединительной линии ...

Логика проста, у пользователя есть соответствующее разрешение,связанный взглядВ противном случае связанный вид или код не выполняется вообще.Итак, permissons обеспечивает достаточную безопасность для администратора django.Контроль разрешений можно использовать как на уровне представления, так и / или на уровне шаблона.

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

Последняя проблема - механизм фильтрации страниц просмотра django и admin.Поскольку почти все административные фильтры используют GET для фильтрации данных и передают идентификаторы в URL для отображения конкретной записи. Секретная часть книги django показывает основную информацию о возможных проблемах безопасности и о том, как django их обрабатывает ... С другой стороны, 22 декабря 2010 г. Обновление безопасности показывает такую ​​важную уязвимость, которая требуетдостаточно информации о структуре модели.

10 голосов
/ 01 мая 2011

В admin нет ничего особенного.Он ведет себя так же, как и любой другой взгляд.Таким образом, если он использует разрешения для определения доступа (например, если вы установили для пользователя .is_staff значение True, но предоставили ему доступ только к определенным разрешениям), то он будет одинаково безопасен для любого представления, которое вы можете создать и которое использует разрешения дляопределить доступ.

В том же духе, настройка, которую вы предоставляете ModelAdmin, приведет к реализации, которая будет в равной степени безопасна, как и все, что вы можете написать.1008 * для вашей модели, например:

def has_change_permission(self, request, obj=None):
    return obj.company == request.user.get_profile().company

Это сработает .Это не собирается просто скрыть кнопку;он полностью блокирует этот объект от редактирования.

Люди, написавшие django.contrib.admin, не писали его, предполагая, что кому-либо с is_staff = True можно доверять так же, как суперпользователю, или он был глупымдостаточно, чтобы никогда не взглянуть на исходный код веб-страницы.Хотя написание ваших собственных представлений приветствуется, это все же надежный интерфейс.

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

def change_view(self, request, object_id, extra_context=None):
    "The 'change' admin view for this model."
    model = self.model
    opts = model._meta

    obj = self.get_object(request, unquote(object_id))

    if not self.has_change_permission(request, obj):
        raise PermissionDenied

    # view continues...

Таким образом, даже если кто-то создаст правильный URL для редактирования данного объекта, при условии, что вы правильно внедрили has_change_permission, пользователь будетбыть лишенным доступа.

0 голосов
/ 04 апреля 2011

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

...