Skip to content

Commit

Permalink
Add majora2.can_suppress_any_pags_via_api permission
Browse files Browse the repository at this point in the history
Allow users granted majora2.can_suppress_any_pags_via_api to suppress
any PAG regardless of the institute ownership

* Add can_suppress_any_pags_via_api to models
* Alter description of can_suppress_pags_via_api to clarify intent
* staff org and user added to test_basic_api
* test class _get_token now supports selecting a user
* test_suppress_else_pag_as_admin test added to test_pag
  • Loading branch information
SamStudio8 committed Jan 5, 2022
1 parent b5db9d7 commit 916c5d4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
3 changes: 2 additions & 1 deletion majora2/api_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1750,7 +1750,8 @@ def f(request, api_o, json_data, user=None, partial=False):
api_o["messages"].append("%s already suppressed" % pag_name)
continue

if pag.owner.profile.institute != user.profile.institute:
# User cannot suppress this PAG if they do not own it without the special "can_suppress_any" permission
if pag.owner.profile.institute != user.profile.institute and not user.has_perm("majora2.can_suppress_any_pags_via_api"):
api_o["ignored"].append(pag_name)
api_o["errors"] += 1
api_o["messages"].append("Your organisation (%s) does not own %s (%s)" % (user.profile.institute.code, pag_name, pag.owner.profile.institute.code))
Expand Down
3 changes: 2 additions & 1 deletion majora2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,8 @@ class Meta:
]
permissions = [
("temp_can_read_pags_via_api", "Can read published artifact groups via the API"),
("can_suppress_pags_via_api", "Can suppress any published artifact group via the API"),
("can_suppress_pags_via_api", "Can suppress their own published artifact group via the API"),
("can_suppress_any_pags_via_api", "Can suppress any published artifact group via the API"),
]
def as_struct(self):
if self.is_suppressed:
Expand Down
19 changes: 17 additions & 2 deletions majora2/test/test_basic_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def setUp(self):
not_hoot = models.Institute(code="HOOO", name="Hooting Office of Ornithology")
not_hoot.save()

staff_hoot = models.Institute(code="HOOS", name="Hooting Office of Statistics")
staff_hoot.save()

# Create a fully approved profile user
user = User.objects.create(username='api_user', email='api@example.org')
user.set_password('password')
Expand All @@ -44,8 +47,17 @@ def setUp(self):
profile = models.Profile(user=not_user, institute=not_hoot, is_site_approved=True)
profile.save()

staff_user = User.objects.create(username='staff_api_user', email='api@example.org')
staff_user.set_password('password')
staff_user.is_active = True # sysadmins mark this field
staff_user.is_staff = True
staff_user.save()
profile = models.Profile(user=staff_user, institute=staff_hoot, is_site_approved=True)
profile.save()

self.user = user
self.not_user = not_user
self.staff_user = staff_user

# Create an API key def
kd = models.ProfileAPIKeyDefinition(
Expand Down Expand Up @@ -179,10 +191,13 @@ def setUp(self):
for scope_group, scope_str in self.scope_strs.items():
self.tokens[scope_group] = self._get_token(scope_str)

def _get_token(self, scope_str):
def _get_token(self, scope_str, user=None):
if user is None:
user = self.user

AccessToken = get_access_token_model()
token = AccessToken.objects.create(
user=self.user,
user=user,
token=str(uuid.uuid4()),
application=self.application,
expires=timezone.now() + datetime.timedelta(days=1),
Expand Down
34 changes: 34 additions & 0 deletions majora2/test/test_pag.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ def setUp(self):
self.user.user_permissions.add(fp)
self.user.save()

fp = Permission.objects.get(codename="can_suppress_any_pags_via_api")
self.staff_user.user_permissions.add(fp)
self.staff_user.save()

def test_suppress_ok(self):
payload = {
"username": self.user.username,
Expand Down Expand Up @@ -129,3 +133,33 @@ def test_suppress_else_pag(self):
j = response.json()
self.assertEqual(j["errors"], 1)
self.assertIn("does not own", "".join(j["messages"]))

def test_suppress_else_pag_as_admin(self):
staff_token = self._get_token(self.scope, user=self.staff_user)

pag = models.PublishedArtifactGroup(
published_name="HOOO/HOOO-BESAM5/HOOO:HOOHOO",
published_version=1,
is_latest=True,
owner=self.user,
)
pag.save()

payload = {
"username": self.staff_user.username,
"token": "oauth",
"publish_group": "HOOO/HOOO-BESAM5/HOOO:HOOHOO",
"reason": "WRONG_SEQUENCE",
}
response = self.c.post(self.endpoint, payload, secure=True, content_type="application/json", HTTP_AUTHORIZATION="Bearer %s" % staff_token)
self.assertEqual(200, response.status_code)

j = response.json()
self.assertEqual(j["errors"], 0)

pag = models.PublishedArtifactGroup.objects.get(published_name="HOOO/HOOO-BESAM5/HOOO:HOOHOO")
assert pag is not None
assert pag.is_suppressed is True
assert pag.suppressed_reason == "WRONG_SEQUENCE"
assert pag.suppressed_date.date() == datetime.date.today()

0 comments on commit 916c5d4

Please sign in to comment.