Skip to content

Commit 46f9899

Browse files
committed
fix is_approved/public auth for projects
1 parent f2a6106 commit 46f9899

2 files changed

Lines changed: 39 additions & 26 deletions

File tree

mpcontribs-api/mpcontribs/api/core.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -475,18 +475,12 @@ def is_external(self, request):
475475
"X-Forwarded-Host"
476476
) is not None and not request.headers.get("Origin")
477477

478-
def is_admin(self, groups):
478+
def is_admin(self, request):
479+
groups = self.get_groups(request)
479480
admin_group = os.environ.get("ADMIN_GROUP", "admin")
480481
return admin_group in groups
481482

482-
def is_admin_or_project_user(self, request, obj):
483-
if self.is_anonymous(request):
484-
return False
485-
486-
groups = self.get_groups(request)
487-
if self.is_admin(groups):
488-
return True
489-
483+
def is_project_user(self, request, obj):
490484
if hasattr(obj, "owner"):
491485
owner = obj.owner
492486
project = obj.name
@@ -496,9 +490,19 @@ def is_admin_or_project_user(self, request, obj):
496490
else:
497491
raise Unauthorized(f"Unable to authorize {obj}")
498492

493+
groups = self.get_groups(request)
499494
username = request.headers.get("X-Consumer-Username")
500495
return project in groups or owner == username
501496

497+
def is_admin_or_project_user(self, request, obj):
498+
if self.is_anonymous(request):
499+
return False
500+
501+
if self.is_admin(request):
502+
return True
503+
504+
return self.is_project_user(request, obj)
505+
502506
def get_projects(self):
503507
# project is LazyReferenceFields (multiple queries)
504508
module = import_module("mpcontribs.api.projects.document")
@@ -530,10 +534,10 @@ def get_projects_filter(self, username, groups, filter_names=None):
530534
return qfilter
531535

532536
def has_read_permission(self, request, qs):
533-
groups = self.get_groups(request)
534-
if self.is_admin(groups):
537+
if self.is_admin(request):
535538
return qs # admins can read all entries
536539

540+
groups = self.get_groups(request)
537541
is_anonymous = self.is_anonymous(request)
538542
is_external = self.is_external(request)
539543
username = request.headers.get("X-Consumer-Username")

mpcontribs-api/mpcontribs/api/projects/views.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,34 +87,43 @@ class ProjectsView(SwaggerView):
8787
resource = ProjectsResource
8888
methods = [Fetch, Create, Delete, Update, BulkFetch]
8989

90-
def has_add_permission(self, req, obj):
91-
if self.is_anonymous(req):
90+
def has_add_permission(self, request, obj):
91+
if self.is_anonymous(request):
9292
return False
9393

94-
obj.owner = req.headers.get("X-Consumer-Username")
95-
groups = self.get_groups(req)
96-
is_admin = self.is_admin(groups)
97-
if is_admin:
94+
obj.owner = request.headers.get("X-Consumer-Username")
95+
if self.is_admin(request):
9896
return True
9997

100-
# is_approved can only be set by an admin
101-
if obj.is_approved:
102-
raise Unauthorized("Only admins can set `is_approved=True`")
98+
data = request.json
99+
if "is_approved" in data or "is_public" in data:
100+
raise Unauthorized("Projects cannot be approved or published on creation.")
103101

104-
# limit the number of projects a user can own (unless admin)
102+
# limit the number of projects a user can own
105103
nr_projects = Projects.objects(owner=obj.owner).count()
106104
if nr_projects > MAX_PROJECTS:
107105
raise Unauthorized(f"{obj.owner} already owns {nr_projects} projects.")
108106

109107
return True
110108

111-
def has_change_permission(self, req, obj):
112-
if not self.is_admin_or_project_user(req, obj):
109+
def has_change_permission(self, request, obj):
110+
if self.is_anonymous(request):
113111
return False
114112

115-
# is_public can only be changed if project is_approved
116-
if obj.is_public and not obj.is_approved:
117-
raise Unauthorized(f"{obj.id} is not approved yet.")
113+
if self.is_admin(request):
114+
return True
115+
116+
if not self.is_project_user(request, obj):
117+
raise Unauthorized(
118+
"Only project owners and collaborators can edit projects."
119+
)
120+
121+
update = request.json
122+
if "is_approved" in update:
123+
raise Unauthorized("Only admins can (un)approve projects.")
124+
125+
if "is_public" in update and not obj.is_approved:
126+
raise Unauthorized("Projects can only be published after admin approval.")
118127

119128
return True
120129

0 commit comments

Comments
 (0)