From 21cb467edcf298289126360ad19fb9599fb20d90 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Sat, 8 Jan 2022 15:47:04 +0100 Subject: [PATCH] Visually indicate the OpenID login process by improved design --- aleksis/core/static/public/style.scss | 12 +++++ .../templates/oauth2_provider/authorize.html | 11 ++++- .../core/templates/two_factor/core/login.html | 33 +++++++++++--- aleksis/core/urls.py | 5 +++ aleksis/core/views.py | 45 ++++++++++++++++++- 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/aleksis/core/static/public/style.scss b/aleksis/core/static/public/style.scss index 09ecb9c1a..4fb6d9b28 100644 --- a/aleksis/core/static/public/style.scss +++ b/aleksis/core/static/public/style.scss @@ -804,3 +804,15 @@ main figure.alert { height: 24px; margin-bottom: 8px; } + +.application-circle { + border-radius: 50%; + width: 20vh; + height: 20vh; +} + + +.application-circle img { + @extend .application-circle; + object-fit: cover; +} diff --git a/aleksis/core/templates/oauth2_provider/authorize.html b/aleksis/core/templates/oauth2_provider/authorize.html index 48b996837..c90d5e8dd 100644 --- a/aleksis/core/templates/oauth2_provider/authorize.html +++ b/aleksis/core/templates/oauth2_provider/authorize.html @@ -12,8 +12,15 @@ <div class="col s12 m10 l8 xl6"> <div class="card"> <div class="card-content"> - <div class="card-title"> - {% trans "Authorize" %} {{ application.name }} + {% if application.icon %} + <div class="center-via-flex margin-bottom"> + <div class="application-circle materialboxed z-depth-2"> + <img src="{{ application.icon.url }}" alt="{{ application.name }}" class="hundred-percent"> + </div> + </div> + {% endif %} + <div class="card-title {% if application.icon %}center{% endif %}"> + {% blocktrans with name=application.name %}Authorize {{ name }}{% endblocktrans %} </div> <p class="margin-bottom">{% trans "The application requests access to the following scopes:" %}</p> {% for scope in scopes_descriptions %} diff --git a/aleksis/core/templates/two_factor/core/login.html b/aleksis/core/templates/two_factor/core/login.html index 9ea4bc6c2..834c4b98b 100644 --- a/aleksis/core/templates/two_factor/core/login.html +++ b/aleksis/core/templates/two_factor/core/login.html @@ -16,7 +16,17 @@ <div class="col s12 m10 l8 xl6"> <div class="card"> <div class="card-content"> - {% if wizard.steps.current == 'auth' and socialaccount_providers %} + {% if oauth and oauth_application.icon %} + <div class="center-via-flex margin-bottom"> + <div class="application-circle materialboxed z-depth-2"> + <img src="{{ oauth_application.icon.url }}" alt="{{ oauth_application.name }}" + class="hundred-percent"> + </div> + </div> + <div class="card-title center"> + {% blocktrans with name=oauth_application.name %}Login for {{ name }}{% endblocktrans %} + </div> + {% elif wizard.steps.current == 'auth' and socialaccount_providers %} <div class="card-title">{% trans "Login with username and password" %}</div> {% else %} <div class="card-title">{% trans "Login" %}</div> @@ -30,12 +40,21 @@ </p> </div> {% elif wizard.steps.current == 'auth' %} - <div class="alert primary"> - <p> - <i class="material-icons left">info</i> - {% blocktrans %}Please login to see this page.{% endblocktrans %} - </p> - </div> + {% if oauth %} + <div class="alert primary"> + <p> + <i class="material-icons left">info</i> + {% blocktrans %}Please login with your account to use the external application.{% endblocktrans %} + </p> + </div> + {% else %} + <div class="alert primary"> + <p> + <i class="material-icons left">info</i> + {% blocktrans %}Please login to see this page.{% endblocktrans %} + </p> + </div> + {% endif %} {% endif %} {% if not wizard.steps.current == "auth" %} <div class="alert primary"> diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py index 753d95085..b5dcb004d 100644 --- a/aleksis/core/urls.py +++ b/aleksis/core/urls.py @@ -134,6 +134,11 @@ urlpatterns = [ views.OAuth2EditView.as_view(), name="edit_oauth2_application", ), + path( + "oauth/authorize/", + views.CustomAuthorizationView.as_view(), + name="oauth2_provider:authorize", + ), path("oauth/", include("oauth2_provider.urls", namespace="oauth2_provider")), path("__i18n__/", include("django.conf.urls.i18n")), path( diff --git a/aleksis/core/views.py b/aleksis/core/views.py index cfb9cd5b3..6354751aa 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -1,6 +1,6 @@ from textwrap import wrap from typing import Any, Dict, Optional, Type -from urllib.parse import urlencode +from urllib.parse import urlencode, urlparse, urlunparse from django.apps import apps from django.conf import settings @@ -18,6 +18,7 @@ from django.http import ( HttpResponseRedirect, HttpResponseServerError, JsonResponse, + QueryDict, ) from django.shortcuts import get_object_or_404, redirect, render from django.template import loader @@ -50,6 +51,9 @@ from haystack.query import SearchQuerySet from haystack.utils.loading import UnifiedIndex from health_check.views import MainView from invitations.views import SendInvite, accept_invitation +from oauth2_provider.exceptions import OAuthToolkitError +from oauth2_provider.models import get_application_model +from oauth2_provider.views import AuthorizationView from reversion import set_user from reversion.views import RevisionMixin from rules import test_rule @@ -1460,3 +1464,42 @@ class LoginView(AllAuthLoginView): return render(self.request, "account/verification_sent.html") return super().done(form_list, **kwargs) + + def get_context_data(self, form, **kwargs): + """Override context data to hide side menu and include OAuth2 application if given.""" + context = super().get_context_data(form, **kwargs) + if self.request.GET.get("oauth"): + context["no_menu"] = True + + if self.request.GET.get("client_id"): + application = get_application_model().objects.get( + client_id=self.request.GET["client_id"] + ) + context["oauth_application"] = application + return context + + +class CustomAuthorizationView(AuthorizationView): + def handle_no_permission(self): + """Override handle_no_permission to provide OAuth2 information to login page.""" + redirect_obj = super().handle_no_permission() + + try: + scopes, credentials = self.validate_authorization_request(self.request) + except OAuthToolkitError as error: + # Application is not available at this time. + return self.error_response(error, application=None) + + login_url_parts = list(urlparse(redirect_obj.url)) + querystring = QueryDict(login_url_parts[4], mutable=True) + querystring["oauth"] = "yes" + querystring["client_id"] = credentials["client_id"] + login_url_parts[4] = querystring.urlencode(safe="/") + + return HttpResponseRedirect(urlunparse(login_url_parts)) + + def get_context_data(self, **kwargs): + """Override context data to hide side menu.""" + context = super().get_context_data(**kwargs) + context["no_menu"] = True + return context -- GitLab