From 45f2eaa9d2965c79d77c898aab3a01a1f06e4149 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Thu, 3 Oct 2024 11:37:49 -0500 Subject: Provide a way to change OAuth2 client secrets. --- .../authentication/oauth2/models/oauth2client.py | 23 ++++++++++- gn_auth/auth/authorisation/users/admin/views.py | 34 ++++++++++++++++ .../admin/confirm-change-client-secret.html | 45 ++++++++++++++++++++++ gn_auth/templates/admin/list-oauth2-clients.html | 10 ++++- 4 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 gn_auth/templates/admin/confirm-change-client-secret.html diff --git a/gn_auth/auth/authentication/oauth2/models/oauth2client.py b/gn_auth/auth/authentication/oauth2/models/oauth2client.py index 8fac648..2c36f45 100644 --- a/gn_auth/auth/authentication/oauth2/models/oauth2client.py +++ b/gn_auth/auth/authentication/oauth2/models/oauth2client.py @@ -3,9 +3,9 @@ import json import logging import datetime from uuid import UUID -from dataclasses import dataclass from functools import cached_property -from typing import Sequence, Optional +from dataclasses import asdict, dataclass +from typing import Any, Sequence, Optional import requests from requests.exceptions import JSONDecodeError @@ -289,3 +289,22 @@ def delete_client( cursor.execute("DELETE FROM oauth2_tokens WHERE client_id=?", params) cursor.execute("DELETE FROM oauth2_clients WHERE client_id=?", params) return the_client + + +def update_client_attribute( + client: OAuth2Client, attribute: str, value: Any) -> OAuth2Client: + """Return a new OAuth2Client with the given attribute updated/changed.""" + attrs = { + attr: type(value) + for attr, value in asdict(client).items() + if attr != "client_id" + } + assert ( + attribute in attrs.keys() and isinstance(value, attrs[attribute])), ( + "Invalid attribute/value provided!") + return OAuth2Client( + client_id=client.client_id, + **{ + attr: (value if attr==attribute else getattr(client, attr)) + for attr in attrs + }) diff --git a/gn_auth/auth/authorisation/users/admin/views.py b/gn_auth/auth/authorisation/users/admin/views.py index 85aeb50..1dd2f1f 100644 --- a/gn_auth/auth/authorisation/users/admin/views.py +++ b/gn_auth/auth/authorisation/users/admin/views.py @@ -30,6 +30,7 @@ from ....authentication.oauth2.models.oauth2client import ( save_client, OAuth2Client, oauth2_clients, + update_client_attribute, client as oauth2_client, delete_client as _delete_client) from ....authentication.users import ( @@ -321,3 +322,36 @@ def delete_client(): "successfully."), "alert-success") return redirect(url_for("oauth2.admin.list_clients")) + + +@admin.route("/clients//change-secret", methods=["GET", "POST"]) +@is_admin +def change_client_secret(client_id: uuid.UUID): + def __no_client__(): + # Calling the function causes the flash to be evaluated + # flash("No such client was found!", "alert-danger") + return redirect(url_for("oauth2.admin.list_clients")) + + with db.connection(app.config["AUTH_DB"]) as conn: + if request.method == "GET": + return oauth2_client( + conn, client_id=client_id + ).maybe(__no_client__(), lambda _client: render_template( + "admin/confirm-change-client-secret.html", + client=_client + )) + + _raw = random_string() + return oauth2_client( + conn, client_id=client_id + ).then( + lambda _client: save_client( + conn, + update_client_attribute( + _client, "client_secret", hash_password(_raw))) + ).then( + lambda _client: render_template( + "admin/registered-client.html", + client=_client, + client_secret=_raw) + ).maybe(__no_client__(), lambda resp: resp) diff --git a/gn_auth/templates/admin/confirm-change-client-secret.html b/gn_auth/templates/admin/confirm-change-client-secret.html new file mode 100644 index 0000000..aa8ef81 --- /dev/null +++ b/gn_auth/templates/admin/confirm-change-client-secret.html @@ -0,0 +1,45 @@ +{%extends "base.html"%} + +{%block title%}gn-auth: View OAuth2 Client{%endblock%} + +{%block pagetitle%}View OAuth2 Client{%endblock%} + +{%block content%} +{{flash_messages()}} + +

Change Oauth2 Client Secret

+ +

You are attempting to change the CLIENT_SECRET value for the + following client:

+ + + + + + + + + + + + +
Client ID{{client.client_id}}
Client Name{{client.client_metadata.client_name}}
+ +

Are you absolutely sure you want to do this?
+ Note that you'll need to update your configurations for the client and + restart it for the settings to take effect!

+ +
+ + + + +
+ +
+
+ +{%endblock%} diff --git a/gn_auth/templates/admin/list-oauth2-clients.html b/gn_auth/templates/admin/list-oauth2-clients.html index ca0ee6d..6da5b2f 100644 --- a/gn_auth/templates/admin/list-oauth2-clients.html +++ b/gn_auth/templates/admin/list-oauth2-clients.html @@ -15,7 +15,7 @@ Client Name Default Redirect URI Owner - Actions + Actions @@ -43,6 +43,14 @@ class="btn btn-danger" /> + + + Change Secret + + {%else%} -- cgit v1.2.3