[oauth2] Add view to generate authorization link per application with given scopes

Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
Yohann D'ANELLO 2021-06-16 00:01:35 +02:00
parent 898f6d52bf
commit 7ea36a5415
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
5 changed files with 137 additions and 27 deletions

View File

@ -0,0 +1,74 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="card">
<div class="card-header text-center">
<h2>{% trans "Available scopes" %}</h2>
</div>
<div class="card-body">
<div class="accordion" id="accordionApps">
{% for app, app_scopes in scopes.items %}
<div class="card">
<div class="card-header" id="app-{{ app.name.lower }}-title">
<a class="text-decoration-none collapsed" href="#" data-toggle="collapse"
data-target="#app-{{ app.name.lower }}" aria-expanded="false"
aria-controls="app-{{ app.name.lower }}">
{{ app.name }}
</a>
</div>
<div class="collapse" id="app-{{ app.name.lower }}" aria-labelledby="app-{{ app.name.lower }}" data-target="#accordionApps">
<div class="card-body">
{% for scope_id, scope_desc in app_scopes.items %}
<div class="form-group">
<label class="form-check-label" for="scope-{{ app.name.lower }}-{{ scope_id }}">
<input type="checkbox" id="scope-{{ app.name.lower }}-{{ scope_id }}"
name="scope-{{ app.name.lower }}" class="checkboxinput form-check-input" value="{{ scope_id }}">
{{ scope_desc }}
</label>
</div>
{% endfor %}
<p id="url-{{ app.name.lower }}">
<a href="{% url 'oauth2_provider:authorize' %}?client_id={{ app.client_id }}&response_type=code" target="_blank">
{{ request.scheme }}://{{ request.get_host }}{% url 'oauth2_provider:authorize' %}?client_id={{ app.client_id }}&response_type=code
</a>
</p>
</div>
</div>
</div>
{% empty %}
<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>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
{% block extrajavascript %}
<script>
{% for app in scopes.keys %}
let elements = document.getElementsByName("scope-{{ app.name.lower }}");
for (let element of elements) {
element.onchange = function (event) {
let scope = ""
for (let element of elements) {
if (element.checked) {
scope += element.value + "%20"
}
}
scope = scope.substr(0, scope.length - 3)
document.getElementById("url-{{ app.name.lower }}").innerHTML = 'Scopes : ' + scope
+ '<br><a href="{% url 'oauth2_provider:authorize' %}?client_id={{ app.client_id }}&response_type=code&scope='+ scope
+ '" target="_blank">{{ request.scheme }}://{{ request.get_host }}{% url 'oauth2_provider:authorize' %}?client_id={{ app.client_id }}&response_type=code&scope='
+ scope + '</a>'
}
}
{% endfor %}
</script>
{% endblock %}

View File

@ -1,10 +1,17 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.urls import path from django.urls import path
from permission.views import RightsView
from .views import RightsView, ScopesView
app_name = 'permission' app_name = 'permission'
urlpatterns = [ urlpatterns = [
path('rights', RightsView.as_view(), name="rights"), path('rights/', RightsView.as_view(), name="rights"),
] ]
if "oauth2_provider" in settings.INSTALLED_APPS:
urlpatterns += [
path('scopes/', ScopesView.as_view(), name="scopes"),
]

View File

@ -1,6 +1,6 @@
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from collections import OrderedDict
from datetime import date from datetime import date
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
@ -143,3 +143,26 @@ class RightsView(TemplateView):
prefix="superusers-") prefix="superusers-")
return context return context
class ScopesView(LoginRequiredMixin, TemplateView):
template_name = "permission/scopes.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
from oauth2_provider.models import Application
from .scopes import PermissionScopes
scopes = PermissionScopes()
context["scopes"] = {}
all_scopes = scopes.get_all_scopes()
for app in Application.objects.filter(Q(user=self.request.user) | Q(client_type='public')).all():
available_scopes = scopes.get_available_scopes(app)
context["scopes"][app] = OrderedDict()
items = [(k, v) for (k, v) in all_scopes.items() if k in available_scopes]
items.sort(key=lambda x: (int(x[0].split("_")[1]), int(x[0].split("_")[0])))
for k, v in items:
context["scopes"][app][k] = v
return context

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-29 14:06+0200\n" "POT-Creation-Date: 2021-06-15 21:17+0200\n"
"PO-Revision-Date: 2020-11-16 20:02+0000\n" "PO-Revision-Date: 2020-11-16 20:02+0000\n"
"Last-Translator: Yohann D'ANELLO <ynerant@crans.org>\n" "Last-Translator: Yohann D'ANELLO <ynerant@crans.org>\n"
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n" "Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
@ -956,8 +956,8 @@ 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⋅e de vouloir déverrouiller cette note ? Les transactions seront " "Êtes-vous sûr⋅e de vouloir déverrouiller cette note ? Les transactions "
"à nouveau possible." "seront à nouveau possible."
#: apps/member/templates/member/club_alias.html:10 #: apps/member/templates/member/club_alias.html:10
#: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:253 #: apps/member/templates/member/profile_alias.html:10 apps/member/views.py:253
@ -1803,6 +1803,25 @@ msgstr "Requête :"
msgid "No associated permission" msgid "No associated permission"
msgstr "Pas de permission associée" msgstr "Pas de permission associée"
#: apps/permission/templates/permission/scopes.html:8
msgid "Available scopes"
msgstr "Scopes disponibles"
#: apps/permission/templates/permission/scopes.html:42
#: note_kfet/templates/oauth2_provider/application_list.html:18
msgid "No applications defined"
msgstr "Pas d'application définie"
#: apps/permission/templates/permission/scopes.html:43
#: note_kfet/templates/oauth2_provider/application_list.html:19
msgid "Click here"
msgstr "Cliquez ici"
#: apps/permission/templates/permission/scopes.html:43
#: 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"
#: apps/permission/views.py:72 #: apps/permission/views.py:72
#, python-brace-format #, python-brace-format
msgid "" msgid ""
@ -3133,11 +3152,10 @@ msgstr "Il n'y a pas de résultat."
#: note_kfet/templates/oauth2_provider/application_confirm_delete.html:8 #: note_kfet/templates/oauth2_provider/application_confirm_delete.html:8
msgid "Are you sure to delete the application" msgid "Are you sure to delete the application"
msgstr "" msgstr "Êtes-vous sûr⋅e de vouloir supprimer l'application"
"Ê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/application_confirm_delete.html:17
#: note_kfet/templates/oauth2_provider/authorize.html:27 #: note_kfet/templates/oauth2_provider/authorize.html:28
msgid "Cancel" msgid "Cancel"
msgstr "Annuler" msgstr "Annuler"
@ -3174,18 +3192,6 @@ msgstr "Modifier l'application"
msgid "Your applications" msgid "Your applications"
msgstr "Vos 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 #: note_kfet/templates/oauth2_provider/application_list.html:24
msgid "New Application" msgid "New Application"
msgstr "Nouvelle application" msgstr "Nouvelle application"
@ -3195,7 +3201,7 @@ msgid "Register a new application"
msgstr "Enregistrer une nouvelle application" msgstr "Enregistrer une nouvelle application"
#: note_kfet/templates/oauth2_provider/authorize.html:9 #: note_kfet/templates/oauth2_provider/authorize.html:9
#: note_kfet/templates/oauth2_provider/authorize.html:28 #: note_kfet/templates/oauth2_provider/authorize.html:29
msgid "Authorize" msgid "Authorize"
msgstr "Autoriser" msgstr "Autoriser"
@ -3203,7 +3209,7 @@ msgstr "Autoriser"
msgid "Application requires following permissions:" msgid "Application requires following permissions:"
msgstr "L'application requiert les permissions suivantes :" msgstr "L'application requiert les permissions suivantes :"
#: note_kfet/templates/oauth2_provider/authorize.html:35 #: note_kfet/templates/oauth2_provider/authorize.html:36
#: note_kfet/templates/oauth2_provider/authorized-oob.html:15 #: note_kfet/templates/oauth2_provider/authorized-oob.html:15
msgid "Error:" msgid "Error:"
msgstr "Erreur :" msgstr "Erreur :"
@ -3218,8 +3224,7 @@ msgstr "Merci de retourner à votre application et entrez ce code :"
#: note_kfet/templates/oauth2_provider/authorized-token-delete.html:9 #: note_kfet/templates/oauth2_provider/authorized-token-delete.html:9
msgid "Are you sure you want to delete this token?" msgid "Are you sure you want to delete this token?"
msgstr "" msgstr "Êtes-vous sûr⋅e de vouloir supprimer ce jeton ?"
"Êtes-vous sûr⋅e de vouloir supprimer ce jeton ?"
#: note_kfet/templates/oauth2_provider/authorized-tokens.html:7 #: note_kfet/templates/oauth2_provider/authorized-tokens.html:7
msgid "Tokens" msgid "Tokens"

View File

@ -12,14 +12,15 @@
<form id="authorizationForm" method="post"> <form id="authorizationForm" method="post">
<div class="card-body"> <div class="card-body">
<p>{% trans "Application requires following permissions:" %}</p> <p>{% trans "Application requires following permissions:" %}</p>
{% csrf_token %}
{{ form|crispy }}
<ul> <ul>
{% for scope in scopes_descriptions %} {% for scope in scopes_descriptions %}
<li>{{ scope }}</li> <li>{{ scope }}</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% csrf_token %}
{{ form|crispy }}
</div> </div>
<div class="card-footer text-center"> <div class="card-footer text-center">
<div class="control-group"> <div class="control-group">