about summary refs log tree commit diff
path: root/gn_auth/auth/authentication/oauth2/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'gn_auth/auth/authentication/oauth2/views.py')
-rw-r--r--gn_auth/auth/authentication/oauth2/views.py29
1 files changed, 26 insertions, 3 deletions
diff --git a/gn_auth/auth/authentication/oauth2/views.py b/gn_auth/auth/authentication/oauth2/views.py
index 22437a2..0e2c4eb 100644
--- a/gn_auth/auth/authentication/oauth2/views.py
+++ b/gn_auth/auth/authentication/oauth2/views.py
@@ -9,6 +9,7 @@ from flask import (
     flash,
     request,
     url_for,
+    jsonify,
     redirect,
     Response,
     Blueprint,
@@ -17,6 +18,7 @@ from flask import (
 
 from gn_auth.auth.db import sqlite3 as db
 from gn_auth.auth.db.sqlite3 import with_db_connection
+from gn_auth.auth.jwks import jwks_directory, list_jwks
 from gn_auth.auth.errors import NotFoundError, ForbiddenAccess
 from gn_auth.auth.authentication.users import valid_login, user_by_email
 
@@ -45,6 +47,14 @@ def authorise():
             flash("Invalid OAuth2 client.", "alert-danger")
 
         if request.method == "GET":
+            def __forgot_password_table_exists__(conn):
+                with db.cursor(conn) as cursor:
+                    cursor.execute("SELECT name FROM sqlite_master "
+                                   "WHERE type='table' "
+                                   "AND name='forgot_password_tokens'")
+                    return bool(cursor.fetchone())
+                return False
+
             client = server.query_client(request.args.get("client_id"))
             _src = urlparse(request.args["redirect_uri"])
             return render_template(
@@ -53,7 +63,9 @@ def authorise():
                 scope=client.scope,
                 response_type=request.args["response_type"],
                 redirect_uri=request.args["redirect_uri"],
-                source_uri=f"{_src.scheme}://{_src.netloc}/")
+                source_uri=f"{_src.scheme}://{_src.netloc}/",
+                display_forgot_password=with_db_connection(
+                    __forgot_password_table_exists__))
 
         form = request.form
         def __authorise__(conn: db.DbConnection):
@@ -65,14 +77,15 @@ def authorise():
             try:
                 email = validate_email(
                     form.get("user:email"), check_deliverability=False)
-                user = user_by_email(conn, email["email"])
+                user = user_by_email(conn, email["email"])  # type: ignore
                 if valid_login(conn, user, form.get("user:password", "")):
                     if not user.verified:
                         return redirect(
                             url_for("oauth2.users.handle_unverified",
                                     response_type=form["response_type"],
                                     client_id=client_id,
-                                    redirect_uri=form["redirect_uri"]),
+                                    redirect_uri=form["redirect_uri"],
+                                    email=email["email"]),
                             code=307)
                     return server.create_authorization_response(request=request, grant_user=user)
                 flash(email_passwd_msg, "alert-danger")
@@ -116,3 +129,13 @@ def introspect_token() -> Response:
                 IntrospectionEndpoint.ENDPOINT_NAME)
 
     raise ForbiddenAccess("You cannot access this endpoint")
+
+
+@auth.route("/public-jwks", methods=["GET"])
+def public_jwks():
+    """Provide the JWK public keys used by this application."""
+    return jsonify({
+        "documentation": (
+            "The keys are listed in order of creation, from the oldest (first) "
+            "to the newest (last)."),
+        "jwks": tuple(key.as_dict() for key in list_jwks(jwks_directory(app)))})