diff --git a/resultsdb/__init__.py b/resultsdb/__init__.py index e5e7275..4c67efc 100644 --- a/resultsdb/__init__.py +++ b/resultsdb/__init__.py @@ -30,7 +30,7 @@ from resultsdb.models import db from . import config -import flask +from flask import Flask, jsonify, redirect, url_for # the version as used in setup.py @@ -43,7 +43,7 @@ def create_app(config_obj=None): - app = flask.Flask(__name__) + app = Flask(__name__) app.secret_key = "replace-me-with-something-random" # make sure app behaves when behind a proxy @@ -98,6 +98,12 @@ def create_app(config_obj=None): register_handlers(app) register_blueprints(app) + if app.config["AUTH_MODULE"] == "oidc": + app.logger.info("OpenIDConnect authentication is enabled") + enable_oidc(app) + else: + app.logger.info("OpenIDConnect authentication is disabled") + app.logger.debug("Finished ResultsDB initialization") return app @@ -156,11 +162,11 @@ def register_handlers(app): # TODO: find out why error handler works for 404 but not for 400 @app.errorhandler(400) def bad_request(error): - return flask.jsonify({"message": "Bad request"}), 400 + return jsonify({"message": "Bad request"}), 400 @app.errorhandler(404) def not_found(error): - return flask.jsonify({"message": "Not found"}), 404 + return jsonify({"message": "Not found"}), 404 def register_blueprints(app): @@ -168,18 +174,24 @@ def register_blueprints(app): app.register_blueprint(api_v2, url_prefix="/api/v2.0") app.register_blueprint(api_v3, url_prefix="/api/v3") - if app.config["AUTH_MODULE"] == "oidc": - @app.route("/auth/oidclogin") - @oidc.require_login - def login(): - return { +def enable_oidc(app): + @app.route("/auth/profile") + @oidc.require_login + def user_info(): + return jsonify( + { "username": oidc.user_getfield(app.config["OIDC_USERNAME_FIELD"]), "token": oidc.get_access_token(), + "access_token": oidc.get_access_token(), + "refresh_token": oidc.get_refresh_token(), } + ) - oidc.init_app(app) - app.oidc = oidc - app.logger.info("OpenIDConnect authentication is enabled") - else: - app.logger.info("OpenIDConnect authentication is disabled") + @app.route("/auth/oidclogin") + @oidc.require_login + def login(): + return redirect(url_for("user_info")) + + oidc.init_app(app) + app.oidc = oidc diff --git a/resultsdb/controllers/api_v3.py b/resultsdb/controllers/api_v3.py index 0e2d2ed..5279df6 100644 --- a/resultsdb/controllers/api_v3.py +++ b/resultsdb/controllers/api_v3.py @@ -73,6 +73,11 @@ def create_endpoint(params_class): def create(body: params_class): return create_result(body) + @oidc.require_login + @validate() + def create_with_login(body: params_class): + return create_result(body) + def get_schema(): return jsonify(params.construct().schema()), 200 @@ -83,6 +88,12 @@ def get_schema(): methods=["POST"], view_func=create, ) + api.add_url_rule( + f"/oidc/results/{artifact_type}s", + endpoint=f"oidc_results_{artifact_type}s", + methods=["POST"], + view_func=create_with_login, + ) api.add_url_rule( f"/schemas/{artifact_type}s", endpoint=f"schemas_{artifact_type}s", diff --git a/testing/test_api_v3.py b/testing/test_api_v3.py index e2f2188..cceb248 100644 --- a/testing/test_api_v3.py +++ b/testing/test_api_v3.py @@ -4,10 +4,18 @@ import flask import pytest +from resultsdb.models import db from resultsdb.parsers.api_v3 import RESULTS_PARAMS_CLASSES from resultsdb.controllers.api_v3 import oidc +@pytest.fixture(scope="function", autouse=True) +def db_session(): + db.session.rollback() + db.drop_all() + db.create_all() + + @pytest.fixture(autouse=True) def mock_ldap(): with patch("ldap.initialize") as ldap_init: @@ -133,7 +141,7 @@ def test_api_v3_create_redhat_container_image(client): assert r.json["testcase"] == { "href": "http://localhost/api/v2.0/testcases/testcase1", "name": "testcase1", - "ref_url": "https://test.example.com/docs/testcase1", + "ref_url": None, } assert r.json["data"]["item"] == [data["item"]] assert r.json["data"]["type"] == ["redhat-container-image"]