Я создаю простой API, используя django-tastypie.Идея в том, что у меня есть два ресурса:
- A Примечание ресурс, представляющий заметку, оставленную пользователем.Только пользователь, создавший заметку, может редактировать ее.
- A Комментарий ресурс.Комментарии могут быть оставлены в любой заметке любым пользователем.
TL; DR: Я не могу ограничить редактирование заметки для создателя заметки, в то же время позволяя любому пользователю комментироватьПримечание.
Я использую следующую настройку для аутентификации:
class CreatedByEditAuthorization(Authorization):
def is_authorized(self, request, object=None, **kwargs):
return True
def apply_limits(self, request, object_list):
if request and request.method != 'GET' and hasattr(request, 'user'):
return object_list.filter(created_by=request.user)
return object_list
Короче говоря, пользователь имеет право редактировать только те объекты, для которых он равен свойству созданного_байя (они могут толькоотредактируйте созданные ими объекты).
Это связано следующим образом:
class NoteResource(ModelResource):
comments = fields.ToManyField('myapp.api.resources.CommentResource', 'comments', null=True, blank=True)
created_by = fields.ToOneField('account.api.resources.UserResource', 'created_by')
def obj_create(self, bundle, request, **kwargs):
return super(HapResource, self).obj_create(bundle, request, created_by=request.user)
class Meta:
queryset = Note.objects.all()
allowed_methods = ['get', 'put', 'post']
authorization = CreatedByEditAuthorization()
, поэтому здесь, когда объект создается, я автоматически присоединяю текущего пользователя к атрибуту created_by
исвяжите его с соответствующей авторизацией.
Ресурс Comment
прост и имеет только ForeignKey
для Note
ресурса.
Проблема заключается в следующем: если пользователь A создает заметку, а пользователь B пытается прокомментировать эту заметку, tastypie отправляет (или имитирует) запрос POST для редактирования этой заметки.Эта попытка отклонена, поскольку пользователь B не создал заметку, поэтому создание комментария завершается неудачей.
Вопрос заключается в следующем: Есть ли способ:
- Запретить использование вкусного пирога POST для создания обратной связи с ресурсом заметки или
- Измените схему авторизации, чтобы заметки могли редактировать только их создатели, но комментарии могли создаватьсявообще?
Заранее спасибо за любые идеи.
Редактировать: У меня есть большой жирный хак, который может это сделать.Я уверен, что это безопасно, но я не уверен;Я постараюсь составить несколько запросов, чтобы убедиться.Вместо использования fields.ForeignKey
в Comment
для связи с Note
я создаю настраиваемое поле:
class SafeForeignKey(fields.ForeignKey):
def build_related_resource(self, value, request=None, related_obj=None, related_name=None):
temp = request.method
if isinstance(value, basestring):
request.method = 'GET'
ret = super(SafeForeignKey, self).build_related_resource(value, request, related_obj, related_name)
request.method = temp
return ret
Каждый раз, когда мы пытаемся создать этот связанный ресурс, мы помечаем запрос как GET
(поскольку мы ожидаем, что он будет соответствовать запросу SELECT
, а не UPDATE
, который соответствует PUT
или POST
).Это действительно некрасиво и потенциально небезопасно, если используется неправильно, и я надеюсь на лучшее решение.
Редактировать 2: Насколько я могу судить, прочитав источник вкусного пирога,нет способа отфильтровать авторизацию по запросу, который действительно будет отправлен.