Django REST Framework - Allow staff to access all endpointsDjango REST framework object level permissionsDjango REST framework: Check user is in groupHow to return data with 403 error in Django Rest Framework?Django REST Framework - Custom Permissions not EvaluatingPermission checks in DRF viewsets are not working rightDjango Rest Framework - best way to an endpoint?Check rest_framework permissions staticallyDjango Rest Framework - self.request.user in model methodDjango Rest Framework custom permission validationDjango Rest Framework: serializer response error
Bounded Torsion, without Mazur’s Theorem
"It is what it is" in French
What gave NASA the confidence for a translunar injection in Apollo 8?
My current job follows "worst practices". How can I talk about my experience in an interview without giving off red flags?
How can I print a 1 cm overhang with minimal supports?
Is there a way to shorten this while condition?
Are gangsters hired to attack people at a train station classified as a terrorist attack?
German phrase for 'suited and booted'
How can I deal with someone that wants to kill something that isn't supposed to be killed?
What rules turn any attack that hits a given target into a critical hit?
Why is the UH-60 tail rotor canted?
Can I pay with HKD in Macau or Shenzhen?
Adding gears to my grandson's 12" bike
What kind of anatomy does a centaur have?
How to work a regular job as a former celebrity
Has Peter Parker ever eaten bugs?
How can I calculate the cost of Skyss bus tickets
How to Sow[] until I've Reap[]'d enough?
Why is DC so, so, so Democratic?
ExactlyOne extension method
Does quantity of data extensions impact performance?
Monty Hall Problem with a Fallible Monty
What was the rationale behind 36 bit computer architectures?
Why can't a country print its own money to spend it only abroad?
Django REST Framework - Allow staff to access all endpoints
Django REST framework object level permissionsDjango REST framework: Check user is in groupHow to return data with 403 error in Django Rest Framework?Django REST Framework - Custom Permissions not EvaluatingPermission checks in DRF viewsets are not working rightDjango Rest Framework - best way to an endpoint?Check rest_framework permissions staticallyDjango Rest Framework - self.request.user in model methodDjango Rest Framework custom permission validationDjango Rest Framework: serializer response error
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I'm building a DRF API, and I would like to allow staff members (is_staff == True
) to access all of the REST endpoints, while still providing custom permission checking per ViewSet. Ideally, this would be a global setting, but I'm not against setting it up per ViewSet.
Here are the things I've tried:
Option 1: Check on every custom permission
from rest_framework import permissions
class SomeModelPermission(permissions.BasePermission):
def has_permission(self, request, view):
if request.user.is_staff:
return True
# other logic
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
# other logic
This works, but I'd rather not repeat so much code.
Option 2: Bitwise operators
I tried removing the is_staff
logic from the custom permission above, and adding this to the ViewSet:
from rest_framework import permissions, viewsets
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAdminUser|SomeModelPermission,)
However, this actually does not enforce permissions as I'd like, because IsAdminUser
inherits from BasePermission
, which is defined as:
class BasePermission(object):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return True
IsAdminUser
doesn't define its own has_object_permission
, so it will always return True
when checking object permissions, resulting in unintended object access.
Any ideas? I was hoping there would be some way I could set a global permissions check that would return True
when the user is a staff member, and defer to the custom permissions otherwise. But reading through how permissions are determined, I'm not sure that this is possible.
python django permissions django-rest-framework
add a comment |
I'm building a DRF API, and I would like to allow staff members (is_staff == True
) to access all of the REST endpoints, while still providing custom permission checking per ViewSet. Ideally, this would be a global setting, but I'm not against setting it up per ViewSet.
Here are the things I've tried:
Option 1: Check on every custom permission
from rest_framework import permissions
class SomeModelPermission(permissions.BasePermission):
def has_permission(self, request, view):
if request.user.is_staff:
return True
# other logic
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
# other logic
This works, but I'd rather not repeat so much code.
Option 2: Bitwise operators
I tried removing the is_staff
logic from the custom permission above, and adding this to the ViewSet:
from rest_framework import permissions, viewsets
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAdminUser|SomeModelPermission,)
However, this actually does not enforce permissions as I'd like, because IsAdminUser
inherits from BasePermission
, which is defined as:
class BasePermission(object):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return True
IsAdminUser
doesn't define its own has_object_permission
, so it will always return True
when checking object permissions, resulting in unintended object access.
Any ideas? I was hoping there would be some way I could set a global permissions check that would return True
when the user is a staff member, and defer to the custom permissions otherwise. But reading through how permissions are determined, I'm not sure that this is possible.
python django permissions django-rest-framework
add a comment |
I'm building a DRF API, and I would like to allow staff members (is_staff == True
) to access all of the REST endpoints, while still providing custom permission checking per ViewSet. Ideally, this would be a global setting, but I'm not against setting it up per ViewSet.
Here are the things I've tried:
Option 1: Check on every custom permission
from rest_framework import permissions
class SomeModelPermission(permissions.BasePermission):
def has_permission(self, request, view):
if request.user.is_staff:
return True
# other logic
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
# other logic
This works, but I'd rather not repeat so much code.
Option 2: Bitwise operators
I tried removing the is_staff
logic from the custom permission above, and adding this to the ViewSet:
from rest_framework import permissions, viewsets
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAdminUser|SomeModelPermission,)
However, this actually does not enforce permissions as I'd like, because IsAdminUser
inherits from BasePermission
, which is defined as:
class BasePermission(object):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return True
IsAdminUser
doesn't define its own has_object_permission
, so it will always return True
when checking object permissions, resulting in unintended object access.
Any ideas? I was hoping there would be some way I could set a global permissions check that would return True
when the user is a staff member, and defer to the custom permissions otherwise. But reading through how permissions are determined, I'm not sure that this is possible.
python django permissions django-rest-framework
I'm building a DRF API, and I would like to allow staff members (is_staff == True
) to access all of the REST endpoints, while still providing custom permission checking per ViewSet. Ideally, this would be a global setting, but I'm not against setting it up per ViewSet.
Here are the things I've tried:
Option 1: Check on every custom permission
from rest_framework import permissions
class SomeModelPermission(permissions.BasePermission):
def has_permission(self, request, view):
if request.user.is_staff:
return True
# other logic
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
# other logic
This works, but I'd rather not repeat so much code.
Option 2: Bitwise operators
I tried removing the is_staff
logic from the custom permission above, and adding this to the ViewSet:
from rest_framework import permissions, viewsets
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAdminUser|SomeModelPermission,)
However, this actually does not enforce permissions as I'd like, because IsAdminUser
inherits from BasePermission
, which is defined as:
class BasePermission(object):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return True
IsAdminUser
doesn't define its own has_object_permission
, so it will always return True
when checking object permissions, resulting in unintended object access.
Any ideas? I was hoping there would be some way I could set a global permissions check that would return True
when the user is a staff member, and defer to the custom permissions otherwise. But reading through how permissions are determined, I'm not sure that this is possible.
python django permissions django-rest-framework
python django permissions django-rest-framework
asked Mar 26 at 14:37
Michael HaysMichael Hays
1,0592 gold badges9 silver badges14 bronze badges
1,0592 gold badges9 silver badges14 bronze badges
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Bitwise solution:
How about creating your own IsAdminUser
which also defines has_object_permission
? You could just inherit from the existing one:
from rest_framework.permissions import IsAdminUser as BaseIsAdminUser
class IsAdminUser(BaseIsAdminUser):
def has_object_permission(self, request, view, obj):
# Just reuse the same logic as `has_permission`...
return self.has_permission(request, view)
Then you can do what you attempted above, with the bitwise operator:
from rest_framework import permissions, viewsets
from your_own_project.permissions import IsAdminUser
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (IsAdminUser|SomeModelPermission,)
Another solution:
A bit "hacky" in some ways, but you could try to create your own permission types on the fly.
So the end result would look something like:
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = skip_for_staff((SomeModelPermission, SomeOtherPermission, ...))
With the implementation something similar to:
class StaffAllowedMixin:
def has_permission(self, request, view):
if request.user.is_staff:
return True
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return super().has_object_permission(request, view, obj)
def skip_for_staff(permission_classes):
# You can probably also use a comprehension here, but for clarity:
staff_allowed_classes = []
for permission_class in permissions(
staff_allowed_classes.append(
# Create a new type (class) with name StaffAllowed<...>
type(f"StaffAllowedpermission_class",
# Inherit from the mixin above, and from the original class
(StaffAllowedMixin, permission_class),
# empty dictionary means you don't want to override any attributes
)
)
return tuple(staff_allowed_classes)
Essentially, for each permission class, you create a new class with the extra mixin that takes precedence and checks if the user is staff.
But you do that on the fly, where your permissions are used, instead of having to predefine it for every permission.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55359806%2fdjango-rest-framework-allow-staff-to-access-all-endpoints%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Bitwise solution:
How about creating your own IsAdminUser
which also defines has_object_permission
? You could just inherit from the existing one:
from rest_framework.permissions import IsAdminUser as BaseIsAdminUser
class IsAdminUser(BaseIsAdminUser):
def has_object_permission(self, request, view, obj):
# Just reuse the same logic as `has_permission`...
return self.has_permission(request, view)
Then you can do what you attempted above, with the bitwise operator:
from rest_framework import permissions, viewsets
from your_own_project.permissions import IsAdminUser
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (IsAdminUser|SomeModelPermission,)
Another solution:
A bit "hacky" in some ways, but you could try to create your own permission types on the fly.
So the end result would look something like:
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = skip_for_staff((SomeModelPermission, SomeOtherPermission, ...))
With the implementation something similar to:
class StaffAllowedMixin:
def has_permission(self, request, view):
if request.user.is_staff:
return True
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return super().has_object_permission(request, view, obj)
def skip_for_staff(permission_classes):
# You can probably also use a comprehension here, but for clarity:
staff_allowed_classes = []
for permission_class in permissions(
staff_allowed_classes.append(
# Create a new type (class) with name StaffAllowed<...>
type(f"StaffAllowedpermission_class",
# Inherit from the mixin above, and from the original class
(StaffAllowedMixin, permission_class),
# empty dictionary means you don't want to override any attributes
)
)
return tuple(staff_allowed_classes)
Essentially, for each permission class, you create a new class with the extra mixin that takes precedence and checks if the user is staff.
But you do that on the fly, where your permissions are used, instead of having to predefine it for every permission.
add a comment |
Bitwise solution:
How about creating your own IsAdminUser
which also defines has_object_permission
? You could just inherit from the existing one:
from rest_framework.permissions import IsAdminUser as BaseIsAdminUser
class IsAdminUser(BaseIsAdminUser):
def has_object_permission(self, request, view, obj):
# Just reuse the same logic as `has_permission`...
return self.has_permission(request, view)
Then you can do what you attempted above, with the bitwise operator:
from rest_framework import permissions, viewsets
from your_own_project.permissions import IsAdminUser
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (IsAdminUser|SomeModelPermission,)
Another solution:
A bit "hacky" in some ways, but you could try to create your own permission types on the fly.
So the end result would look something like:
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = skip_for_staff((SomeModelPermission, SomeOtherPermission, ...))
With the implementation something similar to:
class StaffAllowedMixin:
def has_permission(self, request, view):
if request.user.is_staff:
return True
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return super().has_object_permission(request, view, obj)
def skip_for_staff(permission_classes):
# You can probably also use a comprehension here, but for clarity:
staff_allowed_classes = []
for permission_class in permissions(
staff_allowed_classes.append(
# Create a new type (class) with name StaffAllowed<...>
type(f"StaffAllowedpermission_class",
# Inherit from the mixin above, and from the original class
(StaffAllowedMixin, permission_class),
# empty dictionary means you don't want to override any attributes
)
)
return tuple(staff_allowed_classes)
Essentially, for each permission class, you create a new class with the extra mixin that takes precedence and checks if the user is staff.
But you do that on the fly, where your permissions are used, instead of having to predefine it for every permission.
add a comment |
Bitwise solution:
How about creating your own IsAdminUser
which also defines has_object_permission
? You could just inherit from the existing one:
from rest_framework.permissions import IsAdminUser as BaseIsAdminUser
class IsAdminUser(BaseIsAdminUser):
def has_object_permission(self, request, view, obj):
# Just reuse the same logic as `has_permission`...
return self.has_permission(request, view)
Then you can do what you attempted above, with the bitwise operator:
from rest_framework import permissions, viewsets
from your_own_project.permissions import IsAdminUser
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (IsAdminUser|SomeModelPermission,)
Another solution:
A bit "hacky" in some ways, but you could try to create your own permission types on the fly.
So the end result would look something like:
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = skip_for_staff((SomeModelPermission, SomeOtherPermission, ...))
With the implementation something similar to:
class StaffAllowedMixin:
def has_permission(self, request, view):
if request.user.is_staff:
return True
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return super().has_object_permission(request, view, obj)
def skip_for_staff(permission_classes):
# You can probably also use a comprehension here, but for clarity:
staff_allowed_classes = []
for permission_class in permissions(
staff_allowed_classes.append(
# Create a new type (class) with name StaffAllowed<...>
type(f"StaffAllowedpermission_class",
# Inherit from the mixin above, and from the original class
(StaffAllowedMixin, permission_class),
# empty dictionary means you don't want to override any attributes
)
)
return tuple(staff_allowed_classes)
Essentially, for each permission class, you create a new class with the extra mixin that takes precedence and checks if the user is staff.
But you do that on the fly, where your permissions are used, instead of having to predefine it for every permission.
Bitwise solution:
How about creating your own IsAdminUser
which also defines has_object_permission
? You could just inherit from the existing one:
from rest_framework.permissions import IsAdminUser as BaseIsAdminUser
class IsAdminUser(BaseIsAdminUser):
def has_object_permission(self, request, view, obj):
# Just reuse the same logic as `has_permission`...
return self.has_permission(request, view)
Then you can do what you attempted above, with the bitwise operator:
from rest_framework import permissions, viewsets
from your_own_project.permissions import IsAdminUser
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = (IsAdminUser|SomeModelPermission,)
Another solution:
A bit "hacky" in some ways, but you could try to create your own permission types on the fly.
So the end result would look something like:
class SomeModelViewSet(viewsets.ModelViewSet):
permission_classes = skip_for_staff((SomeModelPermission, SomeOtherPermission, ...))
With the implementation something similar to:
class StaffAllowedMixin:
def has_permission(self, request, view):
if request.user.is_staff:
return True
return super().has_permission(request, view)
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return super().has_object_permission(request, view, obj)
def skip_for_staff(permission_classes):
# You can probably also use a comprehension here, but for clarity:
staff_allowed_classes = []
for permission_class in permissions(
staff_allowed_classes.append(
# Create a new type (class) with name StaffAllowed<...>
type(f"StaffAllowedpermission_class",
# Inherit from the mixin above, and from the original class
(StaffAllowedMixin, permission_class),
# empty dictionary means you don't want to override any attributes
)
)
return tuple(staff_allowed_classes)
Essentially, for each permission class, you create a new class with the extra mixin that takes precedence and checks if the user is staff.
But you do that on the fly, where your permissions are used, instead of having to predefine it for every permission.
edited Mar 26 at 15:17
answered Mar 26 at 14:59
GeekfishGeekfish
1,35918 silver badges27 bronze badges
1,35918 silver badges27 bronze badges
add a comment |
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55359806%2fdjango-rest-framework-allow-staff-to-access-all-endpoints%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown