aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-10-03 11:37:49 -0500
committerFrederick Muriuki Muriithi2024-10-03 11:37:49 -0500
commit45f2eaa9d2965c79d77c898aab3a01a1f06e4149 (patch)
tree5b5945e81091c68d9f861c71ac8af3da8a05b4e3
parentb9de9e436dd4f84174f6fc1b707e1b303a94fcf4 (diff)
downloadgn-auth-45f2eaa9d2965c79d77c898aab3a01a1f06e4149.tar.gz
Provide a way to change OAuth2 client secrets.
-rw-r--r--gn_auth/auth/authentication/oauth2/models/oauth2client.py23
-rw-r--r--gn_auth/auth/authorisation/users/admin/views.py34
-rw-r--r--gn_auth/templates/admin/confirm-change-client-secret.html45
-rw-r--r--gn_auth/templates/admin/list-oauth2-clients.html10
4 files changed, 109 insertions, 3 deletions
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/<uuid:client_id>/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()}}
+
+<h2>Change Oauth2 Client Secret</h2>
+
+<p>You are attempting to change the <strong>CLIENT_SECRET</strong> value for the
+ following client:</p>
+
+<table class="table">
+ <tbody>
+ <tr>
+ <td><strong>Client ID</strong></td>
+ <td>{{client.client_id}}</td>
+ </tr>
+ <tr>
+ <td><strong>Client Name</strong></td>
+ <td>{{client.client_metadata.client_name}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Are you absolutely sure you want to do this?<br />
+ <small>Note that you'll need to update your configurations for the client and
+ restart it for the settings to take effect!</small></p>
+
+<form id="frm-change-client-secret"
+ method="POST"
+ action="{{url_for('oauth2.admin.change_client_secret',
+ client_id=client.client_id)}}">
+
+ <input type="hidden" name="client_id" value="{{client.client_id}}" />
+ <input type="hidden" name="client_name" value="{{client.client_metadata.client_name}}" />
+
+ <div class="form-group">
+ <input type="submit" class="btn btn-danger" value="generate new secret" />
+ </div>
+</form>
+
+{%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 @@
<th>Client Name</th>
<th>Default Redirect URI</th>
<th>Owner</th>
- <th colspan="2">Actions</th>
+ <th colspan="3">Actions</th>
</tr>
</thead>
@@ -43,6 +43,14 @@
class="btn btn-danger" />
</form>
</td>
+ <td>
+ <a href="{{url_for('oauth2.admin.change_client_secret',
+ client_id=client.client_id)}}"
+ title="Change the client secret!"
+ class="btn btn-danger">
+ Change Secret
+ </a>
+ </td>
</tr>
{%else%}
<tr>