Better templates for OAuth2 authentication

Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
Yohann D'ANELLO 2021-06-15 21:31:51 +02:00
parent 8be16e7b58
commit 898f6d52bf
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
11 changed files with 361 additions and 24 deletions

View File

@ -3,6 +3,7 @@
from oauth2_provider.scopes import BaseScopes from oauth2_provider.scopes import BaseScopes
from member.models import Club from member.models import Club
from note_kfet.middlewares import get_current_request
from .backends import PermissionBackend from .backends import PermissionBackend
from .models import Permission from .models import Permission
@ -22,14 +23,12 @@ class PermissionScopes(BaseScopes):
def get_available_scopes(self, application=None, request=None, *args, **kwargs): def get_available_scopes(self, application=None, request=None, *args, **kwargs):
if not application: if not application:
return [] return []
user = application.user
return [f"{p.id}_{p.membership.club.id}" return [f"{p.id}_{p.membership.club.id}"
for t in Permission.PERMISSION_TYPES for t in Permission.PERMISSION_TYPES
for p in PermissionBackend.get_raw_permissions(user, t[0])] for p in PermissionBackend.get_raw_permissions(get_current_request(), t[0])]
def get_default_scopes(self, application=None, request=None, *args, **kwargs): def get_default_scopes(self, application=None, request=None, *args, **kwargs):
if not application: if not application:
return [] return []
user = application.user
return [f"{p.id}_{p.membership.club.id}" return [f"{p.id}_{p.membership.club.id}"
for p in PermissionBackend.get_raw_permissions(user, 'view')] for p in PermissionBackend.get_raw_permissions(get_current_request(), 'view')]

View File

@ -540,8 +540,8 @@ msgstr "Taille maximale : 2 Mo"
msgid "This image cannot be loaded." msgid "This image cannot be loaded."
msgstr "Cette image ne peut pas être chargée." msgstr "Cette image ne peut pas être chargée."
#: apps/member/forms.py:141 apps/member/views.py:101 #: apps/member/forms.py:141 apps/member/views.py:100
#: apps/registration/forms.py:33 apps/registration/views.py:258 #: apps/registration/forms.py:33 apps/registration/views.py:254
msgid "An alias with a similar name already exists." msgid "An alias with a similar name already exists."
msgstr "Un alias avec un nom similaire existe déjà." msgstr "Un alias avec un nom similaire existe déjà."
@ -900,7 +900,7 @@ msgid "Account #"
msgstr "Compte n°" msgstr "Compte n°"
#: apps/member/templates/member/base.html:48 #: apps/member/templates/member/base.html:48
#: apps/member/templates/member/base.html:62 apps/member/views.py:58 #: apps/member/templates/member/base.html:62 apps/member/views.py:59
#: apps/registration/templates/registration/future_profile_detail.html:48 #: apps/registration/templates/registration/future_profile_detail.html:48
#: apps/wei/templates/wei/weimembership_form.html:117 #: apps/wei/templates/wei/weimembership_form.html:117
msgid "Update Profile" msgid "Update Profile"
@ -932,7 +932,7 @@ msgid ""
"Are you sure you want to lock this note? This will prevent any transaction " "Are you sure you want to lock this note? This will prevent any transaction "
"that would be performed, until the note is unlocked." "that would be performed, until the note is unlocked."
msgstr "" msgstr ""
"Êtes-vous sûr de vouloir verrouiller cette note ? Cela empêchera toute " "Êtes-vous sûr⋅e de vouloir verrouiller cette note ? Cela empêchera toute "
"transaction qui devrait être faite, jusqu'à ce qu'elle soit déverrouillée." "transaction qui devrait être faite, jusqu'à ce qu'elle soit déverrouillée."
#: apps/member/templates/member/base.html:104 #: apps/member/templates/member/base.html:104
@ -956,7 +956,7 @@ msgstr "Verrouiller de force"
msgid "" msgid ""
"Are you sure you want to unlock this note? Transactions will be re-enabled." "Are you sure you want to unlock this note? Transactions will be re-enabled."
msgstr "" msgstr ""
"Êtes-vous sûr de vouloir déverrouiller cette note ? Les transactions seront " "Êtes-vous sûr⋅e de vouloir déverrouiller cette note ? Les transactions seront "
"à nouveau possible." "à nouveau possible."
#: apps/member/templates/member/club_alias.html:10 #: apps/member/templates/member/club_alias.html:10
@ -1097,7 +1097,7 @@ msgstr "Sauvegarder les changements"
msgid "Registrations" msgid "Registrations"
msgstr "Inscriptions" msgstr "Inscriptions"
#: apps/member/views.py:71 apps/registration/forms.py:23 #: apps/member/views.py:72 apps/registration/forms.py:23
msgid "This address must be valid." msgid "This address must be valid."
msgstr "Cette adresse doit être valide." msgstr "Cette adresse doit être valide."
@ -1481,6 +1481,9 @@ msgstr "Pas de motif spécifié"
#: apps/treasury/templates/treasury/sogecredit_detail.html:65 #: apps/treasury/templates/treasury/sogecredit_detail.html:65
#: apps/wei/tables.py:74 apps/wei/tables.py:114 #: apps/wei/tables.py:74 apps/wei/tables.py:114
#: apps/wei/templates/wei/weiregistration_confirm_delete.html:31 #: apps/wei/templates/wei/weiregistration_confirm_delete.html:31
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:18
#: note_kfet/templates/oauth2_provider/application_detail.html:31
#: note_kfet/templates/oauth2_provider/authorized-token-delete.html:12
msgid "Delete" msgid "Delete"
msgstr "Supprimer" msgstr "Supprimer"
@ -1490,6 +1493,7 @@ msgstr "Supprimer"
#: apps/wei/templates/wei/bus_detail.html:20 #: apps/wei/templates/wei/bus_detail.html:20
#: apps/wei/templates/wei/busteam_detail.html:20 #: apps/wei/templates/wei/busteam_detail.html:20
#: apps/wei/templates/wei/busteam_detail.html:40 #: apps/wei/templates/wei/busteam_detail.html:40
#: note_kfet/templates/oauth2_provider/application_detail.html:30
msgid "Edit" msgid "Edit"
msgstr "Éditer" msgstr "Éditer"
@ -1731,7 +1735,7 @@ msgstr "s'applique au club"
msgid "role permissions" msgid "role permissions"
msgstr "permissions par rôles" msgstr "permissions par rôles"
#: apps/permission/signals.py:63 #: apps/permission/signals.py:67
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"You don't have the permission to change the field {field} on this instance " "You don't have the permission to change the field {field} on this instance "
@ -1740,7 +1744,7 @@ msgstr ""
"Vous n'avez pas la permission de modifier le champ {field} sur l'instance du " "Vous n'avez pas la permission de modifier le champ {field} sur l'instance du "
"modèle {app_label}.{model_name}." "modèle {app_label}.{model_name}."
#: apps/permission/signals.py:73 apps/permission/views.py:105 #: apps/permission/signals.py:77 apps/permission/views.py:105
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"You don't have the permission to add an instance of model {app_label}." "You don't have the permission to add an instance of model {app_label}."
@ -1749,7 +1753,7 @@ msgstr ""
"Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}." "Vous n'avez pas la permission d'ajouter une instance du modèle {app_label}."
"{model_name}." "{model_name}."
#: apps/permission/signals.py:102 #: apps/permission/signals.py:106
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"You don't have the permission to delete this instance of model {app_label}." "You don't have the permission to delete this instance of model {app_label}."
@ -1977,35 +1981,35 @@ msgstr "L'équipe de la Note Kfet."
msgid "Register new user" msgid "Register new user"
msgstr "Enregistrer un nouvel utilisateur" msgstr "Enregistrer un nouvel utilisateur"
#: apps/registration/views.py:93 #: apps/registration/views.py:95
msgid "Email validation" msgid "Email validation"
msgstr "Validation de l'adresse mail" msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:95 #: apps/registration/views.py:97
msgid "Validate email" msgid "Validate email"
msgstr "Valider l'adresse e-mail" msgstr "Valider l'adresse e-mail"
#: apps/registration/views.py:137 #: apps/registration/views.py:141
msgid "Email validation unsuccessful" msgid "Email validation unsuccessful"
msgstr "La validation de l'adresse mail a échoué" msgstr "La validation de l'adresse mail a échoué"
#: apps/registration/views.py:148 #: apps/registration/views.py:152
msgid "Email validation email sent" msgid "Email validation email sent"
msgstr "L'email de vérification de l'adresse email a bien été envoyé" msgstr "L'email de vérification de l'adresse email a bien été envoyé"
#: apps/registration/views.py:156 #: apps/registration/views.py:160
msgid "Resend email validation link" msgid "Resend email validation link"
msgstr "Renvoyer le lien de validation" msgstr "Renvoyer le lien de validation"
#: apps/registration/views.py:174 #: apps/registration/views.py:178
msgid "Pre-registered users list" msgid "Pre-registered users list"
msgstr "Liste des utilisateurs en attente d'inscription" msgstr "Liste des utilisateurs en attente d'inscription"
#: apps/registration/views.py:198 #: apps/registration/views.py:202
msgid "Unregistered users" msgid "Unregistered users"
msgstr "Utilisateurs en attente d'inscription" msgstr "Utilisateurs en attente d'inscription"
#: apps/registration/views.py:211 #: apps/registration/views.py:215
msgid "Registration detail" msgid "Registration detail"
msgstr "Détails de l'inscription" msgstr "Détails de l'inscription"
@ -2225,7 +2229,7 @@ msgstr "Cette facture est verrouillée et ne peut pas être supprimée."
msgid "" msgid ""
"Are you sure you want to delete this invoice? This action can't be undone." "Are you sure you want to delete this invoice? This action can't be undone."
msgstr "" msgstr ""
"Êtes-vous sûr de vouloir supprimer cette facture ? Cette action ne pourra " "Êtes-vous sûr⋅e de vouloir supprimer cette facture ? Cette action ne pourra "
"pas être annulée." "pas être annulée."
#: apps/treasury/templates/treasury/invoice_confirm_delete.html:28 #: apps/treasury/templates/treasury/invoice_confirm_delete.html:28
@ -2863,7 +2867,7 @@ msgid ""
"Are you sure you want to delete the registration of %(user)s for the WEI " "Are you sure you want to delete the registration of %(user)s for the WEI "
"%(wei_name)s? This action can't be undone." "%(wei_name)s? This action can't be undone."
msgstr "" msgstr ""
"Êtes-vous sûr de vouloir supprimer l'inscription de %(user)s pour le WEI " "Êtes-vous sûr⋅e de vouloir supprimer l'inscription de %(user)s pour le WEI "
"%(wei_name)s ? Cette action ne pourra pas être annulée." "%(wei_name)s ? Cette action ne pourra pas être annulée."
#: apps/wei/templates/wei/weiregistration_list.html:19 #: apps/wei/templates/wei/weiregistration_list.html:19
@ -3127,6 +3131,104 @@ msgstr "Chercher par un attribut tel que le nom …"
msgid "There is no results." msgid "There is no results."
msgstr "Il n'y a pas de résultat." msgstr "Il n'y a pas de résultat."
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:8
msgid "Are you sure to delete the application"
msgstr ""
"Êtes-vous sûr⋅e de vouloir supprimer l'application"
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:17
#: note_kfet/templates/oauth2_provider/authorize.html:27
msgid "Cancel"
msgstr "Annuler"
#: note_kfet/templates/oauth2_provider/application_detail.html:11
msgid "Client id"
msgstr "ID client"
#: note_kfet/templates/oauth2_provider/application_detail.html:14
msgid "Client secret"
msgstr "Secret client"
#: note_kfet/templates/oauth2_provider/application_detail.html:17
msgid "Client type"
msgstr "Type de client"
#: note_kfet/templates/oauth2_provider/application_detail.html:20
msgid "Authorization Grant Type"
msgstr "Type d'autorisation"
#: note_kfet/templates/oauth2_provider/application_detail.html:23
msgid "Redirect Uris"
msgstr "URIs de redirection"
#: note_kfet/templates/oauth2_provider/application_detail.html:29
#: note_kfet/templates/oauth2_provider/application_form.html:23
msgid "Go Back"
msgstr "Retour en arrière"
#: note_kfet/templates/oauth2_provider/application_form.html:12
msgid "Edit application"
msgstr "Modifier l'application"
#: note_kfet/templates/oauth2_provider/application_list.html:7
msgid "Your applications"
msgstr "Vos applications"
#: note_kfet/templates/oauth2_provider/application_list.html:18
msgid "No applications defined"
msgstr "Pas d'application définie"
#: note_kfet/templates/oauth2_provider/application_list.html:19
msgid "Click here"
msgstr "Cliquez ici"
#: note_kfet/templates/oauth2_provider/application_list.html:19
msgid "if you want to register a new one"
msgstr "si vous voulez en enregistrer une nouvelle"
#: note_kfet/templates/oauth2_provider/application_list.html:24
msgid "New Application"
msgstr "Nouvelle application"
#: note_kfet/templates/oauth2_provider/application_registration_form.html:5
msgid "Register a new application"
msgstr "Enregistrer une nouvelle application"
#: note_kfet/templates/oauth2_provider/authorize.html:9
#: note_kfet/templates/oauth2_provider/authorize.html:28
msgid "Authorize"
msgstr "Autoriser"
#: note_kfet/templates/oauth2_provider/authorize.html:14
msgid "Application requires following permissions:"
msgstr "L'application requiert les permissions suivantes :"
#: note_kfet/templates/oauth2_provider/authorize.html:35
#: note_kfet/templates/oauth2_provider/authorized-oob.html:15
msgid "Error:"
msgstr "Erreur :"
#: note_kfet/templates/oauth2_provider/authorized-oob.html:13
msgid "Success"
msgstr "Succès"
#: note_kfet/templates/oauth2_provider/authorized-oob.html:21
msgid "Please return to your application and enter this code:"
msgstr "Merci de retourner à votre application et entrez ce code :"
#: note_kfet/templates/oauth2_provider/authorized-token-delete.html:9
msgid "Are you sure you want to delete this token?"
msgstr ""
"Êtes-vous sûr⋅e de vouloir supprimer ce jeton ?"
#: note_kfet/templates/oauth2_provider/authorized-tokens.html:7
msgid "Tokens"
msgstr "Jetons"
#: note_kfet/templates/oauth2_provider/authorized-tokens.html:22
msgid "There are no authorized tokens yet."
msgstr "Il n'y a pas encore de jeton autorisé."
#: note_kfet/templates/registration/logged_out.html:13 #: note_kfet/templates/registration/logged_out.html:13
msgid "Thanks for spending some quality time with the Web site today." msgid "Thanks for spending some quality time with the Web site today."
msgstr "Merci d'avoir utilisé la Note Kfet." msgstr "Merci d'avoir utilisé la Note Kfet."
@ -3168,7 +3270,7 @@ msgid ""
"password twice so we can verify you typed it in correctly." "password twice so we can verify you typed it in correctly."
msgstr "" msgstr ""
"Veuillez entrer votre ancien mot de passe pour des raisons de sécurité, puis " "Veuillez entrer votre ancien mot de passe pour des raisons de sécurité, puis "
"renseigner votre nouveau mot de passe à deux reprises, pour être sûr de " "renseigner votre nouveau mot de passe à deux reprises, pour être sûr⋅e de "
"l'avoir tapé correctement." "l'avoir tapé correctement."
#: note_kfet/templates/registration/password_change_form.html:16 #: note_kfet/templates/registration/password_change_form.html:16

View File

@ -0,0 +1,24 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="card">
<div class="card-header text-center">
<h3>{% trans "Are you sure to delete the application" %} {{ application.name }}?</h3>
</div>
<div class="card-footer text-center">
<form method="post" action="{% url 'oauth2_provider:delete' application.pk %}">
{% csrf_token %}
<div class="control-group">
<div class="controls">
<a class="btn btn-secondary btn-large" href="{% url "oauth2_provider:list" %}">{% trans "Cancel" %}</a>
<input type="submit" class="btn btn-large btn-danger" name="allow" value="{% trans "Delete" %}"/>
</div>
</div>
</form>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,34 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="card">
<div class="card-header text-center">
<h3>{{ application.name }}</h3>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-xl-6">{% trans "Client id" %}</dt>
<dd class="col-xl-6"><input class="form-control" type="text" value="{{ application.client_id }}" readonly></dd>
<dt class="col-xl-6">{% trans "Client secret" %}</dt>
<dd class="col-xl-6"><input class="form-control" type="text" value="{{ application.client_secret }}" readonly></dd>
<dt class="col-xl-6">{% trans "Client type" %}</dt>
<dd class="col-xl-6">{{ application.client_type }}</dd>
<dt class="col-xl-6">{% trans "Authorization Grant Type" %}</dt>
<dd class="col-xl-6">{{ application.authorization_grant_type }}</dd>
<dt class="col-xl-6">{% trans "Redirect Uris" %}</dt>
<dd class="col-xl-6"><textarea class="form-control" readonly>{{ application.redirect_uris }}</textarea></dd>
</dl>
</div>
<div class="card-footer text-center">
<a class="btn btn-secondary" href="{% url "oauth2_provider:list" %}">{% trans "Go Back" %}</a>
<a class="btn btn-primary" href="{% url "oauth2_provider:update" application.id %}">{% trans "Edit" %}</a>
<a class="btn btn-danger" href="{% url "oauth2_provider:delete" application.id %}">{% trans "Delete" %}</a>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,30 @@
{% extends "base.html" %}
{% load i18n %}
{% load crispy_forms_filters %}
{% block content %}
<form class="form-horizontal" method="post" action="{% block app-form-action-url %}{% url 'oauth2_provider:update' application.id %}{% endblock app-form-action-url %}">
<div class="card">
<div class="card-header text-center">
<h3 class="block-center-heading">
{% block app-form-title %}
{% trans "Edit application" %} {{ application.name }}
{% endblock app-form-title %}
</h3>
</div>
<div class="card-body">
{% csrf_token %}
{{ form|crispy }}
</div>
<div class="card-footer text-center control-group">
<div class="controls">
<a class="btn btn-secondary" 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">Save</button>
</div>
</div>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="card">
<div class="card-header text-center">
<h3>{% trans "Your applications" %}</h3>
</div>
<div class="card-body">
{% if applications %}
<ul>
{% for application in applications %}
<li><a href="{{ application.get_absolute_url }}">{{ application.name }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>
{% trans "No applications defined" %}.
<a href="{% url 'oauth2_provider:register' %}">{% trans "Click here" %}</a> {% trans "if you want to register a new one" %}.
</p>
{% endif %}
</div>
<div class="card-footer text-center">
<a class="btn btn-success" href="{% url "oauth2_provider:register" %}">{% trans "New Application" %}</a>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,9 @@
{% extends "oauth2_provider/application_form.html" %}
{% load i18n %}
{% block app-form-title %}{% trans "Register a new application" %}{% endblock app-form-title %}
{% block app-form-action-url %}{% url 'oauth2_provider:register' %}{% endblock app-form-action-url %}
{% block app-form-back-url %}{% url "oauth2_provider:list" %}"{% endblock app-form-back-url %}

View File

@ -0,0 +1,40 @@
{% extends "base.html" %}
{% load i18n %}
{% load crispy_forms_filters %}
{% block content %}
<div class="card">
<div class="card-header text-center">
<h3>{% trans "Authorize" %} {{ application.name }} ?</h3>
</div>
{% if not error %}
<form id="authorizationForm" method="post">
<div class="card-body">
<p>{% trans "Application requires following permissions:" %}</p>
{% csrf_token %}
{{ form|crispy }}
<ul>
{% for scope in scopes_descriptions %}
<li>{{ scope }}</li>
{% endfor %}
</ul>
</div>
<div class="card-footer text-center">
<div class="control-group">
<div class="controls">
<input type="submit" class="btn btn-large" value="{% trans "Cancel" %}"/>
<input type="submit" class="btn btn-large btn-primary" name="allow" value="{% trans "Authorize" %}"/>
</div>
</div>
</div>
</form>
{% else %}
<div class="card-body">
<h2>{% trans "Error:" %} {{ error.error }}</h2>
<p>{{ error.description }}</p>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,29 @@
{% extends "base.html" %}
{% load i18n %}
{% block title %}
Success code={{code}}
{% endblock %}
{% block content %}
<div class="card">
<h3 class="card-header text-center">
{% if not error %}
{% trans "Success" %}
{% else %}
{% trans "Error:" %} {{ error.error }}
{% endif %}
</h3>
<div class="card-body">
{% if not error %}
<p>{% trans "Please return to your application and enter this code:" %}</p>
<p><code>{{ code }}</code></p>
{% else %}
<p>{{ error.description }}</p>
{% endif %}
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,16 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="card">
<form action="" method="post">
{% csrf_token %}
<h3 class="card-header text-center">
{% trans "Are you sure you want to delete this token?" %}
</h3>
<div class="card-footer text-center">
<input type="submit" value="{% trans "Delete" %}" />
</div>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="card">
<h3 class="card-header text-center">
{% trans "Tokens" %}
</h3>
<div class="card-body">
<ul>
{% for authorized_token in authorized_tokens %}
<li>
{{ authorized_token.application }}
(<a href="{% url 'oauth2_provider:authorized-token-delete' authorized_token.pk %}">revoke</a>)
</li>
<ul>
{% for scope_name, scope_description in authorized_token.scopes.items %}
<li>{{ scope_name }}: {{ scope_description }}</li>
{% endfor %}
</ul>
{% empty %}
<li>{% trans "There are no authorized tokens yet." %}</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}