From ba71d77d5f690ef1e2e465082619040be226c729 Mon Sep 17 00:00:00 2001 From: npalaska Date: Tue, 9 Mar 2021 00:30:48 -0500 Subject: [PATCH] Refactoring, address comments, more unit tests, metadata_api updates --- lib/pbench/server/api/__init__.py | 13 +- .../server/api/resources/graphql_api.py | 251 +------------ .../server/api/resources/metadata_api.py | 331 ++++++++++++++++++ lib/pbench/server/database/models/metadata.py | 86 ++++- .../unit/server/test_metadata_sessions.py | 223 ++++++++++++ lib/pbench/test/unit/server/test_user_auth.py | 47 --- 6 files changed, 634 insertions(+), 317 deletions(-) create mode 100644 lib/pbench/server/api/resources/metadata_api.py create mode 100644 lib/pbench/test/unit/server/test_metadata_sessions.py diff --git a/lib/pbench/server/api/__init__.py b/lib/pbench/server/api/__init__.py index a2f2fd3c24..c96e6eace1 100644 --- a/lib/pbench/server/api/__init__.py +++ b/lib/pbench/server/api/__init__.py @@ -7,14 +7,15 @@ import os import sys -from flask import Flask, request +from flask import Flask from flask_restful import Api from flask_cors import CORS from pbench.server import PbenchServerConfig from pbench.common.exceptions import BadConfig, ConfigFileNotSpecified from pbench.server.api.resources.upload_api import Upload, HostInfo -from pbench.server.api.resources.graphql_api import GraphQL, UserMetadata, QueryMetadata +from pbench.server.api.resources.graphql_api import GraphQL +from pbench.server.api.resources.metadata_api import UserMetadata, QueryMetadata from pbench.common.logger import get_pbench_logger from pbench.server.api.resources.query_apis.elasticsearch_api import Elasticsearch from pbench.server.api.resources.query_apis.query_controllers import QueryControllers @@ -86,10 +87,14 @@ def register_endpoints(api, app, config): ) api.add_resource( - UserMetadata, f"{base_uri}/metadata", resource_class_args=(config, logger, token_auth), + UserMetadata, + f"{base_uri}/metadata", + resource_class_args=(config, logger, token_auth), ) api.add_resource( - QueryMetadata, f"{base_uri}/metadata/", resource_class_args=(config, logger), + QueryMetadata, + f"{base_uri}/metadata/", + resource_class_args=(config, logger), ) diff --git a/lib/pbench/server/api/resources/graphql_api.py b/lib/pbench/server/api/resources/graphql_api.py index 29f64101cb..2f6e41a861 100644 --- a/lib/pbench/server/api/resources/graphql_api.py +++ b/lib/pbench/server/api/resources/graphql_api.py @@ -1,255 +1,6 @@ import requests -import datetime -import json from flask_restful import Resource, abort -from flask import request, make_response, jsonify -from pbench.server.database.models.metadata import MetadataModel -from pbench.server.database.database import Database -from pbench.server.api.auth import Auth - - -class UserMetadata(Resource): - """ - Abstracted pbench API for handling user metadata by using graphql schema - """ - - def __init__(self, config, logger, auth): - self.server_config = config - self.logger = logger - self.auth = auth - - @Auth.token_auth.login_required(f=Auth().verify_auth()) - def post(self): - """ - Post request for creating metadata instance for a user. - This requires a JWT auth token in the header field - - This requires a JSON data with required user metadata fields - { - "config": "config", - "description": "description", - } - - Required headers include - Authorization: JWT token (user received upon login) - - :return: JSON Payload - response_object = { - "status": "success" - "data" { - "id": "metadata_id", - "config": "Config string" - "description": "Description string" - } - } - """ - post_data = request.get_json() - if not post_data: - self.logger.warning("Invalid json object: %s", request.url) - abort(400, message="Invalid json object in request") - - config = post_data.get("config") - if not config: - self.logger.warning("Config not provided during metadata creation") - abort(400, message="Please provide a config string") - - description = post_data.get("description") - if not description: - self.logger.warning("Description not provided during metadata creation") - abort(400, message="Please provide a description string") - current_user_id = self.auth.token_auth.current_user().id - - try: - # Create a new metadata session - metadata_session = MetadataModel( - created=str(datetime.datetime.now()), - config=config, - description=description, - user_id=current_user_id - ) - # insert the metadata session for a user - Database.db_session.add(metadata_session) - Database.db_session.commit() - self.logger.info("New user metadata session created") - except Exception: - self.logger.exception("Exception occurred during Metadata creation") - abort(500, message="INTERNAL ERROR") - else: - response_object = { - "status": "success", - "data": { - "id": metadata_session.id, - "config": metadata_session.config, - "description": metadata_session.description, - }, - } - return make_response(jsonify(response_object), 201) - - @Auth.token_auth.login_required(f=Auth().verify_auth()) - def get(self): - """ - Get request for querying all the metadata sessions for a user. - This requires a JWT auth token in the header field - - Required headers include - Authorization: JWT token (user received upon login) - - :return: JSON Payload - response_object = { - "status": "success" - "data": { - "sessions": [ - {"id": "metadata_id", - "config": "Config string" - "description": "Description string"}, - {}] - } - } - """ - current_user_id = self.auth.token_auth.current_user().id - try: - # Fetch the metadata session - sessions = ( - Database.db_session.query(MetadataModel) - .filter_by(user_id=current_user_id) - .all() - ) - - req_keys = ["id", "config", "description", "created"] - data = json.dumps([{key: session.as_dict()[key] for key in req_keys} for session in sessions]) - except Exception: - self.logger.exception("Exception occurred during querying Metadata model") - abort(500, message="INTERNAL ERROR") - - response_object = { - "status": "success", - "data": { - "sessions": data - }, - } - return make_response(jsonify(response_object), 200) - - -class QueryMetadata(Resource): - """ - Abstracted pbench API for querying a single user metadata session - """ - - def __init__(self, config, logger): - self.server_config = config - self.logger = logger - - @Auth.token_auth.login_required(f=Auth().verify_auth()) - def get(self, id=None): - """ - Get request for querying a metadata session for a user given a metadata id. - This requires a JWT auth token in the header field - - This requires a JSON data with required user metadata fields to update - { - "description": "description", - } - - The url requires a metadata session id such as /user/metadata/ - - Required headers include - Authorization: JWT token (user received upon login) - - :return: JSON Payload - response_object = { - "status": "success" - "data" { - "id": "metadata_id", - "config": "Config string" - "description": "Description string" - } - } - """ - if not id: - self.logger.warning("Meatadata id not provided during metadata query") - abort(400, message="Please provide a metadata id to query") - - try: - # Fetch the metadata session - session = ( - Database.db_session.query(MetadataModel) - .filter_by(id=id) - .first() - ) - except Exception: - self.logger.exception("Exception occurred during querying Metadata model") - abort(500, message="INTERNAL ERROR") - else: - response_object = { - "status": "success", - "data": { - "id": session.id, - "config": session.config, - "description": session.description, - }, - } - return make_response(jsonify(response_object), 200) - - @Auth.token_auth.login_required(f=Auth().verify_auth()) - def put(self, id=None): - """ - Put request for updating a metadata session for a user given a metadata id. - This requires a JWT auth token in the header field - - The url requires a metadata session id such as /user/metadata/ - - Required headers include - Authorization: JWT token (user received upon login) - - :return: JSON Payload - response_object = { - "status": "success" - "data" { - "id": "metadata_id", - "config": "Config string" - "description": "Description string" - } - } - """ - if not id: - self.logger.warning("Meatadata id not provided during metadata query") - abort(400, message="Please provide a metadata id to query") - - post_data = request.get_json() - if not post_data: - self.logger.warning("Invalid json object: %s", request.url) - abort(400, message="Invalid json object in request") - - description = post_data.get("description") - if not description: - self.logger.warning("Description not provided during metadata update") - abort(400, message="Please provide a description string") - - try: - # Fetch the metadata session - session = ( - Database.db_session.query(MetadataModel) - .filter_by(id=id) - .first() - ) - session.description = description - # Update the metadata session for a user - Database.db_session.add(session) - Database.db_session.commit() - self.logger.info("User metadata session updated") - except Exception: - self.logger.exception("Exception occurred during querying Metadata model") - abort(500, message="INTERNAL ERROR") - else: - response_object = { - "status": "success", - "data": { - "id": session.id, - "config": session.config, - "description": session.description, - }, - } - return make_response(jsonify(response_object), 200) +from flask import request, make_response class GraphQL(Resource): diff --git a/lib/pbench/server/api/resources/metadata_api.py b/lib/pbench/server/api/resources/metadata_api.py new file mode 100644 index 0000000000..8305cdeeb5 --- /dev/null +++ b/lib/pbench/server/api/resources/metadata_api.py @@ -0,0 +1,331 @@ +from flask_restful import Resource, abort +from flask import request, make_response, jsonify +from pbench.server.database.models.metadata import Metadata +from pbench.server.api.auth import Auth + + +class UserMetadata(Resource): + """ + Abstracted pbench API for handling user metadata by using graphql schema + """ + + def __init__(self, config, logger, auth): + self.server_config = config + self.logger = logger + self.auth = auth + + @Auth.token_auth.login_required() + def post(self): + """ + Post request for creating metadata instance for a user. + This requires a Pbench auth token in the header field + + This requires a JSON data with required user metadata fields + { + "config": "config", + "description": "description", + } + + Required headers include + Authorization: Bearer + + :return: JSON Payload + response_object = { + "message": "success" + "data" { + "id": "metadata_id", + "config": "Config string" + "description": "Description string" + } + } + """ + post_data = request.get_json() + if not post_data: + self.logger.warning("Invalid json object: {}", request.url) + abort(400, message="Invalid json object in request") + + current_user_id = self.auth.token_auth.current_user().id + + config = post_data.get("config") + if not config: + self.logger.warning( + "Config not provided during metadata creation. user_id: {}", + current_user_id, + ) + abort(400, message="Config field missing") + + description = post_data.get("description") + if not description: + self.logger.warning( + "Description not provided during metadata creation by user: {}", + current_user_id, + ) + abort(400, message="Description field missing") + + try: + # Create a new metadata session + metadata_session = Metadata( + config=config, description=description, user_id=current_user_id + ) + # insert the metadata session for a user + metadata_session.add() + self.logger.info( + "New metadata session created for user_id {}", current_user_id + ) + except Exception: + self.logger.exception("Exception occurred during the Metadata creation") + abort(500, message="INTERNAL ERROR") + else: + response_object = { + "message": "success", + "data": { + "id": metadata_session.id, + "config": metadata_session.config, + "description": metadata_session.description, + }, + } + return make_response(jsonify(response_object), 201) + + @Auth.token_auth.login_required() + def get(self): + """ + Get request for querying all the metadata sessions for a user. + returns the list of all the metadata sessions associated with a logged in user. + This requires a Pbench auth token in the header field + + Required headers include + Authorization: Bearer + + :return: JSON Payload + response_object = { + "status": "success" + "data": { + "sessions": [ + {"id": "metadata_id", + "config": "Config string" + "description": "Description string"}, + {}] + } + } + """ + current_user_id = self.auth.token_auth.current_user().id + try: + # Fetch the metadata session + metadata_sessions = Metadata.query(user_id=current_user_id) + data = [session.get_json() for session in metadata_sessions] + except Exception: + self.logger.exception( + "Exception occurred while querying the Metadata model" + ) + abort(500, message="INTERNAL ERROR") + + response_object = { + "message": "success", + "data": {"sessions": data}, + } + return make_response(jsonify(response_object), 200) + + +class QueryMetadata(Resource): + """ + Abstracted pbench API for querying a single user metadata session + """ + + def __init__(self, config, logger): + self.server_config = config + self.logger = logger + + def verify_metadata(self, session, action): + current_user_id = Auth.token_auth.current_user().id + metadata_user_id = session.user_id + if current_user_id != metadata_user_id: + self.logger.warning( + "Metadata {}: Logged in user_id {} is different than the one provided in the URI {}", + action, + current_user_id, + metadata_user_id, + ) + abort(403, message="Not authorized to perform the specified action") + + @Auth.token_auth.login_required() + def get(self, id=None): + """ + Get request for querying a metadata session of a user given a metadata id. + This requires a Pbench auth token in the header field + + The url requires a metadata session id such as /user/metadata/ + + Required headers include + Authorization: Bearer + + :return: JSON Payload + response_object = { + "message": "success" + "data" { + "id": "metadata_id", + "config": "Config string" + "description": "Description string" + } + } + """ + if not id: + self.logger.warning("Metadata id not provided during metadata query") + abort(400, message="Please provide a metadata id to query") + + try: + # Fetch the metadata session + metadata_session = Metadata.query(id=id) + except Exception: + self.logger.exception( + "Exception occurred in the GET request while querying the Metadata model, id: {}", + id, + ) + abort(500, message="INTERNAL ERROR") + + # Verify if the metadata session id in the url belongs to the logged in user + self.verify_metadata(metadata_session, "get") + + response_object = { + "message": "success", + "data": { + "id": metadata_session.id, + "config": metadata_session.config, + "description": metadata_session.description, + }, + } + return make_response(jsonify(response_object), 200) + + @Auth.token_auth.login_required() + def put(self, id=None): + """ + Put request for updating a metadata session of a user given a metadata id. + This requires a Pbench auth token in the header field + + The url requires a metadata session id such as /user/metadata/ + + This requires a JSON data with required user metadata fields to update + { + "description": "description", + } + + Required headers include + Authorization: Bearer + + :return: JSON Payload + response_object = { + "message": "success" + "data" { + "id": "metadata_id", + "config": "Config string" + "description": "Description string" + } + } + """ + if not id: + self.logger.warning("Metadata id not provided during metadata query") + abort(400, message="Please provide a metadata id to query") + + post_data = request.get_json() + if not post_data: + self.logger.warning("Invalid json object: {}", request.url) + abort(400, message="Invalid json object in request") + + try: + metadata_session = Metadata.query(id=id) + except Exception: + self.logger.exception( + "Exception occurred in the PUT request while querying the Metadata model, id: {}", + id, + ) + abort(500, message="INTERNAL ERROR") + + # Verify if the metadata session id in the url belongs to the logged in user + self.verify_metadata(metadata_session, "put") + + # Check if the metadata payload contain fields that are either protected or + # not present in the metadata db. If any key in the payload does not match + # with the column name we will abort the update request. + non_existent = set(post_data.keys()).difference( + set(Metadata.__table__.columns.keys()) + ) + if non_existent: + self.logger.warning( + "User trying to update fields that are not present in the metadata database. Fields: {}", + non_existent, + ) + abort(400, message="Invalid fields in update request payload") + protected = set(post_data.keys()).intersection(set(Metadata.get_protected())) + for field in protected: + if getattr(metadata_session, field) != post_data[field]: + self.logger.warning( + "User trying to update the non-updatable fields. {}: {}", + field, + post_data[field], + ) + abort(403, message="Invalid update request payload") + try: + metadata_session.update(**post_data) + self.logger.info( + "User metadata session updated, id: {}", metadata_session.id + ) + except Exception: + self.logger.exception("Exception occurred updating the Metadata model") + abort(500, message="INTERNAL ERROR") + else: + response_object = { + "message": "success", + "data": { + "id": metadata_session.id, + "config": metadata_session.config, + "description": metadata_session.description, + }, + } + return make_response(jsonify(response_object), 200) + + @Auth.token_auth.login_required() + def delete(self, id=None): + """ + Delete request for deleting a metadata session of a user given a metadata id. + This requires a Pbench auth token in the header field + + The url requires a metadata session id such as /user/metadata/ + + Required headers include + Authorization: Bearer + + :return: JSON Payload + response_object = { + "message": "success" + } + """ + if not id: + self.logger.warning("Metadata id not provided during metadata query") + abort(400, message="Please provide a metadata id to query") + + try: + # Fetch the metadata session + metadata_session = Metadata.query(id=id) + except Exception: + self.logger.exception( + "Exception occurred in the Delete request while querying the Metadata model, id: {}", + id, + ) + abort(500, message="INTERNAL ERROR") + + # Verify if the metadata session id in the url belongs to the logged in user + self.verify_metadata(metadata_session, "delete") + + try: + # Delete the metadata session + Metadata.delete(id=id) + except Exception: + self.logger.exception( + "Exception occurred in the while deleting the metadata entry, id: {}", + id, + ) + abort(500, message="INTERNAL ERROR") + + response_object = { + "message": "success", + } + return make_response(jsonify(response_object), 200) diff --git a/lib/pbench/server/database/models/metadata.py b/lib/pbench/server/database/models/metadata.py index 69385d980d..c835fd7945 100644 --- a/lib/pbench/server/database/models/metadata.py +++ b/lib/pbench/server/database/models/metadata.py @@ -1,31 +1,85 @@ import datetime -from dateutil import parser from pbench.server.database.database import Database -from sqlalchemy import Column, Integer, String, DateTime, ForeignKey +from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Text -class MetadataModel(Database.Base): +class Metadata(Database.Base): """ Metadata Model for storing user metadata details """ # TODO: Think about the better name __tablename__ = "metadata" id = Column(Integer, primary_key=True, autoincrement=True) - created = Column(DateTime, nullable=False) - updated = Column(DateTime, nullable=False) - config = Column(String(255), unique=False, nullable=False) + created = Column(DateTime, nullable=False, default=datetime.datetime.now()) + updated = Column(DateTime, nullable=False, default=datetime.datetime.now()) + config = Column(Text, unique=False, nullable=False) description = Column(String(255), nullable=False) - user_id = Column(Integer, ForeignKey('users.id')) - - def __init__(self, created, config, description, user_id): - self.created = parser.parse(created) - self.updated = datetime.datetime.now() - self.config = config - self.description = description - self.user_id = user_id + user_id = Column(Integer, ForeignKey("users.id")) def __str__(self): return f"Url id: {self.id}, created on: {self.created}, description: {self.description}" - def as_dict(self): - return {c.name: str(getattr(self, c.name)) for c in self.__table__.columns} \ No newline at end of file + def get_json(self): + return { + "id": self.id, + "config": self.config, + "description": self.description, + "created": self.created, + "updated": self.updated, + } + + @staticmethod + def get_protected(): + return ["id", "created"] + + @staticmethod + def query(id=None, user_id=None): + # Currently we would only query with single argument. Argument need to be either id/user_id + if id: + metadata = Database.db_session.query(Metadata).filter_by(id=id).first() + elif user_id: + # If the query parameter is user_id then we return the list of all the metadata linked to that user + metadata = Database.db_session.query(Metadata).filter_by(user_id=user_id) + else: + metadata = None + + return metadata + + def add(self): + """ + Add the current metadata object to the database + """ + try: + Database.db_session.add(self) + Database.db_session.commit() + except Exception: + Database.db_session.rollback() + raise + + def update(self, **kwargs): + """ + Update the current user object with given keyword arguments + """ + try: + for key, value in kwargs.items(): + setattr(self, key, value) + Database.db_session.commit() + except Exception: + Database.db_session.rollback() + raise + + @staticmethod + def delete(id): + """ + Delete the metadata session with a given id + :param username: + :return: + """ + try: + metadata_query = Database.db_session.query(Metadata).filter_by(id=id) + metadata_query.delete() + Database.db_session.commit() + return True + except Exception: + Database.db_session.rollback() + raise diff --git a/lib/pbench/test/unit/server/test_metadata_sessions.py b/lib/pbench/test/unit/server/test_metadata_sessions.py new file mode 100644 index 0000000000..d408086fd7 --- /dev/null +++ b/lib/pbench/test/unit/server/test_metadata_sessions.py @@ -0,0 +1,223 @@ +import datetime +from lib.pbench.test.unit.server.test_user_auth import register_user, login_user + + +def user_register_login(client, server_config): + with client: + response = register_user( + client, + server_config, + username="user", + firstname="firstname", + lastname="lastName", + email="user@domain.com", + password="12345", + ) + data = response.json + assert data["message"] == "Successfully registered." + + response = login_user(client, server_config, "user", "12345") + data_login = response.json + assert data_login["auth_token"] + return data_login + + +class TestMetadataSession: + @staticmethod + def test_metadata_creation(client, server_config): + data_login = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config2", "description": "description2"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + + response = client.get( + f"{server_config.rest_uri}/metadata", + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["sessions"] + assert response.status_code == 200 + + @staticmethod + def test_unauthorized_metadata_creation(client, server_config): + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + ) + data = response.json + assert data is None + assert response.status_code == 401 + + @staticmethod + def test_single_metadata_query(client, server_config): + data_login = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["id"] + + metadata_id = data["data"]["id"] + response = client.get( + f"{server_config.rest_uri}/metadata/{metadata_id}", + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["config"] == "config1" + + @staticmethod + def test_unauthorized_metadata_query1(client, server_config): + # Test querying metadata without Pbench auth header + data_login = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["id"] + + metadata_id = data["data"]["id"] + response = client.get(f"{server_config.rest_uri}/metadata/{metadata_id}",) + assert response.status_code == 401 + + @staticmethod + def test_unauthorized_metadata_query2(client, server_config): + # Test querying someone else's metadata + data_login_1 = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login_1["auth_token"]), + ) + data_1 = response.json + assert data_1["message"] == "success" + assert data_1["data"]["id"] + + # Create another user and login + response = register_user( + client, + server_config, + username="user2", + firstname="firstname2", + lastname="lastName2", + email="user2@domain.com", + password="12345", + ) + data = response.json + assert data["message"] == "Successfully registered." + + response = login_user(client, server_config, "user2", "12345") + data_login_2 = response.json + assert data_login_2["auth_token"] + + # Create metadata session for 2nd user + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config2", "description": "description2"}, + headers=dict(Authorization="Bearer " + data_login_2["auth_token"]), + ) + data_2 = response.json + assert data_2["message"] == "success" + assert data_2["data"]["id"] + + # Query the metadata session 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}", + headers=dict(Authorization="Bearer " + data_login_2["auth_token"]), + ) + data = response.json + assert data["message"] == "Not authorized to perform the specified action" + assert response.status_code == 403 + + @staticmethod + def test_metadata_update(client, server_config): + data_login = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["id"] + + metadata_id = data["data"]["id"] + response = client.put( + f"{server_config.rest_uri}/metadata/{metadata_id}", + json={"description": "description2"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["description"] == "description2" + + @staticmethod + def test_metadata_update_with_invalid_fields(client, server_config): + data_login = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["id"] + + metadata_id = data["data"]["id"] + response = client.put( + f"{server_config.rest_uri}/metadata/{metadata_id}", + json={"created": datetime.datetime.now()}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "Invalid update request payload" + assert response.status_code == 403 + + @staticmethod + def test_metadata_delete(client, server_config): + data_login = user_register_login(client, server_config) + with client: + response = client.post( + f"{server_config.rest_uri}/metadata", + json={"config": "config1", "description": "description1"}, + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert data["data"]["id"] + + metadata_id = data["data"]["id"] + response = client.delete( + f"{server_config.rest_uri}/metadata/{metadata_id}", + headers=dict(Authorization="Bearer " + data_login["auth_token"]), + ) + data = response.json + assert data["message"] == "success" + assert response.status_code == 200 diff --git a/lib/pbench/test/unit/server/test_user_auth.py b/lib/pbench/test/unit/server/test_user_auth.py index 67fa101a84..52fb08cd5b 100644 --- a/lib/pbench/test/unit/server/test_user_auth.py +++ b/lib/pbench/test/unit/server/test_user_auth.py @@ -423,50 +423,3 @@ def test_delete_user(client, server_config): data = response.json assert data["message"] == "Successfully deleted." assert response.status_code == 200 - - -class TestMetadataSession: - @staticmethod - def test_metadata_creation(client, server_config): - """ Test for user registration """ - with client: - response = register_user( - client, - server_config, - username="user", - firstname="firstname", - lastname="lastName", - email="user@domain.com", - password="12345", - ) - data = response.json - assert data["status"] == "success" - - response = login_user(client, server_config, "user", "12345") - data_login = response.json - assert data_login["status"] == "success" - assert data_login["auth_token"] - - response = client.post( - f"{server_config.rest_uri}/metadata", - json={"config": "config1", "description": "description1"}, - headers=dict(Authorization="Bearer " + data_login["auth_token"]) - ) - data = response.json - assert data["status"] == "success" - - response = client.post( - f"{server_config.rest_uri}/metadata", - json={"config": "config2", "description": "description2"}, - headers=dict(Authorization="Bearer " + data_login["auth_token"]) - ) - data = response.json - assert data["status"] == "success" - - response = client.get( - f"{server_config.rest_uri}/metadata", - headers=dict(Authorization="Bearer " + data_login["auth_token"]) - ) - data = response.json - assert data["status"] == "success" - assert response.status_code == 200 \ No newline at end of file