Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
re2o
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nounous
re2o
Commits
6478a0ae
Commit
6478a0ae
authored
Apr 20, 2018
by
Maël Kervella
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ACL permission on API
parent
510a0c9b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
107 additions
and
1 deletion
+107
-1
api/permissions.py
api/permissions.py
+106
-0
api/settings.py
api/settings.py
+1
-1
No files found.
api/permissions.py
0 → 100644
View file @
6478a0ae
from
rest_framework
import
permissions
from
re2o.acl
import
can_create
,
can_edit
,
can_delete
,
can_view_all
class
DefaultACLPermission
(
permissions
.
BasePermission
):
"""
Permission subclass in charge of checking the ACL to determine
if a user can access the models
"""
perms_map
=
{
'GET'
:
[
lambda
model
:
model
.
can_view_all
],
'OPTIONS'
:
[
lambda
model
:
model
.
can_view_all
],
'HEAD'
:
[
lambda
model
:
model
.
can_view_all
],
'POST'
:
[
lambda
model
:
model
.
can_create
],
#'PUT': [],
#'PATCH': [],
#'DELETE': [],
}
perms_obj_map
=
{
'GET'
:
[
lambda
obj
:
obj
.
can_view
],
'OPTIONS'
:
[
lambda
obj
:
obj
.
can_view
],
'HEAD'
:
[
lambda
obj
:
obj
.
can_view
],
#'POST': [],
'PUT'
:
[
lambda
obj
:
obj
.
can_edit
],
#'PATCH': [],
'DELETE'
:
[
lambda
obj
:
obj
.
can_delete
],
}
def
get_required_permissions
(
self
,
method
,
model
):
"""
Given a model and an HTTP method, return the list of acl
functions that the user is required to verify.
"""
if
method
not
in
self
.
perms_map
:
raise
exceptions
.
MethodNotAllowed
(
method
)
return
[
perm
(
model
)
for
perm
in
self
.
perms_map
[
method
]]
def
get_required_object_permissions
(
self
,
method
,
obj
):
"""
Given an object and an HTTP method, return the list of acl
functions that the user is required to verify.
"""
if
method
not
in
self
.
perms_map
:
raise
exceptions
.
MethodNotAllowed
(
method
)
return
[
perm
(
obj
)
for
perm
in
self
.
perms_map
[
method
]]
def
_queryset
(
self
,
view
):
"""
Return the queryset associated with view and raise an error
is there is none.
"""
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 ACLPermissions are not applied
# to the root view when using DefaultRouter.
if
getattr
(
view
,
'_ignore_model_permissions'
,
False
):
return
True
if
not
request
.
user
or
not
request
.
user
.
is_authenticated
:
return
False
queryset
=
self
.
_queryset
(
view
)
perms
=
self
.
get_required_permissions
(
request
.
method
,
queryset
.
model
)
return
all
(
perm
(
request
.
user
)[
0
]
for
perm
in
perms
)
def
has_object_permission
(
self
,
request
,
view
,
obj
):
# authentication checks have already executed via has_permission
queryset
=
self
.
_queryset
(
view
)
user
=
request
.
user
perms
=
self
.
get_required_object_permissions
(
request
.
method
,
obj
)
if
not
all
(
perm
(
request
.
user
)[
0
]
for
perm
in
perms
):
# If the user does not have permissions we need to determine if
# they have read permissions to see 403, or not, and simply see
# a 404 response.
if
request
.
method
in
SAFE_METHODS
:
# Read permissions already checked and failed, no need
# to make another lookup.
raise
Http404
read_perms
=
self
.
get_required_object_permissions
(
'GET'
,
obj
)
if
not
read_perms
(
request
.
user
)[
0
]:
raise
Http404
# Has read permissions.
return
False
return
True
api/settings.py
View file @
6478a0ae
...
...
@@ -32,6 +32,6 @@ REST_FRAMEWORK = {
'rest_framework.authentication.SessionAuthentication'
,
),
'DEFAULT_PERMISSION_CLASSES'
:
(
'
rest_framework.permissions.IsAuthenticated
'
,
'
api.permissions.DefaultACLPermission
'
,
)
}
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