From e1cbca31b63899152bad552f253146007bec39eb Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Mon, 28 Jun 2021 18:20:34 +0200 Subject: [PATCH 1/8] setup django-mfa3 --- castellum/settings/default.py | 6 ++++++ castellum/urls.py | 3 ++- setup.cfg | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/castellum/settings/default.py b/castellum/settings/default.py index 42427d9cf..714226159 100644 --- a/castellum/settings/default.py +++ b/castellum/settings/default.py @@ -29,6 +29,7 @@ INSTALLED_APPS = [ 'phonenumber_field', 'parler', 'stronghold', + 'mfa', 'castellum.utils', 'castellum.castellum_auth', @@ -247,6 +248,11 @@ BOOTSTRAP4 = { AXES_LOCKOUT_TEMPLATE = 'axes-lockout.html' +# Two factor authentication +# See https://github.com/xi/django-mfa3 +MFA_SITE_TITLE = 'Castellum' +MFA_DOMAIN = None + # Secondary language in emails for readers who do not understand the # primary language diff --git a/castellum/urls.py b/castellum/urls.py index 2ee160875..3e1b90a75 100644 --- a/castellum/urls.py +++ b/castellum/urls.py @@ -25,7 +25,6 @@ from django.conf import settings from django.contrib import admin from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin -from django.contrib.auth.views import LoginView from django.contrib.auth.views import LogoutView from django.http import HttpResponse from django.urls import include @@ -35,6 +34,7 @@ from django.views.generic import TemplateView from django.views.i18n import JavaScriptCatalog from django.views.static import serve +from mfa.views import LoginView from stronghold.decorators import public from castellum.castellum_auth.forms import AuthenticationForm @@ -103,6 +103,7 @@ urlpatterns = [ path( 'data-protection/', include('castellum.data_protection.urls', namespace='data_protection') ), + path('mfa/', include('mfa.urls', namespace='mfa')), ] if settings.PROTECTED_MEDIA_SERVER: diff --git a/setup.cfg b/setup.cfg index e89f5bd0e..438d0d14b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,6 +15,7 @@ install_requires = Django == 3.2.5 django-bootstrap4 == 3.0.1 django-ical == 1.8.0 + django-mfa3 == 0.2.2 django-npm == 1.0.0 django-parler == 2.2.0 django-phonenumber-field == 5.2.0 -- GitLab From aa0d7ce61e08878cc0cb2aff5f1df63a8b005377 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Wed, 30 Jun 2021 16:47:13 +0200 Subject: [PATCH 2/8] setup cbor-js --- castellum/settings/default.py | 3 +++ package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/castellum/settings/default.py b/castellum/settings/default.py index 714226159..9bfd47464 100644 --- a/castellum/settings/default.py +++ b/castellum/settings/default.py @@ -239,6 +239,9 @@ NPM_FILE_PATTERNS = { 'main.css', 'locales/de.js', ], + 'cbor-js': [ + 'cbor.js', + ], } BOOTSTRAP4 = { diff --git a/package.json b/package.json index 21c95fb11..2f1cdcb00 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@fortawesome/fontawesome-free": "^5.15.3", "@ttskch/select2-bootstrap4-theme": "^1.5.2", "bootstrap": "^4.6.0", + "cbor-js": "^0.1.0", "fullcalendar-scheduler": "^5.8.0", "jdenticon": "^3.1.0", "jquery": "^3.6.0", -- GitLab From 3a0782677de9d17c9b3971bc49fa18c1817281d6 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Mon, 28 Jun 2021 19:20:30 +0200 Subject: [PATCH 3/8] exclude MFAKey model from tests --- tests/studies/views/test_diff_view.py | 1 + tests/subjects/views/test_subject_export.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/studies/views/test_diff_view.py b/tests/studies/views/test_diff_view.py index 8dd46c6a0..a1629544a 100644 --- a/tests/studies/views/test_diff_view.py +++ b/tests/studies/views/test_diff_view.py @@ -15,6 +15,7 @@ EXCLUDED = [ 'contacts.', 'contenttypes.', 'geofilters.Geolocation.', + 'mfa.MFAKey.', 'pseudonyms.Pseudonym.', 'recruitment.AttributeCategory.', 'recruitment.AttributeCategoryTranslation.', diff --git a/tests/subjects/views/test_subject_export.py b/tests/subjects/views/test_subject_export.py index 0990416b5..f6031bc67 100644 --- a/tests/subjects/views/test_subject_export.py +++ b/tests/subjects/views/test_subject_export.py @@ -26,6 +26,7 @@ EXCLUDED = [ 'contacts.Street.', 'contenttypes.', 'geofilters.Geolocation.', + 'mfa.MFAKey.', 'pseudonyms.Domain.', 'pseudonyms.Pseudonym.', 'recruitment.AttributeCategory.', -- GitLab From 9e805112f0dc5ae64ba806511b457701dbe68479 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Mon, 28 Jun 2021 19:03:45 +0200 Subject: [PATCH 4/8] link to mfa:list from index --- castellum/static/images/circle-icons/key.png | Bin 0 -> 5807 bytes castellum/templates/index.html | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 castellum/static/images/circle-icons/key.png diff --git a/castellum/static/images/circle-icons/key.png b/castellum/static/images/circle-icons/key.png new file mode 100644 index 0000000000000000000000000000000000000000..89d0d935cbdd99d169a887549c9a4edc312a091f GIT binary patch literal 5807 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 IC-MIO1?@qUkN^Mx literal 0 HcmV?d00001 diff --git a/castellum/templates/index.html b/castellum/templates/index.html index 0688a043b..bdb8a710e 100644 --- a/castellum/templates/index.html +++ b/castellum/templates/index.html @@ -56,6 +56,17 @@ {% endif %} + + {% if user.is_staff or user.is_superuser %}
-- GitLab From 87698bed755c70aa2bee5bea4328265ab5723b54 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Mon, 28 Jun 2021 20:23:42 +0200 Subject: [PATCH 5/8] install cryptograpy from alpine to avoid having to build it --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index dba4c9390..1fb402d78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ FROM alpine:3.13.5 ENV PYTHONUNBUFFERED 1 ENV BUILDPKGS gettext py3-pip py3-wheel -ENV RUNTIMEPKGS uwsgi uwsgi-python uwsgi-router_static python3 py3-psycopg2 py3-pyldap libmagic proj gdal +ENV RUNTIMEPKGS uwsgi uwsgi-python uwsgi-router_static python3 py3-psycopg2 py3-pyldap py3-cryptography libmagic proj gdal RUN adduser -D -g '' uwsgi -- GitLab From f5a03d6fcea7596b47560bc17b0f49884bc88ea3 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Tue, 29 Jun 2021 18:12:05 +0200 Subject: [PATCH 6/8] use mfa public decorator --- castellum/urls.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/castellum/urls.py b/castellum/urls.py index 3e1b90a75..2b9f94d66 100644 --- a/castellum/urls.py +++ b/castellum/urls.py @@ -34,6 +34,7 @@ from django.views.generic import TemplateView from django.views.i18n import JavaScriptCatalog from django.views.static import serve +from mfa.decorators import public as mfa_public from mfa.views import LoginView from stronghold.decorators import public @@ -85,13 +86,13 @@ urlpatterns = [ template_name="login.html", authentication_form=AuthenticationForm, ), name='login'), - path('logout/', LogoutView.as_view(), name='logout'), - path('favicon.ico', public(RedirectView.as_view(url='/static/images/favicon.ico'))), + path('logout/', mfa_public(LogoutView.as_view()), name='logout'), + path('favicon.ico', mfa_public(public(RedirectView.as_view(url='/static/images/favicon.ico')))), path('ping/', dummy, name='ping'), path('feeds/', FeedsView.as_view(), name='feeds'), - path('i18n/', set_language, name='set_language'), - path('jsi18n/', public(JavaScriptCatalog.as_view()), name='javascript-catalog'), + path('i18n/', mfa_public(set_language), name='set_language'), + path('jsi18n/', mfa_public(public(JavaScriptCatalog.as_view())), name='javascript-catalog'), path('admin/', admin.site.urls), path('studies/', include('castellum.studies.urls', namespace='studies')), -- GitLab From e1b3b479f3198ee22e063ab964b0540ce0437ca5 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Mon, 28 Jun 2021 18:55:53 +0200 Subject: [PATCH 7/8] overwrite templates --- castellum/templates/mfa/auth_FIDO2.html | 24 ++++++++++++ castellum/templates/mfa/auth_TOTP.html | 19 ++++++++++ castellum/templates/mfa/base.html | 6 +++ castellum/templates/mfa/create_FIDO2.html | 25 +++++++++++++ castellum/templates/mfa/create_TOTP.html | 30 +++++++++++++++ .../templates/mfa/mfakey_confirm_delete.html | 11 ++++++ castellum/templates/mfa/mfakey_list.html | 37 +++++++++++++++++++ 7 files changed, 152 insertions(+) create mode 100644 castellum/templates/mfa/auth_FIDO2.html create mode 100644 castellum/templates/mfa/auth_TOTP.html create mode 100644 castellum/templates/mfa/base.html create mode 100644 castellum/templates/mfa/create_FIDO2.html create mode 100644 castellum/templates/mfa/create_TOTP.html create mode 100644 castellum/templates/mfa/mfakey_confirm_delete.html create mode 100644 castellum/templates/mfa/mfakey_list.html diff --git a/castellum/templates/mfa/auth_FIDO2.html b/castellum/templates/mfa/auth_FIDO2.html new file mode 100644 index 000000000..925badbe2 --- /dev/null +++ b/castellum/templates/mfa/auth_FIDO2.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% load static i18n %} + +{% block title %}{% translate 'Two-factor authentication' %} · {{ block.super }}{% endblock %} + +{% block content %} +
+

{% translate 'Two-factor authentication' %}

+

{% translate 'When you are ready to authenticate with FIDO2, press the button below.' %}

+ +
+ {% csrf_token %} + {% include 'utils/form_errors.html' with form=form %} + {{ form.code.as_hidden }} + + {% translate 'Use TOTP instead' %} +
+
+{% endblock %} + +{% block extra_scripts %} + + +{% endblock %} diff --git a/castellum/templates/mfa/auth_TOTP.html b/castellum/templates/mfa/auth_TOTP.html new file mode 100644 index 000000000..93cc05023 --- /dev/null +++ b/castellum/templates/mfa/auth_TOTP.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% load static i18n bootstrap4 %} + +{% block title %}{% translate 'Two-factor authentication' %} · {{ block.super }}{% endblock %} + +{% block content %} +
+

{% translate 'Two-factor authentication' %}

+

{% translate 'Open your TOTP app to get an authentication code.' %}

+ +
+ {% csrf_token %} + {% include 'utils/form_errors.html' with form=form %} + {% bootstrap_field form.code %} + + {% translate 'Use FIDO2 instead' %} +
+
+{% endblock %} diff --git a/castellum/templates/mfa/base.html b/castellum/templates/mfa/base.html new file mode 100644 index 000000000..5397e87cb --- /dev/null +++ b/castellum/templates/mfa/base.html @@ -0,0 +1,6 @@ +{% extends "base_with_breadcrumbs.html" %} +{% load i18n %} + +{% block breadcrumbs %} + +{% endblock %} diff --git a/castellum/templates/mfa/create_FIDO2.html b/castellum/templates/mfa/create_FIDO2.html new file mode 100644 index 000000000..135d17cf3 --- /dev/null +++ b/castellum/templates/mfa/create_FIDO2.html @@ -0,0 +1,25 @@ +{% extends "mfa/base.html" %} +{% load static i18n bootstrap4%} + +{% block title %}{% translate 'Add FIDO2 key' %} · {{ block.super }}{% endblock %} + +{% block breadcrumbs %} + {{ block.super }} + +{% endblock %} + +{% block content %} +
+ {% csrf_token %} + {% include 'utils/form_errors.html' with form=form %} + {% bootstrap_field form.name %} +

{% translate 'You will be prompted to activate the device once you click "create".' %}

+ {{ form.code.as_hidden }} + +
+{% endblock %} + +{% block extra_scripts %} + + +{% endblock %} diff --git a/castellum/templates/mfa/create_TOTP.html b/castellum/templates/mfa/create_TOTP.html new file mode 100644 index 000000000..04eca9afa --- /dev/null +++ b/castellum/templates/mfa/create_TOTP.html @@ -0,0 +1,30 @@ +{% extends "mfa/base.html" %} +{% load static i18n bootstrap4 mfa %} + +{% block title %}{% translate 'Add TOTP key' %} · {{ block.super }}{% endblock %} + +{% block breadcrumbs %} + {{ block.super }} + +{% endblock %} + +{% block content %} +
+ {% csrf_token %} + {% include 'utils/form_errors.html' with form=form %} + {% bootstrap_field form.name %} + +
+
+

{% translate 'Scan the QR-code with your TOTP app and enter a valid code to finish registration.' %}

+ + + + {% bootstrap_field form.code %} +
+
+ +
+{% endblock %} diff --git a/castellum/templates/mfa/mfakey_confirm_delete.html b/castellum/templates/mfa/mfakey_confirm_delete.html new file mode 100644 index 000000000..fe1ec7dd0 --- /dev/null +++ b/castellum/templates/mfa/mfakey_confirm_delete.html @@ -0,0 +1,11 @@ +{% extends "mfa/base.html" %} +{% load i18n %} + +{% block content %} +

{% blocktrans with name=object.name %}Are you sure you want to delete the key "{{ name }}"?{% endblocktrans %}

+
+ {% csrf_token %} + {% translate 'Cancel' %} + +
+{% endblock %} diff --git a/castellum/templates/mfa/mfakey_list.html b/castellum/templates/mfa/mfakey_list.html new file mode 100644 index 000000000..a638018e1 --- /dev/null +++ b/castellum/templates/mfa/mfakey_list.html @@ -0,0 +1,37 @@ +{% extends "mfa/base.html" %} +{% load i18n %} + +{% block content %} +
+
+
+ {% if object_list %} + {% translate 'Login keys configured' %} + {% else %} + {% translate 'No login keys configured' %} + {% endif %} +
+ +

{% translate 'Two-factor authentication adds an additional layer of security to your account by requiring more than just a password to log in.' %}

+ +
    + {% for key in object_list %} +
  • +
    + {{ key.name }} + {{ key.method }} +
    + +
  • + {% endfor %} +
+ + +
+
+{% endblock %} -- GitLab From cc95e72e8407c50123f88fde625feb209e83040f Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Mon, 5 Jul 2021 10:19:15 +0200 Subject: [PATCH 8/8] document mfa settings --- docs/example_deployment/settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/example_deployment/settings.py b/docs/example_deployment/settings.py index 70ac99fbe..6dbb1e24a 100644 --- a/docs/example_deployment/settings.py +++ b/docs/example_deployment/settings.py @@ -34,6 +34,10 @@ PROTECTED_MEDIA_SERVER = 'uwsgi' # The example deployment does not contain a mail server, so use dummy instead EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +# See https://github.com/xi/django-mfa3 +MFA_DOMAIN = 'example.com' +MFA_SITE_TITLE = 'Castellum Demo' + # See https://docs.djangoproject.com/en/stable/topics/logging/ ADMINS = [('admin', 'admin@example.com')] LOGGING = { -- GitLab