Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
23b2d809
Commit
23b2d809
authored
Sep 01, 2017
by
Ryan P Kilby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Unify QS handling for model/object permissions
parent
af460d2b
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
40 additions
and
24 deletions
+40
-24
rest_framework/permissions.py
+18
-23
tests/test_permissions.py
+22
-1
No files found.
rest_framework/permissions.py
View file @
23b2d809
...
...
@@ -114,6 +114,21 @@ class DjangoModelPermissions(BasePermission):
return
[
perm
%
kwargs
for
perm
in
self
.
perms_map
[
method
]]
def
_queryset
(
self
,
view
):
assert
hasattr
(
view
,
'get_queryset'
)
\
or
getattr
(
view
,
'queryset'
,
None
)
is
not
None
,
(
'Cannot apply {} on a view that does not set '
'`.queryset` or have a `.get_queryset()` method.'
)
.
format
(
self
.
__class__
.
__name__
)
if
hasattr
(
view
,
'get_queryset'
):
queryset
=
view
.
get_queryset
()
assert
queryset
is
not
None
,
(
'{}.get_queryset() returned None'
.
format
(
view
.
__class__
.
__name__
)
)
return
queryset
return
view
.
queryset
def
has_permission
(
self
,
request
,
view
):
# Workaround to ensure DjangoModelPermissions are not applied
# to the root view when using DefaultRouter.
...
...
@@ -124,19 +139,7 @@ class DjangoModelPermissions(BasePermission):
not
is_authenticated
(
request
.
user
)
and
self
.
authenticated_users_only
):
return
False
if
hasattr
(
view
,
'get_queryset'
):
queryset
=
view
.
get_queryset
()
assert
queryset
is
not
None
,
(
'{}.get_queryset() returned None'
.
format
(
view
.
__class__
.
__name__
)
)
else
:
queryset
=
getattr
(
view
,
'queryset'
,
None
)
assert
queryset
is
not
None
,
(
'Cannot apply DjangoModelPermissions on a view that '
'does not set `.queryset` or have a `.get_queryset()` method.'
)
queryset
=
self
.
_queryset
(
view
)
perms
=
self
.
get_required_permissions
(
request
.
method
,
queryset
.
model
)
return
request
.
user
.
has_perms
(
perms
)
...
...
@@ -183,16 +186,8 @@ class DjangoObjectPermissions(DjangoModelPermissions):
return
[
perm
%
kwargs
for
perm
in
self
.
perms_map
[
method
]]
def
has_object_permission
(
self
,
request
,
view
,
obj
):
if
hasattr
(
view
,
'get_queryset'
):
queryset
=
view
.
get_queryset
()
else
:
queryset
=
getattr
(
view
,
'queryset'
,
None
)
assert
queryset
is
not
None
,
(
'Cannot apply DjangoObjectPermissions on a view that '
'does not set `.queryset` or have a `.get_queryset()` method.'
)
# authentication checks have already executed via has_permission
queryset
=
self
.
_queryset
(
view
)
model_cls
=
queryset
.
model
user
=
request
.
user
...
...
tests/test_permissions.py
View file @
23b2d809
...
...
@@ -9,7 +9,7 @@ from django.test import TestCase
from
rest_framework
import
(
HTTP_HEADER_ENCODING
,
authentication
,
generics
,
permissions
,
serializers
,
status
status
,
views
)
from
rest_framework.compat
import
ResolverMatch
,
guardian
,
set_many
from
rest_framework.filters
import
DjangoObjectPermissionsFilter
...
...
@@ -219,6 +219,27 @@ class ModelPermissionsIntegrationTests(TestCase):
response
=
view
(
request
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_401_UNAUTHORIZED
)
def
test_queryset_assertions
(
self
):
class
View
(
views
.
APIView
):
authentication_classes
=
[
authentication
.
BasicAuthentication
]
permission_classes
=
[
permissions
.
DjangoModelPermissions
]
view
=
View
.
as_view
()
request
=
factory
.
get
(
'/'
,
HTTP_AUTHORIZATION
=
self
.
permitted_credentials
)
msg
=
'Cannot apply DjangoModelPermissions on a view that does not set `.queryset` or have a `.get_queryset()` method.'
with
self
.
assertRaisesMessage
(
AssertionError
,
msg
):
view
(
request
)
# Faulty `get_queryset()` methods should trigger the above "view does not have a queryset" assertion.
class
View
(
RootView
):
def
get_queryset
(
self
):
return
None
view
=
View
.
as_view
()
request
=
factory
.
get
(
'/'
,
HTTP_AUTHORIZATION
=
self
.
permitted_credentials
)
with
self
.
assertRaisesMessage
(
AssertionError
,
'View.get_queryset() returned None'
):
view
(
request
)
class
BasicPermModel
(
models
.
Model
):
text
=
models
.
CharField
(
max_length
=
100
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment