From f360de10de584b48f6cbd82c6c8d009c191f1279 Mon Sep 17 00:00:00 2001 From: npalaska Date: Wed, 17 Mar 2021 01:10:51 -0400 Subject: [PATCH] make login optional on public metadata obbject query --- .../server/api/resources/metadata_api.py | 41 +++++++++++++++---- ...a_sessions.py => test_metadata_objects.py} | 18 ++++---- 2 files changed, 42 insertions(+), 17 deletions(-) rename lib/pbench/test/unit/server/{test_metadata_sessions.py => test_metadata_objects.py} (95%) diff --git a/lib/pbench/server/api/resources/metadata_api.py b/lib/pbench/server/api/resources/metadata_api.py index 3b6f5ae496..e4bd565948 100644 --- a/lib/pbench/server/api/resources/metadata_api.py +++ b/lib/pbench/server/api/resources/metadata_api.py @@ -154,6 +154,15 @@ def __init__(self, config, logger): def verify_metadata(self, metadata): current_user = Auth.token_auth.current_user() metadata_user_id = metadata.user_id + if current_user is None: + # The request is not from a logged-in user + if metadata_user_id is None: + return True + self.logger.warning( + "Metadata user verification: Public user is trying to access private metadata object for user {}", + metadata_user_id, + ) + return False if current_user.id != metadata_user_id and not current_user.is_admin(): self.logger.warning( "Metadata user verification: Logged in user_id {} is different than the one provided in the URI {}", @@ -163,15 +172,16 @@ def verify_metadata(self, metadata): return False return True - @Auth.token_auth.login_required() + @Auth.token_auth.login_required(optional=True) def get(self, id=None): """ Get request for querying a metadata object of a user given a metadata id. - This requires a Pbench auth token in the header field + This requires a Pbench auth token in the header field if the metadata object is private to a user + The url requires a metadata object id such as /user/metadata/ - Required headers include + Optional headers include Authorization: Bearer :return: JSON Payload @@ -191,7 +201,7 @@ def get(self, id=None): try: # Fetch the metadata object - metadata_object = Metadata.query(id=id)[0] + metadata_objects = Metadata.query(id=id) except Exception: self.logger.exception( "Exception occurred in the GET request while querying the Metadata model, id: {}", @@ -199,6 +209,11 @@ def get(self, id=None): ) abort(500, message="INTERNAL ERROR") + if metadata_objects: + metadata_object = metadata_objects[0] + else: + abort(404, message="Not found") + # Verify if the metadata object id in the url belongs to the logged in user if not self.verify_metadata(metadata_object): abort(403, message="Not authorized to perform the GET request") @@ -210,7 +225,7 @@ def get(self, id=None): } return make_response(jsonify(response_object), 200) - @Auth.token_auth.login_required() + @Auth.token_auth.login_required(optional=True) def put(self, id=None): """ Put request for updating a metadata object of a user given a metadata id. @@ -248,7 +263,7 @@ def put(self, id=None): abort(400, message="Invalid json object in request") try: - metadata_object = Metadata.query(id=id)[0] + metadata_objects = Metadata.query(id=id) except Exception: self.logger.exception( "Exception occurred in the PUT request while querying the Metadata model, id: {}", @@ -256,6 +271,11 @@ def put(self, id=None): ) abort(500, message="INTERNAL ERROR") + if metadata_objects: + metadata_object = metadata_objects[0] + else: + abort(404, message="Not found") + # Verify if the metadata object id in the url belongs to the logged in user if not self.verify_metadata(metadata_object): abort(403, message="Not authorized to perform the PUT request") @@ -293,7 +313,7 @@ def put(self, id=None): } return make_response(jsonify(response_object), 200) - @Auth.token_auth.login_required() + @Auth.token_auth.login_required(optional=True) def delete(self, id=None): """ Delete request for deleting a metadata object of a user given a metadata id. @@ -315,7 +335,7 @@ def delete(self, id=None): try: # Fetch the metadata object - metadata_object = Metadata.query(id=id)[0] + metadata_objects = Metadata.query(id=id) except Exception: self.logger.exception( "Exception occurred in the Delete request while querying the Metadata model, id: {}", @@ -323,6 +343,11 @@ def delete(self, id=None): ) abort(500, message="INTERNAL ERROR") + if metadata_objects: + metadata_object = metadata_objects[0] + else: + abort(404, message="Not found") + # Verify if the metadata object id in the url belongs to the logged in user if not self.verify_metadata(metadata_object): abort(403, message="Not authorized to perform the DELETE request") diff --git a/lib/pbench/test/unit/server/test_metadata_sessions.py b/lib/pbench/test/unit/server/test_metadata_objects.py similarity index 95% rename from lib/pbench/test/unit/server/test_metadata_sessions.py rename to lib/pbench/test/unit/server/test_metadata_objects.py index 1c94f7d830..a414b944e1 100644 --- a/lib/pbench/test/unit/server/test_metadata_sessions.py +++ b/lib/pbench/test/unit/server/test_metadata_objects.py @@ -22,7 +22,7 @@ def user_register_login(client, server_config): return data_login -class TestMetadataSession: +class TestMetadataObjects: @staticmethod def test_metadata_creation_with_authorization(client, server_config): data_login = user_register_login(client, server_config) @@ -65,7 +65,7 @@ def test_metadata_creation_with_authorization(client, server_config): == '{"config": "config1", "description": "description1"}' ) - # Get all the saved sessions of logged in user + # Get all the saved metadata objects of logged in user response = client.get( f"{server_config.rest_uri}/metadata/saved", headers=dict(Authorization="Bearer " + data_login["auth_token"]), @@ -77,7 +77,7 @@ def test_metadata_creation_with_authorization(client, server_config): @staticmethod def test_unauthorized_metadata_creation(client, server_config): with client: - # Create a saved session + # Create a saved object response = client.post( f"{server_config.rest_uri}/metadata", json={ @@ -89,7 +89,7 @@ def test_unauthorized_metadata_creation(client, server_config): assert data assert response.status_code == 201 - # Create a favorite session + # Create a favorite metadata object response = client.post( f"{server_config.rest_uri}/metadata", json={ @@ -101,7 +101,7 @@ def test_unauthorized_metadata_creation(client, server_config): data = response.json assert data["data"]["key"] == "favorite" - # Get all the favorite sessions of non-logged in user + # Get all the favorite metadata objects of non-logged in user response = client.get(f"{server_config.rest_uri}/metadata/favorite") assert response.status_code == 200 data = response.json @@ -110,7 +110,7 @@ def test_unauthorized_metadata_creation(client, server_config): == '{"config": "config2", "description": "description2"}' ) - # Get all the saved sessions of non-logged in user + # Get all the saved metadata objects of non-logged in user response = client.get(f"{server_config.rest_uri}/metadata/saved",) assert response.status_code == 200 data = response.json @@ -158,7 +158,7 @@ def test_unauthorized_metadata_query1(client, server_config): metadata_id = data["data"]["id"] response = client.get(f"{server_config.rest_uri}/metadata/{metadata_id}",) - assert response.status_code == 401 + assert response.status_code == 403 @staticmethod def test_unauthorized_metadata_query2(client, server_config): @@ -193,7 +193,7 @@ def test_unauthorized_metadata_query2(client, server_config): data_login_2 = response.json assert data_login_2["auth_token"] - # Create metadata session for 2nd user + # Create metadata objects for 2nd user response = client.post( f"{server_config.rest_uri}/metadata", json={ @@ -205,7 +205,7 @@ def test_unauthorized_metadata_query2(client, server_config): data_2 = response.json assert data_2["data"]["id"] - # Query the metadata session id of the 1st user with an auth token of 2nd user + # Query the metadata object id of the 1st user with an auth token of 2nd user metadata_id = data_1["data"]["id"] response = client.get( f"{server_config.rest_uri}/metadata/{metadata_id}",