Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bug w/ not checking permissions in copy #174

Merged
merged 10 commits into from
Dec 21, 2023
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 @@ -28,6 +28,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 @@ -222,8 +225,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
Loading