Skip to content

Commit

Permalink
Fixed bug w/ not checking permissions in copy (#174)
Browse files Browse the repository at this point in the history
* Fixed bug w/ not checking permissions in copy

* Check read access for secondary libraries

* added access check for public libraries and fixed unittests

* adding a not

* fixing tests

* changed it to stop using merge

* created variables and changed logic

* added tests and removed write access check

* fixed bug

* changing accesses hoping it's final

---------

Co-authored-by: femalves <[email protected]>
  • Loading branch information
kelockhart and femalves authored Dec 21, 2023
1 parent f584fb5 commit 34ba5bd
Show file tree
Hide file tree
Showing 3 changed files with 351 additions and 34 deletions.
274 changes: 272 additions & 2 deletions biblib/tests/unit_tests/test_webservices.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ def test_operations_view_post_types(self):
self.assertEqual(response.json['error'], NO_LIBRARY_SPECIFIED_ERROR['body'])

post_data['action'] = 'copy'
post_data['libraries'] = ['lib1', 'lib2']
post_data['libraries'] = [library_id_1, library_id_2]
response = self.client.post(
url,
data=json.dumps(post_data),
Expand All @@ -727,6 +727,276 @@ def test_operations_view_post_types(self):
self.assertEqual(response.status_code, TOO_MANY_LIBRARIES_SPECIFIED_ERROR['number'])
self.assertEqual(response.json['error'], TOO_MANY_LIBRARIES_SPECIFIED_ERROR['body'])

def test_permissions_on_operations_view_post_types(self):

# Create admin user to give out permissions
admin_user = UserShop()

# Create stub user to use libraries
stub_user = UserShop()

stub_library_1 = LibraryShop()
stub_library_2 = LibraryShop()
stub_library_3 = LibraryShop(public=True)

# Make libraries
# Make the libraries with admin as admin
url = url_for('userview')
response_1 = self.client.post(
url,
data=stub_library_1.user_view_post_data_json,
headers=admin_user.headers
)
library_id_1 = response_1.json['id']

response_2 = self.client.post(
url,
data=stub_library_2.user_view_post_data_json,
headers=admin_user.headers
)
library_id_2 = response_2.json['id']

response_3 = self.client.post(
url,
data=stub_library_3.user_view_post_data_json,
headers=admin_user.headers
)
library_id_3 = response_3.json['id']

# Copy success: User has read access primary and write access secondary
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': True, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='copy', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 200)

# Copy success: User is admin
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': False, 'admin': True, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': True, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='copy', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 200)

# Copy fail: User does not have right permissions
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': True, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='copy', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 403)

# Copy success: User does not have right permissions for primary but library is public
url = url_for('permissionview', library=library_id_3)

with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': True, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_3)
post_data = stub_library_3.operations_view_post_data(action='copy', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 200)

# Union success: User has read access primary and read access secondary
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='union', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 200)

# Union success: User does not have the right permissions for secondary but it's public
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_3)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='union', libraries=[library_id_3])
post_data['name'] = 'New Library 1'
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)
self.assertEqual(response.status_code, 200)

# Union fail: User does not have right permissions
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='union', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 403)

# Union fail: User does not have right permissions
url = url_for('permissionview', library=library_id_1)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': True, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('permissionview', library=library_id_2)
with MockEmailService(stub_user):
response = self.client.post(
url,
data=stub_user.permission_view_post_data_json({'read': False, 'write': False, 'admin': False, 'owner': False}),
headers=admin_user.headers
)
self.assertEqual(response.status_code, 200)

url = url_for('operationsview', library=library_id_1)
post_data = stub_library_1.operations_view_post_data(action='union', libraries=[library_id_2])
response = self.client.post(
url,
data=json.dumps(post_data),
headers=stub_user.headers
)

self.assertEqual(response.status_code, 403)


def test_document_view_put_types(self):
"""
Tests that the content passed to the UserView POST end point
Expand Down Expand Up @@ -1487,7 +1757,7 @@ def _create_libraries(self, n=2, lib_data=None):
lib_ids = []
libraries = []
for nl in range(n):
stub_library = LibraryShop()
stub_library = LibraryShop(public=True)

# Make the libraries
url = url_for('userview')
Expand Down
26 changes: 24 additions & 2 deletions biblib/views/base_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class BaseView(Resource):
#default permissions for write_access()
write_allowed = ['write', 'admin', 'owner']

# default permissions for read_access()
read_allowed = ['read', 'write', 'admin', 'owner']

@staticmethod
def helper_uuid_to_slug(library_uuid):
"""
Expand Down Expand Up @@ -223,8 +226,27 @@ def delete_access(cls, service_uid, library_id):
delete_allowed = cls.helper_access_allowed(service_uid=service_uid,
library_id=library_id,
access_type='owner')
return delete_allowed

return delete_allowed

@classmethod
def read_access(cls, service_uid, library_id):
"""
Defines which type of user has read permissions to a library.
:param service_uid: the user ID within this microservice
:param library_id: the unique ID of the library
:return: boolean, access (True), no access (False)
"""

for access_type in cls.read_allowed:
if cls.helper_access_allowed(service_uid=service_uid,
library_id=library_id,
access_type=access_type):
return True

return False

@classmethod
def write_access(cls, service_uid, library_id):
"""
Expand Down
Loading

0 comments on commit 34ba5bd

Please sign in to comment.