Skip to content

Commit

Permalink
Allow basic management of applications
Browse files Browse the repository at this point in the history
  • Loading branch information
OllieJC committed Feb 16, 2024
1 parent fe11b7a commit 36ab729
Show file tree
Hide file tree
Showing 5 changed files with 416 additions and 112 deletions.
60 changes: 43 additions & 17 deletions sso_oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,36 @@
_individual_clients = {}


def save_client(filename: str, client: dict, client_id: str) -> dict:
has_secret = False
saved = False

if not filename or not client or not client_id:
return False

try:
for client_item in list(client.keys()):
if client_item.startswith("_"):
client.pop(client_item, None)
if client_item == "secret":
has_secret = True

if has_secret:
saving_dict = {client_id: client}
as_json = json.dumps(saving_dict, default=str)
saved = write_file(
filename=filename, content=as_json, bucket_type="clients"
)

except Exception as e:
jprint({"function": "save_client", "filename": filename, "error": str(e)})

if saved:
reset_individual_clients()

return saved


def get_clients() -> dict:
res = {}

Expand All @@ -35,23 +65,13 @@ def get_clients() -> dict:
fc = from_files[fn]
if fc and fc.startswith("{"):
try:
res.update(json.loads(fc))
jc = json.loads(fc)
for jcc in jc:
jc[jcc]["_filename"] = fn
res.update(jc)
except Exception as e:
jprint({"function": "get_clients", "file": fn, "error": str(e)})

from_env = env_var("OAUTH_CLIENTS_JSON_OBJECT")
if from_env and from_env.startswith("{"):
try:
res.update(json.loads(from_env))
except Exception as e:
jprint(
{
"function": "get_clients",
"env_var": "OAUTH_CLIENTS_JSON_OBJECT",
"error": str(e),
}
)

if not IS_PROD:
jprint({"function": "get_clients", "clients": res})

Expand All @@ -62,25 +82,31 @@ def get_clients() -> dict:
return res


def reset_individual_clients():
global _individual_clients
_individual_clients = {}


def get_client(client_id: str) -> dict:
global _individual_clients
if client_id:
if client_id not in _individual_clients:
clients = get_clients()
if client_id in clients:
_individual_clients[client_id] = clients[client_id]
_individual_clients[client_id]["ok"] = True
_individual_clients[client_id]["_ok"] = True
if "client_id" not in _individual_clients[client_id]:
_individual_clients[client_id]["client_id"] = client_id

if client_id in _individual_clients:
return _individual_clients[client_id]

return {"ok": False}
return {"_ok": False}


def is_client(client_id: str) -> bool:
client = get_client(client_id)
return "ok" in client and client["ok"] == True
return "_ok" in client and client["_ok"] == True


def generate_google_auth_url(sub: str) -> str:
Expand Down
18 changes: 15 additions & 3 deletions templates/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,28 @@ <h2 class="govuk-heading-l">Applications</h2>
{%- if allowed_apps %}
{%- for a in allowed_apps %}
{%- set app = allowed_apps[a] %}
{%- if app["name"] and app["sign_in_url"] and app["dashboard_display"] %}
{%- if app["name"] and ((app["sign_in_url"] and app["dashboard_display"]) or app["can_manage"]) %}
<div>
<h3 class="govuk-heading-m">{{ app["name"] }}</h3>
<h3 class="govuk-heading-m" id="{{ a }}">
{{ app["name"] }}
</h3>
{%- if app["description"] %}
<p>
{{ app["description"] }}
</p>
{%- endif %}
<p>
<a href="{{ app['sign_in_url'] }}" role="button" draggable="false" class="govuk-button" data-module="govuk-button">{{ app["button_text"] }}</a>
{%- if app["sign_in_url"] %}
<a href="{{ app['sign_in_url'] }}" role="button" draggable="false" class="govuk-button" data-module="govuk-button">{{ app["button_text"] }}</a>
{%- endif %}

{%- if app["sign_in_url"] and app["can_manage"] %}
&nbsp;
{%- endif %}

{%- if app["can_manage"] %}
<a href="/manage?client_id={{ a }}" role="button" draggable="false" class="govuk-button govuk-button--secondary" data-module="govuk-button">Manage</a>
{%- endif %}
</p>
</div>
{%- endif %}
Expand Down
4 changes: 2 additions & 2 deletions templates/error.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ <h1 class="govuk-panel__title">
{%- endif %}

{%- if try_again_url and not try_again_url.startswith('/error') and not try_again_url == '/' %}
<a href="{{ try_again_url }}">Try again</a> or <a href="/">go to the SSO dashboard</a>.
<a class="govuk-link" href="{{ try_again_url }}">Try again</a> or <a class="govuk-link" href="/">go to the SSO dashboard</a>.
{%- else %}
<a href="/">Go to the SSO dashboard</a>.
<a class="govuk-link" href="/">Go to the SSO dashboard</a>.
{%- endif %}
</p>
</div>
Expand Down
105 changes: 105 additions & 0 deletions templates/manage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{% extends "_primary.html" %}

{% block content %}
<div class="govuk-breadcrumbs">
<ol class="govuk-breadcrumbs__list">
<li class="govuk-breadcrumbs__list-item">
<a class="govuk-breadcrumbs__link" href="/">Single Sign-On</a>
</li>
<li class="govuk-breadcrumbs__list-item" aria-current="page">Manage {{ client.get("name") }}</li>
</ol>
</div>

<main class="govuk-main-wrapper govuk-body " id="main-content" role="main">
<h2 class="govuk-heading-l">Manage {{ client.get("name") }}</h2>

{%- if saving %}
<div>
{%- if save_success %}
<div class="govuk-panel govuk-panel--confirmation">
<h2 class="govuk-panel__title">
Successfully saved changes
</h2>
</div>

{%- if new_secret %}
<div class="govuk-form-group">
<h3 class="govuk-label-wrapper">
<label class="govuk-label govuk-label--m" for="client_secret">
Client Secret
</label>
</h3>
<div id="event-name-hint" class="client_secret-hint">
You won't be able to see this secret again so please make a note securely.<br>
Only application owners can reset and get a new secret.
</div>
<input class="govuk-input" readonly="readonly" id="client_secret" name="client_secret" type="text" value="{{ new_secret }}" aria-describedby="client_secret-hint">
</div>
{%- endif %}

{%- else %}
<p>Something went wrong</p>
{%- endif %}

{%- if client_id %}
<a href="/manage?client_id={{ client_id }}" class="govuk-button govuk-button--secondary" data-module="govuk-button">
Edit {{ client.get("name", "") }}
</a>
&nbsp;
<a href="/dashboard#{{ client_id }}" class="govuk-button govuk-button--secondary" data-module="govuk-button">
Return to dashboard
</a>
{%- endif %}
</div>
{%- elif manager_type %}
<form method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div>
<div class="govuk-form-group">
<h3 class="govuk-label-wrapper">
<label class="govuk-label govuk-label--m" for="client_id">
Client ID
</label>
</h3>
<input class="govuk-input" readonly="readonly" id="client_id" name="client_id" type="text" value="{{ client_id }}">
</div>

<div class="govuk-form-group">
<h3 class="govuk-label-wrapper">
<label class="govuk-label govuk-label--m" for="config">
Client Configuration
</label>
</h3>
<div id="event-name-hint" class="govuk-hint">
You can edit this as an application {{ manager_type }}. Note that managers cannot edit owners or managers, or reset the client secret.
</div>
<textarea class="govuk-textarea" id="config" name="config" rows="{{ client_json_lines }}">{{ client_json }}</textarea>
</div>
</div>

<div>
<button type="submit" class="govuk-button" data-module="govuk-button">
Validate and save
</button>
&nbsp;
<a href="/manage?client_id={{ client_id }}" class="govuk-button govuk-button--secondary" data-module="govuk-button">
Reset
</a>
&nbsp;
<a href="/dashboard#{{ client_id }}" class="govuk-button govuk-button--secondary" data-module="govuk-button">
Return to dashboard
</a>
{%- if manager_type == "owner" %}
&nbsp;
<button type="submit" name="reset_secret" value="reset_secret" class="govuk-button govuk-button--warning" data-module="govuk-button">
Save and reset secret
</button>
{%- endif %}
</div>
</form>
{%- else %}
<div><p>No access</p></div>
{%- endif %}

</main>
{% endblock %}
Loading

0 comments on commit 36ab729

Please sign in to comment.