diff --git a/inventory_provider/auth.py b/inventory_provider/auth.py index ba5ef9b6f290a5201a804bfe61188b6306f38ac0..1dd8ff81ef56049673223f08c3e1f327376ee8a8 100644 --- a/inventory_provider/auth.py +++ b/inventory_provider/auth.py @@ -1,7 +1,8 @@ +from functools import wraps from flask import current_app, g, jsonify from flask_httpauth import HTTPTokenAuth -from functools import wraps -from config import ANONYMOUS_SERVICE_NAME + +from inventory_provider.config import ANONYMOUS_SERVICE_NAME auth = HTTPTokenAuth(scheme="ApiKey") @@ -28,17 +29,11 @@ def authorize(*, allowed_clients): @wraps(f) def wrapped(*args, **kwargs): client = g.get("auth_client") - - if not client: - return jsonify({"error": "Unauthorized"}), 403 - if client not in allowed_clients: # Anonymous clients are allowed to access any resource without providing an API key # TODO: Only for testing, should be removed in Production if client != ANONYMOUS_SERVICE_NAME: return jsonify({"error": "Forbidden"}), 403 - return f(*args, **kwargs) - return wrapped - return decorator \ No newline at end of file + return decorator diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index 8b65079be836dc04318a21db74fe1803e4bb9db6..018df7f53f12ef9372bf56e92ae0af0b26ca5288 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -67,7 +67,8 @@ from redis import Redis from inventory_provider.routes import common from inventory_provider.routes.common import _ignore_cache_or_retrieve, cache_result -from inventory_provider.config import authorize, DASHBOARD_SERVICE_NAME +from inventory_provider.auth import authorize +from inventory_provider.config import DASHBOARD_SERVICE_NAME routes = Blueprint("inventory-data-classifier-support-routes", __name__) diff --git a/test/conftest.py b/test/conftest.py index 1c276b4c89fe5deec9bf787715799dd3b076d160..354126826574b8ce6c4227c458b0a22322429e29 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -70,6 +70,17 @@ def data_config_filename(): with tempfile.NamedTemporaryFile() as f: config = { + "api-keys": { + "brian": { + "api-key": "brian_key" + }, + "dashboard": { + "api-key": "dashboard_key" + }, + "reporting": { + "api-key": "reporting_key" + }, + }, "ssh": { "username": "uSeR-NaMe", "private-key": "private-key-filename", diff --git a/test/test_auth.py b/test/test_auth.py new file mode 100644 index 0000000000000000000000000000000000000000..226ab7a5009b2df1dd187ef14bafca01c276c7d2 --- /dev/null +++ b/test/test_auth.py @@ -0,0 +1,75 @@ +import jsonschema + +from inventory_provider.routes.classifier_schema import ( + ROUTER_INFO_ALL_ROUTERS_RESPONSE_SCHEMA, +) + +DEFAULT_REQUEST_HEADERS_NO_KEY = { + "Content-type": "application/json", + "Accept": ["application/json"], +} + +DEFAULT_REQUEST_HEADERS_BRIAN_KEY = { + "Content-type": "application/json", + "Accept": ["application/json"], + "Authorization": "ApiKey brian_key", +} + +DEFAULT_REQUEST_HEADERS_REPORTING_KEY = { + "Content-type": "application/json", + "Accept": ["application/json"], + "Authorization": "ApiKey reporting_key", +} + +DEFAULT_REQUEST_HEADERS_DASHBOARD_KEY = { + "Content-type": "application/json", + "Accept": ["application/json"], + "Authorization": "ApiKey dashboard_key", +} + +DEFAULT_REQUEST_HEADERS_BAD_KEY = { + "Content-type": "application/json", + "Accept": ["application/json"], + "Authorization": "ApiKey badapikey", +} + +def test_classifier_router_no_key(client): + rv = client.get("/classifier/router-info", headers=DEFAULT_REQUEST_HEADERS_NO_KEY) + assert rv.status_code == 200 + assert rv.is_json + result = rv.json + + jsonschema.validate(result, ROUTER_INFO_ALL_ROUTERS_RESPONSE_SCHEMA) + assert len(result) > 0 + +def test_classifier_router_dashboard_key(client): + rv = client.get("/classifier/router-info", headers=DEFAULT_REQUEST_HEADERS_DASHBOARD_KEY) + assert rv.status_code == 200 + assert rv.is_json + result = rv.json + + jsonschema.validate(result, ROUTER_INFO_ALL_ROUTERS_RESPONSE_SCHEMA) + assert len(result) > 0 + +def test_classifier_router_brian_key(client): + rv = client.get("/classifier/router-info", headers=DEFAULT_REQUEST_HEADERS_BRIAN_KEY) + assert rv.status_code == 403 + assert rv.is_json + result = rv.json + + assert result["error"] == "Forbidden" + +def test_classifier_router_reporting_key(client): + rv = client.get("/classifier/router-info", headers=DEFAULT_REQUEST_HEADERS_REPORTING_KEY) + assert rv.status_code == 403 + assert rv.is_json + result = rv.json + + assert result["error"] == "Forbidden" + +def test_classifier_router_bad_key(client): + rv = client.get("/classifier/router-info", headers=DEFAULT_REQUEST_HEADERS_BAD_KEY) + assert rv.status_code == 401 + result = rv.text + + assert result == "Unauthorized Access" diff --git a/test/test_flask_config.py b/test/test_flask_config.py index 7ba83ec54c3e2e8389924e14b3cff0bad6aea29b..48f7e29c2ab998319c33894d7f11a27efe737449 100644 --- a/test/test_flask_config.py +++ b/test/test_flask_config.py @@ -7,6 +7,17 @@ from inventory_provider.config import CONFIG_SCHEMA @pytest.fixture def config(): return { + "api-keys": { + "brian": { + "api-key": "brian_key" + }, + "dashboard": { + "api-key": "dashboard_key" + }, + "reporting": { + "api-key": "reporting_key" + }, + }, 'redis': { 'hostname': 'localhost', 'port': 6379,