diff --git a/passbook/core/templates/base/page.html b/passbook/core/templates/base/page.html index 3d6b6702d..27a793e28 100644 --- a/passbook/core/templates/base/page.html +++ b/passbook/core/templates/base/page.html @@ -40,7 +40,7 @@
- +
diff --git a/passbook/core/tests/test_views_authentication.py b/passbook/core/tests/test_views_authentication.py deleted file mode 100644 index 8cc9f1769..000000000 --- a/passbook/core/tests/test_views_authentication.py +++ /dev/null @@ -1,45 +0,0 @@ -"""passbook Core Account Test""" -import string -from random import SystemRandom - -from django.test import TestCase -from django.urls import reverse - -from passbook.core.models import User - - -class TestAuthenticationViews(TestCase): - """passbook Core Account Test""" - - def setUp(self): - super().setUp() - self.sign_up_data = { - "name": "Test", - "username": "beryjuorg", - "email": "unittest@passbook.beryju.org", - "password": "B3ryju0rg!", - "password_repeat": "B3ryju0rg!", - } - self.login_data = { - "uid_field": "unittest@example.com", - } - self.user = User.objects.create_superuser( - username="unittest user", - email="unittest@example.com", - password="".join( - SystemRandom().choice(string.ascii_uppercase + string.digits) - for _ in range(8) - ), - ) - - def test_logout_view(self): - """Test account.logout view""" - self.client.force_login(self.user) - response = self.client.get(reverse("passbook_core:auth-logout")) - self.assertEqual(response.status_code, 302) - - def test_sign_up_view_auth(self): - """Test account.sign_up view (Authenticated)""" - self.client.force_login(self.user) - response = self.client.get(reverse("passbook_core:auth-logout")) - self.assertEqual(response.status_code, 302) diff --git a/passbook/core/urls.py b/passbook/core/urls.py index de000d3a0..b4d7bd5fa 100644 --- a/passbook/core/urls.py +++ b/passbook/core/urls.py @@ -1,11 +1,9 @@ """passbook URL Configuration""" from django.urls import path -from passbook.core.views import authentication, overview, user +from passbook.core.views import overview, user urlpatterns = [ - # Authentication views - path("auth/logout/", authentication.LogoutView.as_view(), name="auth-logout"), # User views path("-/user/", user.UserSettingsView.as_view(), name="user-settings"), path("-/user/delete/", user.UserDeleteView.as_view(), name="user-delete"), diff --git a/passbook/core/views/authentication.py b/passbook/core/views/authentication.py deleted file mode 100644 index dea3ab1b4..000000000 --- a/passbook/core/views/authentication.py +++ /dev/null @@ -1,21 +0,0 @@ -"""passbook core authentication views""" -from django.contrib import messages -from django.contrib.auth import logout -from django.contrib.auth.mixins import LoginRequiredMixin -from django.http import HttpRequest, HttpResponse -from django.shortcuts import redirect, reverse -from django.utils.translation import ugettext as _ -from django.views import View -from structlog import get_logger - -LOGGER = get_logger() - - -class LogoutView(LoginRequiredMixin, View): - """Log current user out""" - - def dispatch(self, request: HttpRequest) -> HttpResponse: - """Log current user out""" - logout(request) - messages.success(request, _("You've successfully been logged out.")) - return redirect(reverse("passbook_flows:default-auth")) diff --git a/passbook/flows/migrations/0002_default_flows.py b/passbook/flows/migrations/0002_default_flows.py index 160c97544..e146b2532 100644 --- a/passbook/flows/migrations/0002_default_flows.py +++ b/passbook/flows/migrations/0002_default_flows.py @@ -8,7 +8,9 @@ from passbook.flows.models import FlowDesignation from passbook.stages.identification.models import Templates, UserFields -def create_default_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): +def create_default_authentication_flow( + apps: Apps, schema_editor: BaseDatabaseSchemaEditor +): Flow = apps.get_model("passbook_flows", "Flow") FlowStageBinding = apps.get_model("passbook_flows", "FlowStageBinding") PasswordStage = apps.get_model("passbook_stages_password", "PasswordStage") @@ -18,7 +20,11 @@ def create_default_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): ) db_alias = schema_editor.connection.alias - if Flow.objects.using(db_alias).all().exists(): + if ( + Flow.objects.using(db_alias) + .filter(designation=FlowDesignation.AUTHENTICATION) + .exists() + ): # Only create default flow when none exist return @@ -53,13 +59,46 @@ def create_default_flow(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): ) +def create_default_invalidation_flow( + apps: Apps, schema_editor: BaseDatabaseSchemaEditor +): + Flow = apps.get_model("passbook_flows", "Flow") + FlowStageBinding = apps.get_model("passbook_flows", "FlowStageBinding") + UserLogoutStage = apps.get_model("passbook_stages_user_logout", "UserLogoutStage") + db_alias = schema_editor.connection.alias + + if ( + Flow.objects.using(db_alias) + .filter(designation=FlowDesignation.INVALIDATION) + .exists() + ): + # Only create default flow when none exist + return + + if not UserLogoutStage.objects.using(db_alias).exists(): + UserLogoutStage.objects.using(db_alias).create(name="authentication") + + flow = Flow.objects.using(db_alias).create( + name="default-invalidation-flow", + slug="default-invalidation-flow", + designation=FlowDesignation.INVALIDATION, + ) + FlowStageBinding.objects.using(db_alias).create( + flow=flow, stage=UserLogoutStage.objects.using(db_alias).first(), order=0, + ) + + class Migration(migrations.Migration): dependencies = [ ("passbook_flows", "0001_initial"), ("passbook_stages_user_login", "0001_initial"), + ("passbook_stages_user_logout", "0001_initial"), ("passbook_stages_password", "0001_initial"), ("passbook_stages_identification", "0001_initial"), ] - operations = [migrations.RunPython(create_default_flow)] + operations = [ + migrations.RunPython(create_default_authentication_flow), + migrations.RunPython(create_default_invalidation_flow), + ] diff --git a/passbook/flows/migrations/0004_auto_20200510_2310.py b/passbook/flows/migrations/0004_auto_20200510_2310.py new file mode 100644 index 000000000..9b013bb5e --- /dev/null +++ b/passbook/flows/migrations/0004_auto_20200510_2310.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.5 on 2020-05-10 23:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('passbook_flows', '0003_auto_20200509_1258'), + ] + + operations = [ + migrations.AlterField( + model_name='flow', + name='designation', + field=models.CharField(choices=[('authentication', 'Authentication'), ('enrollment', 'Enrollment'), ('recovery', 'Recovery'), ('password_change', 'Password Change'), ('invalidation', 'Invalidation')], max_length=100), + ), + ] diff --git a/passbook/flows/models.py b/passbook/flows/models.py index d24df11f5..c82ab6e19 100644 --- a/passbook/flows/models.py +++ b/passbook/flows/models.py @@ -18,6 +18,7 @@ class FlowDesignation(models.TextChoices): ENROLLMENT = "enrollment" RECOVERY = "recovery" PASSWORD_CHANGE = "password_change" # nosec # noqa + INVALIDATION = "invalidation" class Stage(UUIDModel): diff --git a/passbook/flows/urls.py b/passbook/flows/urls.py index 48a1659ff..44b7cde00 100644 --- a/passbook/flows/urls.py +++ b/passbook/flows/urls.py @@ -15,6 +15,11 @@ urlpatterns = [ ToDefaultFlow.as_view(designation=FlowDesignation.AUTHENTICATION), name="default-auth", ), + path( + "-/default/invalidation/", + ToDefaultFlow.as_view(designation=FlowDesignation.INVALIDATION), + name="default-invalidation", + ), path( "-/default/recovery/", ToDefaultFlow.as_view(designation=FlowDesignation.RECOVERY), diff --git a/passbook/providers/oauth/templates/oauth2_provider/authorize.html b/passbook/providers/oauth/templates/oauth2_provider/authorize.html index f9ca84bf8..b80a05ea8 100644 --- a/passbook/providers/oauth/templates/oauth2_provider/authorize.html +++ b/passbook/providers/oauth/templates/oauth2_provider/authorize.html @@ -37,7 +37,7 @@ {% blocktrans with user=user %} You are logged in as {{ user }}. Not you? {% endblocktrans %} - {% trans 'Logout' %} + {% trans 'Logout' %}

diff --git a/passbook/providers/oidc/templates/oidc_provider/authorize.html b/passbook/providers/oidc/templates/oidc_provider/authorize.html index 6438d8a92..5a1fa1780 100644 --- a/passbook/providers/oidc/templates/oidc_provider/authorize.html +++ b/passbook/providers/oidc/templates/oidc_provider/authorize.html @@ -38,7 +38,7 @@ {% blocktrans with user=user %} You are logged in as {{ user }}. Not you? {% endblocktrans %} - {% trans 'Logout' %} + {% trans 'Logout' %}

diff --git a/passbook/providers/saml/templates/saml/idp/autosubmit_form.html b/passbook/providers/saml/templates/saml/idp/autosubmit_form.html index 54a198770..b43f243db 100644 --- a/passbook/providers/saml/templates/saml/idp/autosubmit_form.html +++ b/passbook/providers/saml/templates/saml/idp/autosubmit_form.html @@ -18,7 +18,7 @@ {% blocktrans with user=user %} You are logged in as {{ user }}. {% endblocktrans %} - {% trans 'Not you?' %} + {% trans 'Not you?' %}

diff --git a/passbook/providers/saml/templates/saml/idp/login.html b/passbook/providers/saml/templates/saml/idp/login.html index 1126d5bda..d4257cab7 100644 --- a/passbook/providers/saml/templates/saml/idp/login.html +++ b/passbook/providers/saml/templates/saml/idp/login.html @@ -16,7 +16,7 @@ {% blocktrans with user=user %} You are logged in as {{ user }}. {% endblocktrans %} - {% trans 'Not you?' %} + {% trans 'Not you?' %}

diff --git a/passbook/root/urls.py b/passbook/root/urls.py index 73adb5531..a418d097c 100644 --- a/passbook/root/urls.py +++ b/passbook/root/urls.py @@ -12,6 +12,9 @@ from passbook.root.monitoring import MetricsView LOGGER = get_logger() admin.autodiscover() admin.site.login = RedirectView.as_view(pattern_name="passbook_flows:default-auth") +admin.site.logout = RedirectView.as_view( + pattern_name="passbook_flows:default-invalidate" +) handler400 = error.BadRequestView.as_view() handler403 = error.ForbiddenView.as_view()