Last active
August 29, 2015 14:27
-
-
Save g-cassie/001e126838d3f1db0a6f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this uses the models setout in this gist: https://gist.github.com/g-cassie/6b9b0f29371677f48659 | |
from projects.models import Project, User, UserProjectAccess | |
class UserProjectChildProfile(permissions.Profile): | |
# ProjectChild refers to any model that has a ForeignKey to Project | |
def __init__(self, request): | |
self.user = request.user | |
def get_queryset_filters(self, request, queryset): | |
# allows you to return Q objects to filter down a queryset | |
# this is how you can control what objects a user can see | |
# we don't modify queryset directly because there may be multiple | |
# permission profiles that the user falls into | |
# e.g. if a user is an admin for their organization they can see all their orgs stuff | |
# they might also be able to see projects in another organization that they were invited to | |
return queryset.filter(project__users=self.user) | |
def can_create(self, serializer): | |
# a final permissions check once a serializer has been validated | |
# allows you to prevent users from creating objects with specific attributes | |
# e.g. cannot create an object in a project they do not have access to | |
try: | |
a = UserProjectAccess.objects.get(project=serializer.validated_data['project'], user=self.user) | |
except UserProjectAccess.DoesNotExist: | |
return False | |
return a.role in [UserProjectAccess.EDITOR, UserProjectAccess.ADMIN] | |
def can_edit(self, serializer, obj): | |
# same idea as can_create | |
# we get the actual obj being modified as well as the serializer about to be saved | |
# e.g. user cannot move an object into a project they do not belong to | |
try: | |
a = UserProjectAccess.objects.get(project=serializer.validated_data['project'], user=self.user) | |
except UserProjectAccess.DoesNotExist: | |
return False | |
return a.role in [UserProjectAccess.EDITOR, UserProjectAccess.ADMIN] | |
## another example, user cannot set is_trashed=True if they are not an admin | |
if obj.is_trashed == False and serializer.validated_data['is_trashed'] == True: | |
return a.role == UserProjectAccess.ADMIN | |
def can_delete(self, obj): | |
# similar idea to can_create but we get the actual | |
# e.g. user can only delete objects they created | |
return obj.creator == self.user | |
class AdminProjectChildProfile(permissions.Profile): | |
def get_queryset_filters(self, request): | |
return Q(project__organizations=user.organization) | |
def can_delete(self, obj): | |
# admins can always delete | |
# if multiple profiles are available, you just need one profile to return True on a "can_" function | |
# and the request will be permitted. | |
# i.e. admins can always delete even if UserProjectChildProfile.can_delete returns False | |
return True | |
class ProjectChildViewSet(viewsets.ModelViewSet): | |
permission_profiles = [AdminProjectChildProfile, UserProjectChildProfile] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment