Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Backend
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Analyze
Contributor analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Arkindex
Backend
Commits
0f6c78a8
Commit
0f6c78a8
authored
4 years ago
by
Valentin Rigal
Browse files
Options
Downloads
Patches
Plain Diff
Handle public instances in the ACL mixin
parent
adbf5946
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
arkindex/project/mixins.py
+29
-18
29 additions, 18 deletions
arkindex/project/mixins.py
with
29 additions
and
18 deletions
arkindex/project/mixins.py
+
29
−
18
View file @
0f6c78a8
from
django.conf
import
settings
from
django.core.exceptions
import
PermissionDenied
from
django.db.models
import
Q
,
functions
from
django.db.models
import
IntegerField
,
Q
,
Value
,
functions
from
django.shortcuts
import
get_object_or_404
from
django.views.decorators.cache
import
cache_page
from
rest_framework.exceptions
import
APIException
,
ValidationError
...
...
@@ -28,43 +28,48 @@ class ACLMixin(object):
def
user
(
self
):
return
self
.
_user
or
self
.
request
.
user
def
get_public_instances
(
self
,
model
,
default_level
):
return
model
.
objects
\
.
filter
(
public
=
True
)
\
.
annotate
(
max_level
=
Value
(
default_level
,
IntegerField
()))
def
rights_filter
(
self
,
model
,
level
,
public
=
False
):
"""
Return a model queryset matching a given access level for this user
Return a model queryset matching a given access level for this user
.
"""
# Handle specific cases (i.e. admin or anonymous user)
if
self
.
user
.
is_admin
or
self
.
user
.
is_internal
:
return
model
.
objects
.
all
()
elif
user
.
is_anonymous
:
if
level
>
Role
.
Guest
.
value
or
not
public
:
return
model
.
objects
.
all
()
.
annotate
(
max_level
=
Value
(
Role
.
Admin
.
value
))
elif
self
.
user
.
is_anonymous
:
if
not
public
:
return
model
.
objects
.
none
()
else
:
return
model
.
objects
.
filter
(
public
=
Tr
ue
)
return
self
.
get_public_instances
(
model
,
Role
.
Guest
.
val
ue
)
# Filter users rights and annotate the resulting level for those rights
queryset
=
model
.
objects
\
.
filter
(
# Filter instances with
direct and groups rights for this user (They may b
e duplicate
d)
# Filter instances with
rights concerning this user. This may creat
e duplicate
s
Q
(
memberships__user
=
self
.
user
)
|
Q
(
memberships__group__memberships__user
=
self
.
user
)
)
\
.
annotate
(
# Keep only the lowest level for each right via group
max_level
=
functions
.
Least
(
# In case of direct right, group level will be skipped (Null value)
'
memberships__level
'
,
# In case of direct right, the group level will be skipped (Null value)
'
memberships__group__memberships__level
'
)
)
\
.
filter
(
# Ensure one of the right has an adequate level
max_level__gte
=
level
)
# Ensure one of the right has an adequate level
queryset
=
queryset
.
filter
(
max_level__gte
=
level
)
if
(
public
):
# Allow access to public instances if the public parameter is set
queryset
=
queryset
|
model
.
objects
.
filter
(
public
=
True
)
# Use a join to add public instances as this is the more elegant solution
if
public
and
level
<=
Role
.
Guest
.
value
:
queryset
=
queryset
.
union
(
self
.
get_public_instances
(
model
,
Role
.
Guest
.
value
)
)
return
queryset
.
distinct
()
# Return distinct corpus with the max right level among matching rights
return
queryset
.
order_by
(
'
id
'
,
'
-max_level
'
).
distinct
(
'
id
'
)
def
has_access
(
self
,
instance
,
level
):
if
self
.
user
.
is_admin
or
self
.
user
.
is_internal
:
...
...
@@ -86,11 +91,13 @@ class ACLMixin(object):
class
RepositoryACLMixin
(
ACLMixin
):
@property
def
readable_repositories
(
self
):
return
self
.
rights_filter
(
Repository
,
Role
.
Guest
.
value
,
public
=
False
)
return
self
.
rights_filter
(
Repository
,
Role
.
Guest
.
value
)
@property
def
executable_repositories
(
self
):
return
self
.
rights_filter
(
Repository
,
Role
.
Contributor
.
value
,
public
=
False
)
return
self
.
rights_filter
(
Repository
,
Role
.
Contributor
.
value
)
def
has_read_access
(
self
,
repo
):
return
self
.
has_access
(
repo
,
Role
.
Guest
.
value
)
...
...
@@ -103,12 +110,16 @@ class RepositoryACLMixin(ACLMixin):
class
NewCorpusACLMixin
(
ACLMixin
):
@property
def
readable_corpora
(
self
):
return
self
.
rights_filter
(
Corpus
,
Role
.
Guest
.
value
,
public
=
True
)
@property
def
writable_corpora
(
self
):
return
self
.
rights_filter
(
Corpus
,
Role
.
Contributor
.
value
)
@property
def
administrable_corpora
(
self
):
return
self
.
rights_filter
(
Corpus
,
Role
.
Admin
.
value
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment