diff options
author | Frederick Muriuki Muriithi | 2024-05-02 07:50:14 +0300 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-05-02 07:50:14 +0300 |
commit | dcfafd9805cf588c9da201333789157713dae7af (patch) | |
tree | 9de4de1f3eb124fef6e831e5af5ca2d03e2ee0a9 | |
parent | 77a58474da1b3827b3683b0195bc7cbacddbaf4a (diff) | |
download | gn-auth-dcfafd9805cf588c9da201333789157713dae7af.tar.gz |
Register a client's public key(s).
-rw-r--r-- | gn_auth/auth/authorisation/users/admin/views.py | 57 | ||||
-rw-r--r-- | gn_auth/templates/admin/view-oauth2-client.html | 58 |
2 files changed, 114 insertions, 1 deletions
diff --git a/gn_auth/auth/authorisation/users/admin/views.py b/gn_auth/auth/authorisation/users/admin/views.py index b0bb2db..3aadf49 100644 --- a/gn_auth/auth/authorisation/users/admin/views.py +++ b/gn_auth/auth/authorisation/users/admin/views.py @@ -3,12 +3,14 @@ import uuid import json import random import string +from pathlib import Path from typing import Optional from functools import partial from dataclasses import asdict from urllib.parse import urlparse from datetime import datetime, timezone, timedelta +from authlib.jose import JsonWebKey from email_validator import validate_email, EmailNotValidError from flask import ( flash, @@ -17,7 +19,8 @@ from flask import ( redirect, Blueprint, current_app, - render_template) + render_template, + current_app as app) from gn_auth import session @@ -259,6 +262,58 @@ def view_client(client_id: uuid.UUID): scope=current_app.config["OAUTH2_SCOPE"], granttypes=_FORM_GRANT_TYPES_) +@admin.route("/register-client-public-key", methods=["POST"]) +@is_admin +def register_client_public_key(): + """Register a client's SSL key""" + form = request.form + admin_dashboard_uri = redirect(url_for("oauth2.admin.dashboard")) + view_client_uri = redirect(url_for("oauth2.admin.view_client", + client_id=form["client_id"])) + if not bool(form.get("client_id")): + flash("No client selected.", "alert-danger") + return admin_dashboard_uri + + try: + _client = with_db_connection(partial( + oauth2_client, client_id=uuid.UUID(form["client_id"]))) + if _client.is_nothing(): + raise ValueError("No such client.") + _client = _client.value + except ValueError: + flash("Invalid client ID provided.", "alert-danger") + return admin_dashboard_uri + try: + _key = JsonWebKey.import_key(form["client_ssl_key"].strip()) + except ValueError: + flash("Invalid key provided!", "alert-danger") + return view_client_uri + + keypath = Path(app.config["CLIENTS_SSL_PUBLIC_KEYS_DIR"]).joinpath( + f"{_key.thumbprint()}.pem") + if not keypath.exists(): + with open(keypath, mode="w", encoding="utf8") as _kpth: + _kpth.write(form["client_ssl_key"]) + + from gn_auth.debug import __pk__ + with_db_connection(partial(save_client, the_client=OAuth2Client( + client_id=_client.client_id, + client_secret=_client.client_secret, + client_id_issued_at=_client.client_id_issued_at, + client_secret_expires_at=_client.client_secret_expires_at, + client_metadata={ + **_client.client_metadata, + "public_keys": list(set( + _client.client_metadata.get("public_keys", []) + + [str(keypath)]))}, + user=_client.user))) + flash("Client key successfully registered.", "alert-success") + return view_client_uri + + flash("Client key already exists.", "alert-warning") + return view_client_uri + + @admin.route("/edit-client", methods=["POST"]) @is_admin def edit_client(): diff --git a/gn_auth/templates/admin/view-oauth2-client.html b/gn_auth/templates/admin/view-oauth2-client.html index 97993e8..38e48c7 100644 --- a/gn_auth/templates/admin/view-oauth2-client.html +++ b/gn_auth/templates/admin/view-oauth2-client.html @@ -67,5 +67,63 @@ <input type="submit" value="update client" /> </form> + +<hr /> +<h2>Signing/Verification SSL Keys</h2> +<table> + <caption>Registered Public Keys</caption> + <thead> + <tr> + <th>JWK Thumbprint</th> + <th>Actions</th> + </tr> + </thead> + + <tbody> + {%for sslkey in client.jwks.keys:%} + <tr> + <td>{{sslkey.thumbprint()}}</td> + <td> + <form> + <input type="hidden" + name="client_id" + value="{{client.client_id}}" /> + <input type="hidden" + name="ssl_key" + value="{{sslkey.thumbprint()}}" /> + <input type="submit" + class="btn btn-danger" + value="delete key" /> + </form> + </td> + </tr> + {%else%} + <tr> + <td class="alert-warning" + colspan="2"> + There are no registered SSL keys for this client. + </td> + </tr> + {%endfor%} + </tbody> +</table> +<form id="frm-client-add-ssl-key" + method="POST" + action="{{url_for('oauth2.admin.register_client_public_key')}}"> + <legend>Register new SSL key</legend> + <input type="hidden" name="client_id" value="{{client.client_id}}" /> + <fieldset> + <label for="txt-area-client-ssl-key">Client's Public Key</label> + <textarea id="txt-area-client-ssl-key" + name="client_ssl_key" + required="required" + class="form-control" + rows="10"></textarea> + </fieldset> + + <br /> + <input type="submit" class="btn btn-primary" value="register key" /> +</form> + {%endif%} {%endblock%} |