diff --git a/canaille/oidc/tokens.py b/canaille/oidc/tokens.py index 078192d6..56131f23 100644 --- a/canaille/oidc/tokens.py +++ b/canaille/oidc/tokens.py @@ -1,9 +1,15 @@ +import datetime + from canaille.flaskutils import permissions_needed from canaille.models import User from canaille.oidc.models import Client from canaille.oidc.models import Token from flask import abort from flask import Blueprint +from flask import flash +from flask import redirect +from flask import url_for +from flask_babel import gettext as _ from flask_themer import render_template @@ -40,3 +46,18 @@ def view(user, token_id): token_audience=token_audience, menuitem="admin", ) + + +@bp.route("//revoke", methods=["GET", "POST"]) +@permissions_needed("manage_oidc") +def revoke(user, token_id): + token = Token.get(token_id=token_id) + + if not token: + abort(404) + + token.revokation_date = datetime.datetime.now() + token.save() + flash(_("The token has successfully been revoked."), "success") + + return redirect(url_for("oidc.tokens.view", token_id=token_id)) diff --git a/canaille/templates/oidc/admin/token_view.html b/canaille/templates/oidc/admin/token_view.html index 119ad2dc..707b4367 100644 --- a/canaille/templates/oidc/admin/token_view.html +++ b/canaille/templates/oidc/admin/token_view.html @@ -2,13 +2,30 @@ {% import 'fomanticui.html' as sui %} {% block script %} + {% endblock %} {% block content %} + +

- {% trans %}View a token{% endtrans %} + {% trans %}Token details{% endtrans %}

@@ -59,7 +76,18 @@ {{ _("Revokation date") }} - {% if token.revokation_date %}{{ token.revokation_date }}{% endif %} + + {% if token.revokation_date %} + {{ token.revokation_date }} + {% else %} + + {% trans %}Revoke token{% endtrans %} + +

+ {% trans %}This token has not been revoked{% endtrans %} +

+ {% endif %} + {{ _("Lifetime") }} diff --git a/canaille/translations/messages.pot b/canaille/translations/messages.pot index 647e32d9..5e53ae42 100644 --- a/canaille/translations/messages.pot +++ b/canaille/translations/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-01-22 13:42+0100\n" +"POT-Creation-Date: 2023-02-04 18:36+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,7 +18,7 @@ msgstr "" "Generated-By: Babel 2.11.0\n" #: canaille/account.py:103 canaille/account.py:128 -#: canaille/oidc/endpoints.py:81 +#: canaille/oidc/endpoints.py:82 msgid "Login failed, please check your information" msgstr "" @@ -42,7 +42,7 @@ msgid "" "should receive it within a few minutes." msgstr "" -#: canaille/account.py:176 canaille/account.py:426 +#: canaille/account.py:176 canaille/account.py:423 msgid "Could not send the password initialization email" msgstr "" @@ -76,65 +76,65 @@ msgstr "" msgid "You account has been created successfuly." msgstr "" -#: canaille/account.py:393 +#: canaille/account.py:390 msgid "User account creation succeed." msgstr "" -#: canaille/account.py:420 +#: canaille/account.py:417 msgid "" "A password initialization link has been sent at the user email address. " "It should be received within a few minutes." msgstr "" -#: canaille/account.py:437 +#: canaille/account.py:434 msgid "" "A password reset link has been sent at the user email address. It should " "be received within a few minutes." msgstr "" -#: canaille/account.py:443 +#: canaille/account.py:440 msgid "Could not send the password reset email" msgstr "" -#: canaille/account.py:477 +#: canaille/account.py:474 msgid "Profile edition failed." msgstr "" -#: canaille/account.py:513 +#: canaille/account.py:508 msgid "Profile updated successfuly." msgstr "" -#: canaille/account.py:536 +#: canaille/account.py:531 #, python-format msgid "The user %(user)s has been sucessfuly deleted" msgstr "" -#: canaille/account.py:566 +#: canaille/account.py:561 msgid "Could not send the password reset link." msgstr "" -#: canaille/account.py:570 +#: canaille/account.py:565 msgid "" "A password reset link has been sent at your email address. You should " "receive it within a few minutes." msgstr "" -#: canaille/account.py:581 +#: canaille/account.py:576 #, python-format msgid "" "The user '%(user)s' does not have permissions to update their password. " "We cannot send a password reset email." msgstr "" -#: canaille/account.py:596 +#: canaille/account.py:591 msgid "We encountered an issue while we sent the password recovery email." msgstr "" -#: canaille/account.py:615 +#: canaille/account.py:610 msgid "The password reset link that brought you here was invalid." msgstr "" -#: canaille/account.py:624 +#: canaille/account.py:619 msgid "Your password has been updated successfuly" msgstr "" @@ -396,19 +396,19 @@ msgstr "" msgid "The access has been revoked" msgstr "" -#: canaille/oidc/endpoints.py:129 +#: canaille/oidc/endpoints.py:130 msgid "You have been successfully logged out." msgstr "" -#: canaille/oidc/endpoints.py:327 +#: canaille/oidc/endpoints.py:329 msgid "You have been disconnected" msgstr "" -#: canaille/oidc/endpoints.py:335 +#: canaille/oidc/endpoints.py:337 msgid "An error happened during the logout" msgstr "" -#: canaille/oidc/endpoints.py:347 +#: canaille/oidc/endpoints.py:349 msgid "You have not been disconnected" msgstr "" @@ -432,7 +432,7 @@ msgstr "" msgid "Grant types" msgstr "" -#: canaille/oidc/forms.py:54 canaille/templates/oidc/admin/token_view.html:33 +#: canaille/oidc/forms.py:54 canaille/templates/oidc/admin/token_view.html:54 msgid "Scope" msgstr "" @@ -480,12 +480,16 @@ msgstr "" msgid "Pre-consent" msgstr "" +#: canaille/oidc/tokens.py:61 +msgid "The token has successfully been revoked." +msgstr "" + #: canaille/oidc/utils.py:6 -msgid "Personnal information about yourself, such as your name or your gender." +msgid "Info about yourself, such as your name." msgstr "" #: canaille/oidc/utils.py:8 -msgid "Your email address." +msgid "Your e-mail address." msgstr "" #: canaille/oidc/utils.py:9 @@ -497,11 +501,11 @@ msgid "Your phone number." msgstr "" #: canaille/oidc/utils.py:11 -msgid "Groups you are belonging to" +msgid "Groups you belong to." msgstr "" #: canaille/templates/about.html:12 canaille/themes/default/base.html:106 -msgid "About canaille" +msgid "About Canaille" msgstr "" #: canaille/templates/about.html:14 @@ -623,12 +627,14 @@ msgstr "" #: canaille/templates/group.html:30 #: canaille/templates/oidc/admin/client_edit.html:18 +#: canaille/templates/oidc/admin/token_view.html:21 #: canaille/templates/profile.html:41 msgid "Cancel" msgstr "" #: canaille/templates/group.html:31 #: canaille/templates/oidc/admin/client_edit.html:19 +#: canaille/templates/oidc/admin/token_view.html:22 #: canaille/templates/profile.html:42 msgid "Delete" msgstr "" @@ -723,6 +729,8 @@ msgid "" msgstr "" #: canaille/templates/invite.html:58 +#: canaille/templates/oidc/admin/token_view.html:104 +#: canaille/templates/oidc/admin/token_view.html:114 msgid "Copy" msgstr "" @@ -1039,13 +1047,13 @@ msgstr "" #: canaille/templates/oidc/admin/authorization_list.html:19 #: canaille/templates/oidc/admin/token_list.html:19 -#: canaille/templates/oidc/admin/token_view.html:17 +#: canaille/templates/oidc/admin/token_view.html:38 msgid "Client" msgstr "" #: canaille/templates/oidc/admin/authorization_list.html:20 #: canaille/templates/oidc/admin/token_list.html:20 -#: canaille/templates/oidc/admin/token_view.html:25 +#: canaille/templates/oidc/admin/token_view.html:46 msgid "Subject" msgstr "" @@ -1113,35 +1121,51 @@ msgstr "" msgid "Token" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:7 -msgid "View a token" +#: canaille/templates/oidc/admin/token_view.html:13 +msgid "Token deletion" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:13 +#: canaille/templates/oidc/admin/token_view.html:17 +msgid "Are you sure you want to revoke this token? This action is unrevokable." +msgstr "" + +#: canaille/templates/oidc/admin/token_view.html:28 +msgid "Token details" +msgstr "" + +#: canaille/templates/oidc/admin/token_view.html:34 msgid "Issue date" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:43 +#: canaille/templates/oidc/admin/token_view.html:64 msgid "Audience" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:57 +#: canaille/templates/oidc/admin/token_view.html:78 msgid "Revokation date" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:61 +#: canaille/templates/oidc/admin/token_view.html:84 +msgid "Revoke token" +msgstr "" + +#: canaille/templates/oidc/admin/token_view.html:86 +msgid "This token has not been revoked" +msgstr "" + +#: canaille/templates/oidc/admin/token_view.html:91 msgid "Lifetime" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:65 +#: canaille/templates/oidc/admin/token_view.html:95 msgid "Token type" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:69 +#: canaille/templates/oidc/admin/token_view.html:99 msgid "Access token" msgstr "" -#: canaille/templates/oidc/admin/token_view.html:74 +#: canaille/templates/oidc/admin/token_view.html:109 msgid "Refresh token" msgstr "" @@ -1152,7 +1176,7 @@ msgstr "" #: canaille/templates/oidc/user/authorize.html:32 #, python-format -msgid "You are logged id as: %(name)s" +msgid "You are logged in as %(name)s" msgstr "" #: canaille/templates/oidc/user/authorize.html:39 diff --git a/tests/oidc/test_token_admin.py b/tests/oidc/test_token_admin.py index 1531a418..1a646add 100644 --- a/tests/oidc/test_token_admin.py +++ b/tests/oidc/test_token_admin.py @@ -18,3 +18,17 @@ def test_token_view(testclient, token, logged_admin): def test_token_not_found(testclient, logged_admin): res = testclient.get("/admin/token/" + "yolo", status=404) + + +def test_revoke_token(testclient, token, logged_admin): + assert not token.revoked + + res = testclient.get(f"/admin/token/{token.token_id}/revoke") + assert ("success", "The token has successfully been revoked.") in res.flashes + + token.reload() + assert token.revoked + + +def test_revoke_invalid_token(testclient, logged_admin): + testclient.get(f"/admin/token/invalid/revoke", status=404)