diff options
Diffstat (limited to 'gn2/wqflask/oauth2')
-rw-r--r-- | gn2/wqflask/oauth2/request_utils.py | 3 | ||||
-rw-r--r-- | gn2/wqflask/oauth2/toplevel.py | 65 |
2 files changed, 47 insertions, 21 deletions
diff --git a/gn2/wqflask/oauth2/request_utils.py b/gn2/wqflask/oauth2/request_utils.py index a453d18e..1cdc465f 100644 --- a/gn2/wqflask/oauth2/request_utils.py +++ b/gn2/wqflask/oauth2/request_utils.py @@ -35,7 +35,8 @@ def process_error(error: Response, if error.status_code in range(400, 500): try: err = error.json() - msg = err.get("error_description", f"{error.reason}") + msg = err.get( + "error", err.get("error_description", f"{error.reason}")) except simplejson.errors.JSONDecodeError as _jde: msg = message return { diff --git a/gn2/wqflask/oauth2/toplevel.py b/gn2/wqflask/oauth2/toplevel.py index dffc0a7c..23965cc1 100644 --- a/gn2/wqflask/oauth2/toplevel.py +++ b/gn2/wqflask/oauth2/toplevel.py @@ -1,14 +1,18 @@ """Authentication endpoints.""" -from uuid import UUID +import uuid +import datetime from urllib.parse import urljoin, urlparse, urlunparse + +from authlib.jose import jwt from flask import ( flash, request, Blueprint, url_for, redirect, render_template, current_app as app) from . import session -from .client import SCOPE, no_token_post, user_logged_in from .checks import require_oauth2 from .request_utils import user_details, process_error +from .client import ( + SCOPE, no_token_post, user_logged_in, authserver_uri, oauth2_clientid) toplevel = Blueprint("toplevel", __name__) @@ -18,38 +22,59 @@ def register_client(): """Register an OAuth2 client.""" return "USER IS LOGGED IN AND SUCCESSFULLY ACCESSED THIS ENDPOINT!" + @toplevel.route("/code", methods=["GET"]) def authorisation_code(): """Use authorisation code to get token.""" - def __error__(error): - flash(f"{error['error']}: {error['error_description']}", - "alert-danger") - return redirect("/") - - def __success__(token): - session.set_user_token(token) - udets = user_details() - session.set_user_details({ - "user_id": UUID(udets["user_id"]), - "name": udets["name"], - "email": udets["email"], - "token": session.user_token(), - "logged_in": True - }) - return redirect("/") - code = request.args.get("code", "") if bool(code): base_url = urlparse(request.base_url, scheme=request.scheme) + jwtkey = app.config["SSL_PRIVATE_KEY"] + issued = datetime.datetime.now() request_data = { - "grant_type": "authorization_code", + "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "code": code, "scope": SCOPE, "redirect_uri": urljoin( urlunparse(base_url), url_for("oauth2.toplevel.authorisation_code")), + "assertion": jwt.encode( + header={ + "alg": "RS256", + "typ": "jwt", + "kid": jwtkey.as_dict()["kid"]}, + payload={ + "iss": str(oauth2_clientid()), + "sub": request.args["user_id"], + "aud": urljoin(authserver_uri(), "auth/token"), + "exp": (issued + datetime.timedelta(minutes=5)), + "nbf": int(issued.timestamp()), + "iat": int(issued.timestamp()), + "jti": str(uuid.uuid4())}, + key=jwtkey).decode("utf8"), "client_id": app.config["OAUTH2_CLIENT_ID"] } + + def __error__(error): + flash(f"{error['error']}: {error['error_description']}", + "alert-danger") + app.logger.debug("Request error (%s) %s: %s", + error["status_code"], error["error_description"], + request_data) + return redirect("/") + + def __success__(token): + session.set_user_token(token) + udets = user_details() + session.set_user_details({ + "user_id": uuid.UUID(udets["user_id"]), + "name": udets["name"], + "email": udets["email"], + "token": session.user_token(), + "logged_in": True + }) + return redirect("/") + return no_token_post( "auth/token", data=request_data).either( lambda err: __error__(process_error(err)), __success__) |