Skip to content

Commit 22197a7

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 41c3663 commit 22197a7

File tree

2 files changed

+137
-86
lines changed

2 files changed

+137
-86
lines changed

cap/modules/deposit/api.py

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

473455
self.commit()
474-
475456
return self
476457

477458
@preserve(result=False, fields=PRESERVE_FIELDS)
@@ -500,45 +481,65 @@ def commit(self, *args, **kwargs):
500481
def _add_user_permissions(self, user, permissions, session):
501482
"""Adds permissions for user for this deposit."""
502483
for permission in permissions:
503-
session.add(
504-
ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
505-
user=user))
506-
507-
session.flush()
508-
509-
self['_access'][permission]['users'].append(user.id)
484+
try:
485+
session.add(
486+
ActionUsers.allow(
487+
DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
488+
user=user)
489+
)
490+
session.flush()
491+
except IntegrityError:
492+
session.rollback()
493+
494+
if user.id not in self['_access'][permission]['users']:
495+
self['_access'][permission]['users'].append(user.id)
510496

511497
def _remove_user_permissions(self, user, permissions, session):
512498
"""Remove permissions for user for this deposit."""
513499
for permission in permissions:
514-
session.delete(
515-
ActionUsers.query.filter(ActionUsers.action == permission,
516-
ActionUsers.argument == str(self.id),
517-
ActionUsers.user_id == user.id).one())
518-
session.flush()
500+
try:
501+
session.delete(
502+
ActionUsers.query.filter(
503+
ActionUsers.action == permission,
504+
ActionUsers.argument == str(self.id),
505+
ActionUsers.user_id == user.id).one()
506+
)
507+
session.flush()
508+
except NoResultFound:
509+
session.rollback()
519510

520-
self['_access'][permission]['users'].remove(user.id)
511+
if user.id in self['_access'][permission]['users']:
512+
self['_access'][permission]['users'].remove(user.id)
521513

522514
def _add_egroup_permissions(self, egroup, permissions, session):
523515
for permission in permissions:
524-
session.add(
525-
ActionRoles.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
526-
role=egroup))
527-
session.flush()
516+
try:
517+
session.add(
518+
ActionRoles.allow(
519+
DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
520+
role=egroup)
521+
)
522+
session.flush()
523+
except IntegrityError:
524+
session.rollback()
528525

529526
if egroup.id not in self['_access'][permission]['roles']:
530527
self['_access'][permission]['roles'].append(egroup.id)
531528

532529
def _remove_egroup_permissions(self, egroup, permissions, session):
533530
for permission in permissions:
534-
session.delete(
535-
ActionRoles.query.filter(
536-
ActionRoles.action == permission,
537-
ActionRoles.argument == str(self.id),
538-
ActionRoles.role_id == egroup.id).one())
539-
session.flush()
540-
541-
self['_access'][permission]['roles'].remove(egroup.id)
531+
try:
532+
session.delete(
533+
ActionRoles.query.filter(
534+
ActionRoles.action == permission,
535+
ActionRoles.argument == str(self.id),
536+
ActionRoles.role_id == egroup.id).one())
537+
session.flush()
538+
except NoResultFound:
539+
session.rollback()
540+
541+
if egroup.id in self['_access'][permission]['roles']:
542+
self['_access'][permission]['roles'].remove(egroup.id)
542543

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

tests/integration/test_permissions_api.py

+64-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,14 @@ 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+
depid = resp.json['id']
202+
203+
resp = client.get(f'/deposits/{depid}', headers=auth_headers_for_superuser)
204+
assert owner.email == resp.json['access']['deposit-read']['users'][0]['email']
201205

202206

203-
def test_add_permissions_when_permission_doesnt_exist_returns_400(
207+
def test_add_permissions_when_permission_doesnt_exist_returns_201(
204208
client, users, auth_headers_for_superuser, create_deposit, json_headers):
205209
owner, other_user = users['cms_user'], users['cms_user2']
206210
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
@@ -218,9 +222,51 @@ def test_add_permissions_when_permission_doesnt_exist_returns_400(
218222
]),
219223
)
220224

221-
assert resp.status_code == 400
222-
assert resp.json['message'] == 'Permission does not exist.'
225+
assert resp.status_code == 201
226+
227+
228+
def test_add_multiple_permissions_with_one_failing_adds_the_others(
229+
client, users, auth_headers_for_superuser, create_deposit, json_headers):
230+
owner, other_user = users['cms_user'], users['cms_user2']
231+
third_user = users['lhcb_user']
232+
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
233+
234+
resp = client.post(
235+
f'/deposits/{pid}/actions/permissions',
236+
headers=auth_headers_for_superuser + json_headers,
237+
data=json.dumps([
238+
{
239+
'email': owner.email, # this should fail, the rest should work
240+
'type': 'user',
241+
'op': 'add',
242+
'action': 'deposit-read'
243+
},
244+
{
245+
'email': other_user.email,
246+
'type': 'user',
247+
'op': 'add',
248+
'action': 'deposit-read'
249+
},
250+
{
251+
'email': third_user.email,
252+
'type': 'user',
253+
'op': 'add',
254+
'action': 'deposit-read'
255+
}
256+
]),
257+
)
223258

259+
assert resp.status_code == 201
260+
depid = resp.json['id']
261+
262+
time.sleep(1)
263+
264+
resp = client.get(f'/deposits/{depid}', headers=auth_headers_for_superuser)
265+
read_users = [user['email'] for user in resp.json['access']['deposit-read']['users']]
266+
267+
assert owner.email in read_users
268+
assert other_user.email in read_users
269+
assert third_user.email in read_users
224270

225271
@mark.skip('to discuss if this should be done this way')
226272
def test_add_permissions_when_add_admin_permissions_add_all_the_others_as_well(
@@ -242,10 +288,8 @@ def test_add_permissions_when_add_admin_permissions_add_all_the_others_as_well(
242288
)
243289

244290

245-
def test_add_ermissions_gives_permissions_for_user(client, users,
246-
auth_headers_for_user,
247-
create_deposit,
248-
json_headers):
291+
def test_add_permissions_gives_permissions_for_user(
292+
client, users, auth_headers_for_user, create_deposit, json_headers):
249293
owner, other_user = users['cms_user'], users['cms_user2']
250294
pid = create_deposit(owner, 'test-v1.0.0')['_deposit']['id']
251295

@@ -481,8 +525,11 @@ def test_change_permissions_for_egroup_is_not_case_sensitive(
481525
]),
482526
)
483527

484-
assert resp.status_code == 400
485-
assert resp.json['message'] == 'Permission already exist.'
528+
assert resp.status_code == 201
529+
depid = resp.json['id']
530+
531+
resp = client.get(f'/deposits/{depid}', headers=auth_headers_for_user(owner))
532+
assert owner.email == resp.json['access']['deposit-read']['users'][0]['email']
486533

487534
resp = client.post(
488535
f'/deposits/{pid}/actions/permissions',
@@ -535,8 +582,11 @@ def test_change_permissions_for_user_is_not_case_sensitive(
535582
]),
536583
)
537584

538-
assert resp.status_code == 400
539-
assert resp.json['message'] == 'Permission already exist.'
585+
assert resp.status_code == 201
586+
depid = resp.json['id']
587+
588+
resp = client.get(f'/deposits/{depid}', headers=auth_headers_for_user(owner))
589+
assert owner.email == resp.json['access']['deposit-read']['users'][0]['email']
540590

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

0 commit comments

Comments
 (0)