#rest #design-patterns #django-rest-framework #architecture #django-permissions
#отдых #дизайн-шаблоны #django-rest-фреймворк #архитектура #django-разрешения
Вопрос:
В моем проекте у меня много представлений конечных точек (APIViews, ViewSets). Для всех из них теперь я устанавливаю разрешения, некоторые из них являются разрешениями по умолчанию (например, AllowAny), а некоторые созданы на заказ:
permission_classes = (IsUserHaveSomePermission,)
Теперь я хочу внедрить некоторую гибкую систему, которая позволит мне указать набор разрешенных конечных точек для каждого пользователя, например:
Во внешнем интерфейсе я хочу выбрать какого-либо пользователя и иметь список флажков, соответствующих конечным точкам проекта.
Это просто утопическое решение, некоторые детали могут быть изменены, но главный вопрос заключается в том, как сделать что-то подобное, чтобы администраторы могли динамически изменять список разрешенных конечных точек / представлений для пользователя? заранее спасибо
Ответ №1:
Это решение может быть реализовано путем сохранения, если у пользователя есть разрешение на доступ к текущему методу запроса и пути запроса.
Создайте новую модель базы данных для хранения пользователя, метода запроса и пути запроса. Допустим, имя модели — requestPermission
Вместо пути вы можете сохранить константу, представляющую URL-адрес, чтобы у вас была возможность редактировать путь позже. Эта константа может быть именем URL-адреса, которое поддерживается django.
class RequestPermission(models.Model):
user = user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='request_permissions')
method = models.CharField(max_length=10)
path_name = models.CharField(max_length=200)
создайте пользовательский класс разрешений:
class IsUserResuestAllowed(permissions.BasePermission):
def has_permission(self, request, view):
user = request.user
# you can choose how to get the path_name from the path
path_name = get_path_name(request.path)
return RequestPermission.objects.filter(user=user, method=request.method, path_name=path_name).exists()
Теперь вы можете использовать этот класс в качестве класса разрешений по умолчанию в настройках rest Framework или использовать его для каждого представления.
Комментарии:
1. Да, я рассматривал подобное решение, но здесь мне все еще нужно жестко закодировать все существующие имена путей и их http-методы. Я хотел бы, чтобы у меня была какая-нибудь функция
get_api_endpoints()
, которая возвращала бы какой-нибудь список, например[{url: 'api/v1/endpoint', name: 'url-path-name', methods: ['post', 'delete',...]}, ....]
, чтобы я мог легко отобразить их где-нибудь.2. Для тех, кому нужна такая функция, я частично взял ее из github.com/django-extensions/django-extensions/blob/master /… Примечание: все ваши URL-адреса должны иметь имена