about summary refs log tree commit diff
path: root/gn_auth
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-05-02 07:50:14 +0300
committerFrederick Muriuki Muriithi2024-05-02 07:50:14 +0300
commitdcfafd9805cf588c9da201333789157713dae7af (patch)
tree9de4de1f3eb124fef6e831e5af5ca2d03e2ee0a9 /gn_auth
parent77a58474da1b3827b3683b0195bc7cbacddbaf4a (diff)
downloadgn-auth-dcfafd9805cf588c9da201333789157713dae7af.tar.gz
Register a client's public key(s).
Diffstat (limited to 'gn_auth')
-rw-r--r--gn_auth/auth/authorisation/users/admin/views.py57
-rw-r--r--gn_auth/templates/admin/view-oauth2-client.html58
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%}