aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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%}