Skip to content

Commit 3ef338e

Browse files
committed
deposits: update 'permissions' action methods
* refactors the code so that when an action is not possible, it fails silently, and the flow doesn't stop * closes #2023 Signed-off-by: Ilias Koutsakis <[email protected]>
1 parent 0468747 commit 3ef338e

File tree

2 files changed

+132
-86
lines changed

2 files changed

+132
-86
lines changed

cap/modules/deposit/api.py

+73-72
Original file line numberDiff line numberDiff line change
@@ -431,55 +431,36 @@ def edit_permissions(self, data):
431431
}]
432432
433433
"""
434-
with db.session.begin_nested():
435-
for obj in data:
436-
if obj['type'] == 'user':
437-
try:
438-
user = get_existing_or_register_user(obj['email'])
439-
except DoesNotExistInLDAP:
440-
raise UpdateDepositPermissionsError(
441-
'User with this mail does not exist in LDAP.')
442-
443-
if obj['op'] == 'add':
444-
try:
445-
self._add_user_permissions(user, [obj['action']],
446-
db.session)
447-
except IntegrityError:
448-
raise UpdateDepositPermissionsError(
449-
'Permission already exist.')
450-
451-
elif obj['op'] == 'remove':
452-
try:
453-
self._remove_user_permissions(
454-
user, [obj['action']], db.session)
455-
except NoResultFound:
456-
raise UpdateDepositPermissionsError(
457-
'Permission does not exist.')
458-
459-
elif obj['type'] == 'egroup':
460-
try:
461-
role = get_existing_or_register_role(obj['email'])
462-
except DoesNotExistInLDAP:
463-
raise UpdateDepositPermissionsError(
464-
'Egroup with this mail does not exist in LDAP.')
465-
466-
if obj['op'] == 'add':
467-
try:
468-
self._add_egroup_permissions(
469-
role, [obj['action']], db.session)
470-
except IntegrityError:
471-
raise UpdateDepositPermissionsError(
472-
'Permission already exist.')
473-
elif obj['op'] == 'remove':
474-
try:
475-
self._remove_egroup_permissions(
476-
role, [obj['action']], db.session)
477-
except NoResultFound:
478-
raise UpdateDepositPermissionsError(
479-
'Permission does not exist.')
434+
for obj in data:
435+
if obj['type'] == 'user':
436+
try:
437+
user = get_existing_or_register_user(obj['email'])
438+
except DoesNotExistInLDAP:
439+
raise UpdateDepositPermissionsError(
440+
'User with this mail does not exist in LDAP.')
441+
442+
if obj['op'] == 'add':
443+
self._add_user_permissions(
444+
user, [obj['action']], db.session)
445+
elif obj['op'] == 'remove':
446+
self._remove_user_permissions(
447+
user, [obj['action']], db.session)
448+
449+
elif obj['type'] == 'egroup':
450+
try:
451+
role = get_existing_or_register_role(obj['email'])
452+
except DoesNotExistInLDAP:
453+
raise UpdateDepositPermissionsError(
454+
'Egroup with this mail does not exist in LDAP.')
455+
456+
if obj['op'] == 'add':
457+
self._add_egroup_permissions(
458+
role, [obj['action']], db.session)
459+
elif obj['op'] == 'remove':
460+
self._remove_egroup_permissions(
461+
role, [obj['action']], db.session)
480462

481463
self.commit()
482-
483464
return self
484465

485466
@preserve(result=False, fields=PRESERVE_FIELDS)
@@ -508,45 +489,65 @@ def commit(self, *args, **kwargs):
508489
def _add_user_permissions(self, user, permissions, session):
509490
"""Adds permissions for user for this deposit."""
510491
for permission in permissions:
511-
session.add(
512-
ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
513-
user=user))
514-
515-
session.flush()
516-
517-
self['_access'][permission]['users'].append(user.id)
492+
try:
493+
session.add(
494+
ActionUsers.allow(
495+
DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
496+
user=user)
497+
)
498+
session.flush()
499+
except IntegrityError:
500+
session.rollback()
501+
502+
if user.id not in self['_access'][permission]['users']:
503+
self['_access'][permission]['users'].append(user.id)
518504

519505
def _remove_user_permissions(self, user, permissions, session):
520506
"""Remove permissions for user for this deposit."""
521507
for permission in permissions:
522-
session.delete(
523-
ActionUsers.query.filter(ActionUsers.action == permission,
524-
ActionUsers.argument == str(self.id),
525-
ActionUsers.user_id == user.id).one())
526-
session.flush()
508+
try:
509+
session.delete(
510+
ActionUsers.query.filter(
511+
ActionUsers.action == permission,
512+
ActionUsers.argument == str(self.id),
513+
ActionUsers.user_id == user.id).one()
514+
)
515+
session.flush()
516+
except NoResultFound:
517+
session.rollback()
527518

528-
self['_access'][permission]['users'].remove(user.id)
519+
if user.id in self['_access'][permission]['users']:
520+
self['_access'][permission]['users'].remove(user.id)
529521

530522
def _add_egroup_permissions(self, egroup, permissions, session):
531523
for permission in permissions:
532-
session.add(
533-
ActionRoles.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
534-
role=egroup))
535-
session.flush()
524+
try:
525+
session.add(
526+
ActionRoles.allow(
527+
DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
528+
role=egroup)
529+
)
530+
session.flush()
531+
except IntegrityError:
532+
session.rollback()
536533

537534
if egroup.id not in self['_access'][permission]['roles']:
538535
self['_access'][permission]['roles'].append(egroup.id)
539536

540537
def _remove_egroup_permissions(self, egroup, permissions, session):
541538
for permission in permissions:
542-
session.delete(
543-
ActionRoles.query.filter(
544-
ActionRoles.action == permission,
545-
ActionRoles.argument == str(self.id),
546-
ActionRoles.role_id == egroup.id).one())
547-
session.flush()
548-
549-
self['_access'][permission]['roles'].remove(egroup.id)
539+
try:
540+
session.delete(
541+
ActionRoles.query.filter(
542+
ActionRoles.action == permission,
543+
ActionRoles.argument == str(self.id),
544+
ActionRoles.role_id == egroup.id).one())
545+
session.flush()
546+
except NoResultFound:
547+
session.rollback()
548+
549+
if egroup.id in self['_access'][permission]['roles']:
550+
self['_access'][permission]['roles'].remove(egroup.id)
550551

551552
def _add_experiment_permissions(self, experiment, permissions):
552553
"""Add read permissions to everybody assigned to experiment."""

tests/integration/test_permissions_api.py

+59-14
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from __future__ import absolute_import, print_function
2828

2929
import json
30+
import time
3031

3132
from flask import current_app
3233
from werkzeug.local import LocalProxy
@@ -178,7 +179,7 @@ def test_add_permissions_for_user_that_doesnt_exist_in_ldap_returns_400(
178179
'message'] == 'User with this mail does not exist in LDAP.'
179180

180181

181-
def test_add_permissions_when_permission_already_exist_returns_400(
182+
def test_add_permissions_when_permission_already_exist_returns_201(
182183
client, users, auth_headers_for_superuser, create_deposit, json_headers):
183184
owner = users['cms_user']
184185
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
@@ -196,11 +197,13 @@ def test_add_permissions_when_permission_already_exist_returns_400(
196197
]),
197198
)
198199

199-
assert resp.status_code == 400
200-
assert resp.json['message'] == 'Permission already exist.'
200+
assert resp.status_code == 201
201+
202+
resp = client.get('/deposits/', headers=auth_headers_for_superuser)
203+
assert owner.email in resp.json['hits']['hits'][0]['access']['deposit-read']['users']
201204

202205

203-
def test_add_permissions_when_permission_doesnt_exist_returns_400(
206+
def test_add_permissions_when_permission_doesnt_exist_returns_201(
204207
client, users, auth_headers_for_superuser, create_deposit, json_headers):
205208
owner, other_user = users['cms_user'], users['cms_user2']
206209
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
@@ -218,10 +221,50 @@ def test_add_permissions_when_permission_doesnt_exist_returns_400(
218221
]),
219222
)
220223

221-
assert resp.status_code == 400
222-
assert resp.json['message'] == 'Permission does not exist.'
224+
assert resp.status_code == 201
223225

224226

227+
def test_add_multiple_permissions_with_one_failing_adds_the_others(
228+
client, users, auth_headers_for_superuser, create_deposit, json_headers):
229+
owner, other_user = users['cms_user'], users['cms_user2']
230+
third_user = users['lhcb_user']
231+
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
232+
233+
resp = client.post(
234+
f'/deposits/{pid}/actions/permissions',
235+
headers=auth_headers_for_superuser + json_headers,
236+
data=json.dumps([
237+
{
238+
'email': owner.email, # this should fail, the rest should work
239+
'type': 'user',
240+
'op': 'add',
241+
'action': 'deposit-read'
242+
},
243+
{
244+
'email': other_user.email,
245+
'type': 'user',
246+
'op': 'add',
247+
'action': 'deposit-read'
248+
},
249+
{
250+
'email': third_user.email,
251+
'type': 'user',
252+
'op': 'add',
253+
'action': 'deposit-read'
254+
}
255+
]),
256+
)
257+
258+
assert resp.status_code == 201
259+
time.sleep(1)
260+
261+
resp = client.get('/deposits/', headers=auth_headers_for_superuser)
262+
read_users = resp.json['hits']['hits'][0]['access']['deposit-read']['users']
263+
264+
assert owner.email in read_users
265+
assert other_user.email in read_users
266+
assert third_user.email in read_users
267+
225268
@mark.skip('to discuss if this should be done this way')
226269
def test_add_permissions_when_add_admin_permissions_add_all_the_others_as_well(
227270
client, users, auth_headers_for_user, create_deposit, json_headers):
@@ -242,10 +285,8 @@ def test_add_permissions_when_add_admin_permissions_add_all_the_others_as_well(
242285
)
243286

244287

245-
def test_add_ermissions_gives_permissions_for_user(client, users,
246-
auth_headers_for_user,
247-
create_deposit,
248-
json_headers):
288+
def test_add_permissions_gives_permissions_for_user(
289+
client, users, auth_headers_for_user, create_deposit, json_headers):
249290
owner, other_user = users['cms_user'], users['cms_user2']
250291
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
251292

@@ -481,8 +522,10 @@ def test_change_permissions_for_egroup_is_not_case_sensitive(
481522
]),
482523
)
483524

484-
assert resp.status_code == 400
485-
assert resp.json['message'] == 'Permission already exist.'
525+
assert resp.status_code == 201
526+
527+
resp = client.get('/deposits/', headers=auth_headers_for_user(owner))
528+
assert owner.email in resp.json['hits']['hits'][0]['access']['deposit-read']['users']
486529

487530
resp = client.post(
488531
f'/deposits/{pid}/actions/permissions',
@@ -535,8 +578,10 @@ def test_change_permissions_for_user_is_not_case_sensitive(
535578
]),
536579
)
537580

538-
assert resp.status_code == 400
539-
assert resp.json['message'] == 'Permission already exist.'
581+
assert resp.status_code == 201
582+
583+
resp = client.get('/deposits/', headers=auth_headers_for_user(owner))
584+
assert owner.email in resp.json['hits']['hits'][0]['access']['deposit-read']['users']
540585

541586
resp = client.post(
542587
f'/deposits/{pid}/actions/permissions',

0 commit comments

Comments
 (0)