From da84304778e2df6835f46bae4b7cd9f97ecf52b2 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Thu, 9 Feb 2023 14:00:38 +0300 Subject: oauth2: reorganise the endpoints. --- wqflask/wqflask/oauth2/checks.py | 2 +- wqflask/wqflask/oauth2/toplevel.py | 73 -------------------- wqflask/wqflask/oauth2/users.py | 100 ++++++++++++++++++++++++++-- wqflask/wqflask/templates/oauth2/login.html | 4 +- 4 files changed, 98 insertions(+), 81 deletions(-) diff --git a/wqflask/wqflask/oauth2/checks.py b/wqflask/wqflask/oauth2/checks.py index ccb2c3f7..e6859c4a 100644 --- a/wqflask/wqflask/oauth2/checks.py +++ b/wqflask/wqflask/oauth2/checks.py @@ -29,6 +29,6 @@ def require_oauth2(func): session.pop("user_details", None) flash("You need to be logged in.", "alert-warning") - return redirect(url_for("oauth2.toplevel.login", next=request.endpoint)) + return redirect(url_for("oauth2.user.login", next=request.endpoint)) return __token_valid__ diff --git a/wqflask/wqflask/oauth2/toplevel.py b/wqflask/wqflask/oauth2/toplevel.py index 72933861..1803ef85 100644 --- a/wqflask/wqflask/oauth2/toplevel.py +++ b/wqflask/wqflask/oauth2/toplevel.py @@ -12,81 +12,8 @@ from .checks import require_oauth2, user_logged_in toplevel = Blueprint("toplevel", __name__) -@toplevel.route("/login", methods=["GET", "POST"]) -def login(): - """Route to allow users to sign up.""" - next_endpoint=request.args.get("next", False) - if request.method == "POST": - form = request.form - client = oauth2_client() - config = app.config - try: - token = client.fetch_token( - urljoin(config["GN_SERVER_URL"], "oauth2/token"), - username=form.get("email_address"), - password=form.get("password"), - grant_type="password") - session["oauth2_token"] = token - except OAuthError as _oaerr: - flash(_oaerr.args[0], "alert-danger") - return render_template( - "oauth2/login.html", next_endpoint=next_endpoint, - email=form.get("email_address")) - if user_logged_in(): - if next_endpoint: - return redirect(url_for(next_endpoint)) - return redirect("/") - - return render_template("oauth2/login.html", next_endpoint=next_endpoint) - - -@toplevel.route("/logout", methods=["GET", "POST"]) -def logout(): - if user_logged_in(): - token = session.get("oauth2_token", False) - config = app.config - client = oauth2_client() - resp = client.revoke_token(urljoin(config["GN_SERVER_URL"], "oauth2/revoke")) - keys = tuple(key for key in session.keys() if not key.startswith("_")) - for key in keys: - session.pop(key, default=None) - - return redirect("/") - -@toplevel.route("/register-user", methods=["GET", "POST"]) -def register_user(): - if user_logged_in(): - next_endpoint=request.args.get("next", "/") - flash(("You cannot register a new user while logged in. " - "Please logout to register a new user."), - "alert-danger") - return redirect(next_endpoint) - - if request.method == "GET": - return render_template("oauth2/register_user.html") - - config = app.config - form = request.form - response = requests.post( - urljoin(config["GN_SERVER_URL"], "oauth2/user/register"), - data = { - "user_name": form.get("user_name"), - "email": form.get("email_address"), - "password": form.get("password"), - "confirm_password": form.get("confirm_password")}) - results = response.json() - if "error" in results: - error_messages = tuple( - f"{results['error']}: {msg.strip()}" - for msg in results.get("error_description").split("::")) - for message in error_messages: - flash(message, "alert-danger") - return redirect(url_for("oauth2.toplevel.register_user")) - - flash("Registration successful! Please login to continue.", "alert-success") - return redirect(url_for("oauth2.toplevel.login")) @toplevel.route("/register-client", methods=["GET", "POST"]) @require_oauth2 diff --git a/wqflask/wqflask/oauth2/users.py b/wqflask/wqflask/oauth2/users.py index 67d6b27f..94c3a4ce 100644 --- a/wqflask/wqflask/oauth2/users.py +++ b/wqflask/wqflask/oauth2/users.py @@ -1,7 +1,12 @@ +import requests +from urllib.parse import urljoin + +from authlib.integrations.base_client.errors import OAuthError from flask import ( - flash, request, url_for, redirect, Response, Blueprint, render_template) + flash, request, session, url_for, redirect, Response, Blueprint, + render_template, current_app as app) -from .checks import require_oauth2 +from .checks import require_oauth2, user_logged_in from .client import oauth2_get, oauth2_post, oauth2_client from .request_utils import user_details, request_error, process_error @@ -13,10 +18,20 @@ def user_profile(): __id__ = lambda the_val: the_val usr_dets = user_details() client = oauth2_client() + def __render__(usr_dets, roles=[], **kwargs): + return render_template( + "oauth2/view-user.html", user_details=usr_dets, roles=roles, + **kwargs) + + def __roles_success__(roles): + return oauth2_get("oauth2/user/group/join-request").either( + lambda err: __render__( + user_details, group_join_error=process_error(err)), + lambda gjr: __render__(user_details, group_join_request=gjr)) - roles = oauth2_get("oauth2/user/roles").either(lambda x: "Error", lambda x: x) - return render_template( - "oauth2/view-user.html", user_details=usr_dets, roles=roles) + return oauth2_get("oauth2/user/roles").either( + lambda err: __render__(user_details, role_error=process_error(err)), + __roles_success__) @users.route("/request-add-to-group", methods=["POST"]) @require_oauth2 @@ -37,3 +52,78 @@ def request_add_to_group() -> Response: return oauth2_post(f"oauth2/group/requests/join/{group_id}", data=form).either(__error__, __success__) + +@users.route("/login", methods=["GET", "POST"]) +def login(): + """Route to allow users to sign up.""" + next_endpoint=request.args.get("next", False) + + if request.method == "POST": + form = request.form + client = oauth2_client() + config = app.config + try: + token = client.fetch_token( + urljoin(config["GN_SERVER_URL"], "oauth2/token"), + username=form.get("email_address"), + password=form.get("password"), + grant_type="password") + session["oauth2_token"] = token + except OAuthError as _oaerr: + flash(_oaerr.args[0], "alert-danger") + return render_template( + "oauth2/login.html", next_endpoint=next_endpoint, + email=form.get("email_address")) + + if user_logged_in(): + if next_endpoint: + return redirect(url_for(next_endpoint)) + return redirect("/") + + return render_template("oauth2/login.html", next_endpoint=next_endpoint) + +@users.route("/logout", methods=["GET", "POST"]) +def logout(): + if user_logged_in(): + token = session.get("oauth2_token", False) + config = app.config + client = oauth2_client() + resp = client.revoke_token(urljoin(config["GN_SERVER_URL"], "oauth2/revoke")) + keys = tuple(key for key in session.keys() if not key.startswith("_")) + for key in keys: + session.pop(key, default=None) + + return redirect("/") + +@users.route("/register", methods=["GET", "POST"]) +def register_user(): + if user_logged_in(): + next_endpoint=request.args.get("next", "/") + flash(("You cannot register a new user while logged in. " + "Please logout to register a new user."), + "alert-danger") + return redirect(next_endpoint) + + if request.method == "GET": + return render_template("oauth2/register_user.html") + + config = app.config + form = request.form + response = requests.post( + urljoin(config["GN_SERVER_URL"], "oauth2/user/register"), + data = { + "user_name": form.get("user_name"), + "email": form.get("email_address"), + "password": form.get("password"), + "confirm_password": form.get("confirm_password")}) + results = response.json() + if "error" in results: + error_messages = tuple( + f"{results['error']}: {msg.strip()}" + for msg in results.get("error_description").split("::")) + for message in error_messages: + flash(message, "alert-danger") + return redirect(url_for("oauth2.user.register_user")) + + flash("Registration successful! Please login to continue.", "alert-success") + return redirect(url_for("oauth2.user.login")) diff --git a/wqflask/wqflask/templates/oauth2/login.html b/wqflask/wqflask/templates/oauth2/login.html index d3e0a4d8..eaa1a192 100644 --- a/wqflask/wqflask/templates/oauth2/login.html +++ b/wqflask/wqflask/templates/oauth2/login.html @@ -6,9 +6,9 @@