Skip to content

Commit

Permalink
Merge pull request #535 from DH-IT-Portal-Development/acceptation
Browse files Browse the repository at this point in the history
Acceptation to develop[
  • Loading branch information
tymees authored Sep 7, 2023
2 parents ea08b69 + 7e27e02 commit 57a4794
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 107 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ __pycache__/

### Project-specific ###
media/
certs/
fetc/ldap_settings.py
fetc/saml_settings.py
*.sqlite3

### Coverage ###
Expand Down
90 changes: 90 additions & 0 deletions fetc/saml_settings.example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Copy this file to saml_settings.py if you want to use local SAML
This will 1) enable SAML in settings.py and 2) configure the SAML library to
use your local Development IdP.
For more information on the DevIdP, please consult its Github page:
https://github.com/CentreForDigitalHumanities/Development-IdP
You'll also need some certs, this code assumes they are located in a 'certs'
dir at the project-root. These certs can either be borrowed from the Dev-IdP
project or generated by hand. For the latter, see the CDH Docs.
These certs are used for signing the SAML data from this app to the IdP.
For detailed documentation on SAML and the CDH Federated Auth library, please
consult the CDH Federated Authentication docs:
https://centrefordigitalhumanities.github.io/Federated-Authentication-Docs/
"""
import os

# Import all default SAML settings from the library, we override some later
# Tip: the imported file also contains a lot of docs, which might be nice to
# read also
from cdh.federated_auth.saml.settings import *

# Used to get the full path of <project_root>
_BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# This dict is used to map attributes send by the IdP to the attributes used
# in this app's user model. They key is the name of the attribute as sent by
# the IdP, the value is a tuple with the name of the field on the user model
# See also:
# https://djangosaml2.readthedocs.io/contents/setup.html#users-attributes-and-account-linking
SAML_ATTRIBUTE_MAPPING = {
'uuShortID': ('username',),
'mail': ('email',),
'givenName': ('first_name',),
'uuPrefixedSn': ('last_name',),
# TODO: create an attribute on the user model to store this value
# 'uuLegacyDepartment': (),
}

# Controls which mechanism is used to exchange SAML data with the IdP
# Either POST or REDIRECT. POST is generally preferred, as REDIRECT can run
# into problems as it encodes the SAML data into the URL.
SAML_DEFAULT_BINDING = saml2.BINDING_HTTP_POST

# Use the helper function to generate the SAML_CONFIG.
# This is the main setting used to set up SAML
SAML_CONFIG = create_saml_config(
# This should be the URL of the ethics app (with protocol). Currently
# localhost, port 8000. Please change if you run the app on a different
# hostname/port
# Note that localhost and 127.0.0.1 are not interchangeable here
base_url='http://localhost:8000/',
# The name of the app, does not _really_ matter
name='FEtC-H Portal',
# The full location of the private key of the cert, currently
# <project_root>/certs/private.key
key_file=os.path.join(_BASE_DIR, 'certs/private.key'),
# The full location of the certificate, currently
# <project_root>/certs/private.key
cert_file=os.path.join(_BASE_DIR, 'certs/public.cert'),
# The location of the IdP's metadata
# The current value is valid for the Development IdP, if run at port 7000
# If you run it in a different place/port, please update
# If you use a different IdP, find its metadata URL and copy/paste it here
idp_metadata='http://localhost:7000/saml/idp/metadata/',
# If set to True, the app will allow login attempts not requested by the app
# This _can_ happen if a user logs in directly from the IdP. Currently set
# to true, as the DevIdP can sometimes do funky stuff with the session ID
allow_unsolicited=True,
# A list of attributes the IdP needs to provide for the app to authenticate
# Uses the naming of the IdP, not the internal names in Django
required_attributes=['uuShortID', 'mail', 'givenName', 'uuPrefixedSn'],
# A list of nice-to-have attributes from the IdP
# Uses the naming of the IdP, not the internal names in Django
optional_attributes=['uuLegacyDepartment', ],
# Contact info for this app; will be added to the app's metadata and is
# generally used by the IdP admins to contact all app-admins if they change
# something.
contact_given_name='Humanities IT Portal Development',
contact_email='[email protected]',
)

# Add the SAML auth backend to the list of enabled backends.
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'djangosaml2.backends.Saml2Backend',
)
32 changes: 28 additions & 4 deletions fetc/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"""
import os

from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
Expand All @@ -28,7 +29,7 @@

# Application definition

INSTALLED_APPS = (
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
Expand Down Expand Up @@ -56,9 +57,9 @@

'django.contrib.admin',
'django_user_agents',
)
]

MIDDLEWARE = (
MIDDLEWARE = [
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
Expand All @@ -70,7 +71,7 @@
'django.middleware.security.SecurityMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
'impersonate.middleware.ImpersonateMiddleware',
)
]

TEMPLATES = [
{
Expand All @@ -92,6 +93,16 @@

LOGIN_REDIRECT_URL = '/'

# Determines what login options are displayed on the landing page. NOTE: this
# does not determine which login screen is actually used as default when using
# a LoginRequiredMixin or similar.
# Django login is also used by LDAP auth
# SHOW_SAML_LOGIN is set to true if saml_settings.py is present and loaded
SHOW_DJANGO_LOGIN = True
SHOW_SAML_LOGIN = False
# Debug option, adds a label to the buttons. Otherwise, the buttons are
# identical
SHOW_LOGIN_DESCRIPTORS = DEBUG

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
Expand Down Expand Up @@ -171,3 +182,16 @@
from .ldap_settings import *
except ImportError:
print('Proceeding without LDAP settings')

try:
from .saml_settings import *

# Only add stuff to settings if we actually have SAML settings
INSTALLED_APPS += SAML_APPS
MIDDLEWARE += SAML_MIDDLEWARE

LOGIN_URL = reverse_lazy('saml-login')
SHOW_SAML_LOGIN = True

except ImportError:
print('Proceeding without SAML settings')
25 changes: 24 additions & 1 deletion fetc/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@


urlpatterns = [
# Always keep the default login view available, just to be sure
# We set the correct login view (this or SAML) in settings
path('accounts/login/', auth_views.LoginView.as_view(), name='login'),
path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'),

# Access user uploads
path('media/<str:filename>',
Expand Down Expand Up @@ -52,6 +53,28 @@
path('__debug__/', include(debug_toolbar.urls)),
)

# If SAML is enabled, add the required URL patterns for SAML
if 'cdh.federated_auth' in settings.INSTALLED_APPS:
from djangosaml2.views import LoginView
from cdh.federated_auth.saml.views import LogoutInitView

urlpatterns.extend([
path('saml/login/', LoginView.as_view(), name='saml-login'),
# We can only have one logout view. Luckily, the SAML logout view can
# handle local accounts as well.
path('saml/logout/', LogoutInitView.as_view(), name='logout'),
path('saml/', include('djangosaml2.urls')),
])
else:
# If not, append the default logout-view
urlpatterns.append(
path(
'accounts/logout/',
auth_views.LogoutView.as_view(),
name='logout'
),
)

admin.site.site_header = 'FETC-GW'
admin.site.site_title = 'FETC-GW administratie'
admin.site.index_title = 'FETC-GW administratie'
78 changes: 43 additions & 35 deletions locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,11 @@ msgstr ""
msgid "Feedback verstuurd"
msgstr "Feedback sent"

#: fetc/settings.py:121
#: fetc/settings.py:122
msgid "Nederlands"
msgstr "Dutch"

#: fetc/settings.py:122
#: fetc/settings.py:123
msgid "Engels"
msgstr "English"

Expand Down Expand Up @@ -333,7 +333,7 @@ msgstr "This field is required."

#: main/menus.py:5 main/templates/base/menu.html:7
#: main/templates/main/index.html:7 main/templates/main/index.html:24
#: main/templates/registration/login.html:35
#: main/templates/main/landing.html:34
msgid "Startpagina"
msgstr "Start page"

Expand Down Expand Up @@ -684,8 +684,9 @@ msgstr "Log out"
msgid "FETC-GW-website"
msgstr "FEtC-H website"

#: main/templates/base/menu.html:152 main/templates/registration/login.html:67
#: main/templates/registration/login.html:79
#: main/templates/base/menu.html:152 main/templates/main/landing.html:77
#: main/templates/registration/login.html:31
#: main/templates/registration/login.html:48
msgid "Inloggen"
msgstr "Log in"

Expand Down Expand Up @@ -1019,66 +1020,76 @@ msgstr "Give feedback on this portal"
msgid "Bannerfoto door Kim O'leary"
msgstr "Cover image by Kim O'leary"

#: main/templates/registration/logged_out.html:12
msgid "Je bent succesvol uitgelogd."
msgstr "You have successfully logged out."

#: main/templates/registration/logged_out.html:17
#, python-format
#: main/templates/main/landing.html:52
msgid ""
"Klik <a href=\"%(login_url)s\">hier</a> om opnieuw in te loggen met je "
"Solis-ID."
"Welkom bij het portal van de Facultaire Ethische Toetsingscommissie "
"Geesteswetenschappen (FETC-GW)."
msgstr ""
"Click <a href=\"%(login_url)s\">here</a> to log in again with your Solis-ID."
"Welcome to the portal of the Faculty Ethics assessment Committee Humanities "
"(FEtC-H)"

#: main/templates/main/landing.html:58
#: main/templates/registration/logged_out.html:22
#: main/templates/registration/login.html:48
msgid ""
"Klik <a href=\"http://fetc-gw.wp.hum.uu.nl\">hier</a> om terug te keren naar "
"de FETC-GW-website."
msgstr ""
"Click <a href=\"http://fetc-gw.wp.hum.uu.nl/en/\">here</a> to return to the "
"FEtC-H website."

#: main/templates/registration/login.html:42
msgid ""
"Welkom bij het portal van de Facultaire Ethische Toetsingscommissie "
"Geesteswetenschappen (FETC-GW)."
msgstr ""
"Welcome to the portal of the Faculty Ethics assessment Committee Humanities "
"(FEtC-H)"

#: main/templates/registration/login.html:52
#: main/templates/main/landing.html:62
msgid "Contact"
msgstr "Contact"

#: main/templates/registration/login.html:54
#: main/templates/main/landing.html:64
msgid "Secretaris FETC-GW"
msgstr "FEtC-H Secretary"

#: main/templates/registration/login.html:56
#: main/templates/registration/login.html:62
#: main/templates/main/landing.html:66 main/templates/main/landing.html:72
msgid "Om hier een e-mail adres te zien moet Javascript aan staan"
msgstr "Javascript needs to be enabled to see the email address"

#: main/templates/registration/login.html:60
#: main/templates/main/landing.html:70
msgid "Technische ondersteuning"
msgstr "Technical support"

#: main/templates/registration/login.html:70
#: main/templates/main/landing.html:79
msgid ""
"Om in te loggen heb je een Solis-ID nodig. Heb je geen Solis-ID, neem dan "
"contact op met de secretaris van de FETC-GW."
msgstr ""
"You need a Solis-ID to log in. If you do not have a Solis ID, please contact "
"the secretary of the FEtC-H."

#: main/templates/main/landing.html:86 main/templates/main/landing.html:91
msgid "Log in met je Solis-ID"
msgstr "Log in with your Solis-ID"

#: main/templates/registration/logged_out.html:12
msgid "Je bent succesvol uitgelogd."
msgstr "You have successfully logged out."

#: main/templates/registration/logged_out.html:17
#, python-format
msgid ""
"Klik <a href=\"%(landing_url)s\">hier</a> om naar de startpagina te gaan."
msgstr ""
"Click <a href=\"%(landing_url)s\">here</a> to return to the start page."

#: main/templates/registration/login.html:39
msgid ""
"Gebruikersnaam of wachtwoord incorrect. Probeer het alstublieft opnieuw."
msgstr "Username or password incorrect. Please try again."

#: main/templates/registration/login.html:74
#: main/templates/registration/login.html:43
msgid "Je kan hier inloggen met je Solis-ID en wachtwoord."
msgstr "You can log in here with your Solis-ID and password."

#: main/templates/registration/login.html:77
#: main/templates/registration/login.html:46
msgid "Gebruikersnaam"
msgstr "Username"

#: main/templates/registration/login.html:78
#: main/templates/registration/login.html:47
msgid "Wachtwoord"
msgstr "Password"

Expand Down Expand Up @@ -5879,6 +5890,3 @@ msgstr "Task edited"
#: tasks/views/task_views.py:50
msgid "Taak verwijderd"
msgstr "Task deleted"

#~ msgid "eindverantwoordelijke"
#~ msgstr "Researcher with final responsibility"
3 changes: 2 additions & 1 deletion main/menus.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from menu import Menu, MenuItem

Menu.add_item("home", MenuItem(_('Startpagina'),
Expand All @@ -8,7 +9,7 @@
))

Menu.add_item("footer", MenuItem(_('Log in'),
reverse('login'),
settings.LOGIN_URL,
check=lambda x: not x.user.is_authenticated
))

Expand Down
Loading

0 comments on commit 57a4794

Please sign in to comment.