Django-Guardian/Tastypie: переключение разрешений на уровне объектов от частного к общему

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

Например, у меня есть Event ресурс. Когда User создает Event, Event.creator установлен на User пример. Я использую аа post_save сигнал на Event дать разрешения на уровне объекта User кто создал его - делает его личным для создателя.

я хочу User чтобы иметь возможность переключать уровень разрешений для Event чтобы позволить всем пользователям иметь доступ к нему - то есть изменить событие с частного на общедоступное (и обратно).

Каков наилучший способ справиться с этим? Я хотел бы остаться с опекуном, если это возможно, но я не женат на этом. Вот несколько фрагментов кода, которые помогут проиллюстрировать это:

models.py

class UserProfile(models.Model):    
    user = models.OneToOneField(User, primary_key=True)
    events = models.ManyToManyField('myapp.Event', through="myapp.EventMembership", null=True, blank=True)

class Event(models.Model):
    name = models.CharField(max_length=64)
    creator = models.ForeignKey('myapp.UserProfile', related_name="creator")

resources.py

class EventResource(ModelResource):
    class Meta:
        queryset = Event.objects.all()
        resource_name = 'events'
        authentication = ApiKeyAuthentication()
        authorization = GuardianAuthorization(
            create_permission_code  = "myapp.add_event",
            view_permission_code    = "myapp.view_event",
            update_permission_code  = "myapp.change_event",
            delete_permission_code  = "myapp.delete_event"
        )
        always_return_data = True

    creator = fields.ForeignKey('myapp.UserProfile', 'creator', full=True)

    def hydrate(self, bundle, **kwargs):
        bundle.obj.creator = UserProfile.objects.get(user_id=bundle.request.user)
        return bundle

signals.py

@receiver(post_save, sender=User)
def allow_user_to_create_events(sender, instance, **kwargs):
    if not instance:
        return None

    if kwargs.get('created'):
        ApiKey.objects.create(user=instance)

    # give newly created user permissions to create events
    add_permission(instance, "myapp.add_event", Event)

@receiver(post_save, sender=Event)
def allow_user_to_edit_events(sender, instance, *args, **kwargs):
    if not instance or not isinstance(instance, Event):
        return None

    # assign_perm is a guardian shortcut
    assign_perm("myapp.view_event", instance.creator.user, instance)
    assign_perm("myapp.edit_event", instance.creator.user, instance)
    assign_perm("myapp.delete_event", instance.creator.user, instance)

Спасибо за ваше время и помощь!

Примечание: я использую авторизацию опекуна в моих вкусных ресурсах. Тем не менее, я думаю, что мой вопрос - скорее вопрос опекуна, а не столько о том, как его использовать с вкусным пирогом.

1 ответ

Я не знаю как guaridan-authorization работает. Но в вашем классе авторизации вы всегда можете найти и вернуть True если объект был установлен как публичный.

Другие вопросы по тегам