Skip to content

Commit db527f9

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 47dbc8b commit db527f9

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
@@ -428,55 +428,36 @@ def edit_permissions(self, data):
428428
}]
429429
430430
"""
431-
with db.session.begin_nested():
432-
for obj in data:
433-
if obj['type'] == 'user':
434-
try:
435-
user = get_existing_or_register_user(obj['email'])
436-
except DoesNotExistInLDAP:
437-
raise UpdateDepositPermissionsError(
438-
'User with this mail does not exist in LDAP.')
439-
440-
if obj['op'] == 'add':
441-
try:
442-
self._add_user_permissions(user, [obj['action']],
443-
db.session)
444-
except IntegrityError:
445-
raise UpdateDepositPermissionsError(
446-
'Permission already exist.')
447-
448-
elif obj['op'] == 'remove':
449-
try:
450-
self._remove_user_permissions(
451-
user, [obj['action']], db.session)
452-
except NoResultFound:
453-
raise UpdateDepositPermissionsError(
454-
'Permission does not exist.')
455-
456-
elif obj['type'] == 'egroup':
457-
try:
458-
role = get_existing_or_register_role(obj['email'])
459-
except DoesNotExistInLDAP:
460-
raise UpdateDepositPermissionsError(
461-
'Egroup with this mail does not exist in LDAP.')
462-
463-
if obj['op'] == 'add':
464-
try:
465-
self._add_egroup_permissions(
466-
role, [obj['action']], db.session)
467-
except IntegrityError:
468-
raise UpdateDepositPermissionsError(
469-
'Permission already exist.')
470-
elif obj['op'] == 'remove':
471-
try:
472-
self._remove_egroup_permissions(
473-
role, [obj['action']], db.session)
474-
except NoResultFound:
475-
raise UpdateDepositPermissionsError(
476-
'Permission does not exist.')
431+
for obj in data:
432+
if obj['type'] == 'user':
433+
try:
434+
user = get_existing_or_register_user(obj['email'])
435+
except DoesNotExistInLDAP:
436+
raise UpdateDepositPermissionsError(
437+
'User with this mail does not exist in LDAP.')
438+
439+
if obj['op'] == 'add':
440+
self._add_user_permissions(
441+
user, [obj['action']], db.session)
442+
elif obj['op'] == 'remove':
443+
self._remove_user_permissions(
444+
user, [obj['action']], db.session)
445+
446+
elif obj['type'] == 'egroup':
447+
try:
448+
role = get_existing_or_register_role(obj['email'])
449+
except DoesNotExistInLDAP:
450+
raise UpdateDepositPermissionsError(
451+
'Egroup with this mail does not exist in LDAP.')
452+
453+
if obj['op'] == 'add':
454+
self._add_egroup_permissions(
455+
role, [obj['action']], db.session)
456+
elif obj['op'] == 'remove':
457+
self._remove_egroup_permissions(
458+
role, [obj['action']], db.session)
477459

478460
self.commit()
479-
480461
return self
481462

482463
@preserve(result=False, fields=PRESERVE_FIELDS)
@@ -505,45 +486,65 @@ def commit(self, *args, **kwargs):
505486
def _add_user_permissions(self, user, permissions, session):
506487
"""Adds permissions for user for this deposit."""
507488
for permission in permissions:
508-
session.add(
509-
ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
510-
user=user))
511-
512-
session.flush()
513-
514-
self['_access'][permission]['users'].append(user.id)
489+
try:
490+
session.add(
491+
ActionUsers.allow(
492+
DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
493+
user=user)
494+
)
495+
session.flush()
496+
except IntegrityError:
497+
session.rollback()
498+
499+
if user.id not in self['_access'][permission]['users']:
500+
self['_access'][permission]['users'].append(user.id)
515501

516502
def _remove_user_permissions(self, user, permissions, session):
517503
"""Remove permissions for user for this deposit."""
518504
for permission in permissions:
519-
session.delete(
520-
ActionUsers.query.filter(ActionUsers.action == permission,
521-
ActionUsers.argument == str(self.id),
522-
ActionUsers.user_id == user.id).one())
523-
session.flush()
505+
try:
506+
session.delete(
507+
ActionUsers.query.filter(
508+
ActionUsers.action == permission,
509+
ActionUsers.argument == str(self.id),
510+
ActionUsers.user_id == user.id).one()
511+
)
512+
session.flush()
513+
except NoResultFound:
514+
session.rollback()
524515

525-
self['_access'][permission]['users'].remove(user.id)
516+
if user.id in self['_access'][permission]['users']:
517+
self['_access'][permission]['users'].remove(user.id)
526518

527519
def _add_egroup_permissions(self, egroup, permissions, session):
528520
for permission in permissions:
529-
session.add(
530-
ActionRoles.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
531-
role=egroup))
532-
session.flush()
521+
try:
522+
session.add(
523+
ActionRoles.allow(
524+
DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
525+
role=egroup)
526+
)
527+
session.flush()
528+
except IntegrityError:
529+
session.rollback()
533530

534531
if egroup.id not in self['_access'][permission]['roles']:
535532
self['_access'][permission]['roles'].append(egroup.id)
536533

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

548549
def _add_experiment_permissions(self, experiment, permissions):
549550
"""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)