Skip to content

Commit

Permalink
Improve oauth templates, add authorized token revoke in settings
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanw committed Sep 16, 2024
1 parent 6b52f1c commit 44ea4aa
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 17 deletions.
51 changes: 48 additions & 3 deletions froide/account/oauth_urls.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.forms.models import modelform_factory
from django.http import HttpResponseRedirect
from django.urls import path

Expand All @@ -8,10 +9,14 @@
ApplicationRegistration,
ApplicationUpdate,
AuthorizationView,
AuthorizedTokenDeleteView,
AuthorizedTokensListView,
RevokeTokenView,
TokenView,
)

from .auth import recent_auth_required
from .models import Application


class CustomAuthorizationView(AuthorizationView):
Expand All @@ -36,11 +41,38 @@ def render_to_response(self, context, **kwargs):
urlpatterns = [
path("authorize/", CustomAuthorizationView.as_view(), name="authorize"),
path("token/", TokenView.as_view(), name="token"),
path("revoke_token/", RevokeTokenView.as_view(), name="revoke-token"),
]


class CustomApplicationUpdate(ApplicationUpdate):
fields = ["name", "redirect_uris", "description", "homepage", "image_url"]
class ApplicationEditMixin:
fields = [
"name",
"description",
"homepage",
"redirect_uris",
"post_logout_redirect_uris",
"allowed_origins",
"client_type",
"authorization_grant_type",
]

def get_form_class(self):
"""
Returns the form class for the application model
"""
return modelform_factory(
Application,
fields=self.fields,
)


class CustomApplicationRegistration(ApplicationEditMixin, ApplicationRegistration):
fields = ApplicationEditMixin.fields + ["client_secret"]


class CustomApplicationUpdate(ApplicationEditMixin, ApplicationUpdate):
pass


# Application management views
Expand All @@ -49,7 +81,7 @@ class CustomApplicationUpdate(ApplicationUpdate):
path("applications/", recent_auth_required(ApplicationList.as_view()), name="list"),
path(
"applications/register/",
recent_auth_required(ApplicationRegistration.as_view()),
recent_auth_required(CustomApplicationRegistration.as_view()),
name="register",
),
path(
Expand All @@ -68,3 +100,16 @@ class CustomApplicationUpdate(ApplicationUpdate):
name="update",
),
]

urlpatterns += [
path(
"authorized-tokens/",
AuthorizedTokensListView.as_view(),
name="authorized-token-list",
),
path(
"authorized-tokens/<pk>/delete/",
AuthorizedTokenDeleteView.as_view(),
name="authorized-token-delete",
),
]
26 changes: 20 additions & 6 deletions froide/account/templates/account/settings.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
{% extends 'account/settings_base.html' %}
{% extends "account/settings_base.html" %}
{% load i18n %}
{% load form_helper %}
{% load account_tags %}
{% block title %}
{% trans "Account Settings" %}
{% endblock %}
{% endblock title %}
{% block settings_body %}
<h2>{% trans "Account Settings" %}</h2>
<dl id="general">
<dt>{% blocktrans %}Your name:{% endblocktrans %}</dt>
<dd>
{{ request.user.get_full_name }}
{% block settings_name %}{% endblock %}
{% block settings_name %}
{% endblock settings_name %}
</dd>
<dt>{% trans "Account Privacy:" %}</dt>
<dd>
Expand All @@ -20,7 +21,8 @@ <h2>{% trans "Account Settings" %}</h2>
{% blocktrans %}Your name is hidden on the web.{% endblocktrans %}
{% else %}
{% blocktrans %}Your name is visible.{% endblocktrans %}
{% block settings_privacy %}{% endblock %}
{% block settings_privacy %}
{% endblock settings_privacy %}
<a class="btn btn-sm btn-secondary float-end"
data-bs-toggle="collapse"
href="#make-private">{% trans "Make my account private" %}</a>
Expand Down Expand Up @@ -133,7 +135,8 @@ <h5 class="card-header">{% translate "Setup two-factor login" %}</h5>
{% endrecentauthrequired %}
</div>
</div>
{% block post_password %}{% endblock %}
{% block post_password %}
{% endblock post_password %}
<div id="proofs" class="card mb-3">
<h5 class="card-header">{% translate "Proofs" %}</h5>
<div class="card-body">
Expand All @@ -143,6 +146,17 @@ <h5 class="card-header">{% translate "Proofs" %}</h5>
</div>
</div>
<hr />
<div id="apps" class="card mb-3">
<h5 class="card-header">{% trans "External apps" %}</h5>
<div class="card-body">
{% recentauthrequired "export" %}
<a href="{% url 'oauth2_provider:authorized-token-list' %}">
{% trans "Show external apps with access to your account" %}
</a>
{% endrecentauthrequired %}
</div>
</div>
<hr />
<div id="export" class="card mb-3">
<h5 class="card-header">{% trans "Export your data" %}</h5>
<div class="card-body">
Expand Down Expand Up @@ -191,4 +205,4 @@ <h5 class="card-header">{% blocktrans %}Developer{% endblocktrans %}</h5>
{% endif %}
</div>
</div>
{% endblock %}
{% endblock settings_body %}
13 changes: 8 additions & 5 deletions froide/account/templates/account/settings_base.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{% extends 'account/base.html' %}
{% extends "account/base.html" %}
{% load i18n %}
{% block breadcrumbs %}
{% url "account-settings" as settings_url %}
{% translate "Settings" as settings_name %}
{% include "account/includes/breadcrumbs.html" with section_name=settings_name section_url=settings_url last_item=last_item %}
{% endblock %}
{% endblock breadcrumbs %}
{% block app_container %}
<div class="row">
<div class="col-md-4">
Expand All @@ -19,16 +19,19 @@
<a href="#change-password-now"
class="list-group-item list-group-item-action">{% trans "Change password" %}</a>
<a href="#mfa" class="list-group-item list-group-item-action">{% trans "Setup two-factor login" %}</a>
{% block post_password_menu %}{% endblock %}
{% block post_password_menu %}
{% endblock post_password_menu %}
<a href="#proofs" class="list-group-item list-group-item-action">{% trans "Proofs" %}</a>
<a href="#apps" class="list-group-item list-group-item-action">{% trans "External Apps" %}</a>
<a href="#export" class="list-group-item list-group-item-action">{% trans "Data export" %}</a>
<a href="#delete-account-section"
class="list-group-item list-group-item-action">{% trans "Account deletion" %}</a>
<a href="#developer" class="list-group-item list-group-item-action">{% trans "Developer" %}</a>
</div>
</div>
<div class="col-md-8">
{% block settings_body %}{% endblock %}
{% block settings_body %}
{% endblock settings_body %}
</div>
</div>
{% endblock %}
{% endblock app_container %}
68 changes: 68 additions & 0 deletions froide/account/templates/oauth2_provider/application_detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{% extends "oauth2_provider/base.html" %}
{% load i18n %}
{% block content %}
<div class="block-center">
<h3 class="block-center-heading">{{ application.name }}</h3>
<ul class="unstyled">
<li>
<p>
<b>{% trans "Client id" %}</b>
</p>
<input class="input-block-level"
type="text"
value="{{ application.client_id }}"
readonly>
</li>
{% if not application.hash_client_secret %}
<li>
<p>
<b>{% trans "Client secret" %}</b>
</p>
<input class="input-block-level"
type="text"
value="{{ application.client_secret }}"
readonly>
</li>
{% else %}
<li>{% trans "Client secret has been hashed and can no longer be viewed." %}</li>
{% endif %}
<li>
<p>
<b>{% trans "Client type" %}</b>
</p>
<p>{{ application.client_type }}</p>
</li>
<li>
<p>
<b>{% trans "Authorization Grant Type" %}</b>
</p>
<p>{{ application.authorization_grant_type }}</p>
</li>
<li>
<p>
<b>{% trans "Redirect Uris" %}</b>
</p>
<textarea class="input-block-level" readonly>{{ application.redirect_uris }}</textarea>
</li>
<li>
<p>
<b>{% trans "Post Logout Redirect Uris" %}</b>
</p>
<textarea class="input-block-level" readonly>{{ application.post_logout_redirect_uris }}</textarea>
</li>
<li>
<p>
<b>{% trans "Allowed Origins" %}</b>
</p>
<textarea class="input-block-level" readonly>{{ application.allowed_origins }}</textarea>
</li>
</ul>
<div class="btn-toolbar">
<a class="btn" href="{% url "oauth2_provider:list" %}">{% trans "Go Back" %}</a>
<a class="btn btn-primary"
href="{% url "oauth2_provider:update" application.pk %}">{% trans "Edit" %}</a>
<a class="btn btn-danger"
href="{% url "oauth2_provider:delete" application.pk %}">{% trans "Delete" %}</a>
</div>
</div>
{% endblock content %}
27 changes: 27 additions & 0 deletions froide/account/templates/oauth2_provider/application_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends "oauth2_provider/base.html" %}
{% load i18n %}
{% load form_helper %}
{% block content %}
<div class="block-center">
<form class="form-horizontal"
method="post"
action="{% block app-form-action-url %}{% url 'oauth2_provider:update' application.id %}{% endblock app-form-action-url %}">
{% csrf_token %}
<h3 class="block-center-heading">
{% block app-form-title %}
{% trans "Edit application" %} {{ application.name }}
{% endblock app-form-title %}
</h3>
{% render_form form %}
<div class="control-group">
<div class="controls">
<a class="btn"
href="{% block app-form-back-url %}{% url "oauth2_provider:detail" application.id %}{% endblock app-form-back-url %}">
{% trans "Go Back" %}
</a>
<button type="submit" class="btn btn-primary">{% trans "Save" %}</button>
</div>
</div>
</form>
</div>
{% endblock content %}
9 changes: 6 additions & 3 deletions froide/account/templates/oauth2_provider/authorize.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
<h3 class="block-center-heading">
{% blocktrans with name=application.name %}Authorize the application '{{ name }}'?{% endblocktrans %}
</h3>
<blockquote>
{{ application.description }}
</blockquote>
{% csrf_token %}
{% for field in form %}
{% if field.is_hidden %}{{ field }}{% endif %}
Expand All @@ -20,11 +23,11 @@ <h3 class="block-center-heading">
{{ form.non_field_errors }}
<div class="control-group">
<div class="controls">
<input type="submit" class="btn btn-large" value="{% trans 'Cancel' %}" />
<input type="submit" class="btn btn-large" value="{% trans "Cancel" %}" />
<input type="submit"
class="btn btn-large btn-primary"
name="allow"
value="{% trans 'Authorize' %}" />
value="{% trans "Authorize" %}" />
</div>
</div>
</form>
Expand All @@ -34,4 +37,4 @@ <h2>Error: {{ error.error }}</h2>
{% endif %}
</div>
</div>
{% endblock %}
{% endblock content %}
58 changes: 58 additions & 0 deletions froide/account/templates/oauth2_provider/authorized-tokens.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{% extends "oauth2_provider/base.html" %}
{% load i18n %}
{% block content %}
<div class="block-center">
<h1>{% trans "External applications with access to your account" %}</h1>
<p>{% trans "You have given the following applications access to your account." %}</p>
<ul class="list-unstyled">
{% for authorized_token in authorized_tokens %}
<li>
<details>
<summary>
{{ authorized_token.application.name }}
{% if authorized_token.is_expired %}
<span class="badge text-bg-secondary">{% trans "Expired" %}</span>
{% endif %}
</summary>
{% if authorized_token.application.description %}
<blockquote>
{{ authorized_token.application.description|linebreaks }}
</blockquote>
{% endif %}
<ul>
{% for scope_name, scope_description in authorized_token.scopes.items %}
<li>
<span title="{{ scope_name }}">{{ scope_description }}</span>
</li>
{% endfor %}
</ul>
<dl>
<dt>{% trans "Created" %}</dt>
<dd>
{{ authorized_token.created|date:"DATETIME_FORMAT" }}
</dd>
{% if authorized_token.updated|date:"DATETIME_FORMAT" != authorized_token.created|date:"DATETIME_FORMAT" %}
<dt>{% trans "Updated" %}</dt>
<dd>
{{ authorized_token.updated|date:"DATETIME_FORMAT" }}
</dd>
{% endif %}
<dt>{% trans "Expires" %}</dt>
<dd>
{{ authorized_token.expires|date:"DATETIME_FORMAT" }}
</dd>
</dl>
<form class="mb-3"
action="{% url 'oauth2_provider:authorized-token-delete' authorized_token.pk %}"
method="post">
{% csrf_token %}
<button type="submit" class="btn btn-danger">{% trans "Revoke access" %}</button>
</form>
</details>
</li>
{% empty %}
<li>{% trans "There are no external applications with." %}</li>
{% endfor %}
</ul>
</div>
{% endblock content %}
1 change: 1 addition & 0 deletions froide/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ def is_pkce_required(client_id):
"read:document": _("Read your (private) documents"),
},
"PKCE_REQUIRED": is_pkce_required,
"REFRESH_TOKEN_EXPIRE_SECONDS": 60 * 60 * 24 * 180, # half a year
}
OAUTH2_PROVIDER_APPLICATION_MODEL = "account.Application"

Expand Down

0 comments on commit 44ea4aa

Please sign in to comment.