Configuration options

Configuration settings

Most important settings

HELMHOLTZ_ALLOWED_VOS

A string of lists specifying which VOs are allowed to log into the website.

HELMHOLTZ_CLIENT_ID

Client id for the Helmholtz AAI

HELMHOLTZ_CLIENT_SECRET

Client secret for the Helmholtz AAI

Two settings are necessary to use this package, this is the HELMHOLTZ_CLIENT_ID and the HELMHOLTZ_CLIENT_SECRET that you specified during the OAuth-Client registration (see Register your OAuth-Client at the Helmholtz AAI).

By default, the website allows all users to login and create an account via the Helmholtz AAI. This if often not desired and you can modify this with the HELMHOLTZ_ALLOWED_VOS setting, e.g. something like:

HELMHOLTZ_ALLOWED_VOS = [
    "urn:geant:helmholtz.de:group:hereon#login.helmholtz.de",
]

in your settings.py.

Other settings

Further settings can be used to specify how to connect to the helmholtz AAI and how to interpret the userinfo of the Helmholtz AAI.

HELMHOLTZ_AAI_CONF_URL

openid configuration url of the Helmholtz AAI

HELMHOLTZ_ALLOWED_VOS_REGEXP

Regular expressions for VOs that are allowed to login to the website.

HELMHOLTZ_CLIENT_KWS

Keyword argument for the oauth client to connect with the helmholtz AAI.

HELMHOLTZ_CREATE_USERS

Flag to enable/disable user account creation via the Helmholtz AAI.

HELMHOLTZ_EMAIL_DUPLICATES_ALLOWED

Allow duplicated emails for users in the website

HELMHOLTZ_MAP_ACCOUNTS

Flag whether existing user accounts should be mapped

HELMHOLTZ_UPDATE_USERNAME

Flag whether usernames should be updated from the Helmholtz AAI

HELMHOLTZ_USERNAME_FIELDS

Username fields in the userinfo

HELMHOLTZ_USER_BACKEND

The backend that is used to login the user.

ROOT_URL

Root url for the django application

Customizing the login

If you are using the Helmholtz AAI, you likely want to combine it with the permission system of your Django project. You may want to set the is_staff attribute for users of a specific VO, or perform additional actions when a user logged in for the first time (e.g. send a welcome mail), enters or leaves a VO.

To perfectly adjust the django-helmholtz-aai framework to your projects need, you have two choices:

  1. connect to the signals of the signals module, see Configuration via Signals

  2. subclass the HelmholtzAuthentificationView view, see Customization via the HelmholtzAuthentificationView

The signals are the recommended way as they provide a more stable interface. As the django-helmholtz-aai is very new, we cannot guarantee that there won’t be breaking changes in the HelmholtzAuthentificationView.

Configuration via Signals

The signals module defines various signal that are fired on different events:

aai_user_created

Signal that is fired when a user has been created via the Helmholtz AAI

aai_user_logged_in

Signal that is fired when a user logs in via the Helmholtz AAI

aai_user_updated

Signal that is fired when a user receives an update via the Helmholtz AAI

aai_vo_created

Signal that is fired if a new Virtual Organization has been created

aai_vo_entered

Signal that is fired if a Helmholtz AAI user enteres a VO

aai_vo_left

Signal that is fired if a Helmholtz AAI user left a VO

The purpose of these signals should be pretty much self-explanatory.

Examples

Suppose you want users of a specific VO to become superusers. Then you can do something like this using the aai_vo_entered and aai_vo_left signals:

from django.dispatch import receiver

from django_helmholtz_aai import models, signals

@receiver(signals.aai_vo_entered)
def on_vo_enter(
        sender,
        vo: models.HelmholtzVirtualOrganization,
        user: models.HelmholtzUser,
        **kwargs,
    ):
    vo_id = "urn:geant:helmholtz.de:group:hereon#login.helmholtz.de"
    if vo.eduperson_entitlement == vo_id:
        user.is_superuser = True
        user.save()


@receiver(signals.aai_vo_left)
def on_vo_leave(
        sender,
        vo: models.HelmholtzVirtualOrganization,
        user: models.HelmholtzUser,
        **kwargs,
    ):
    vo_id = "urn:geant:helmholtz.de:group:hereon#login.helmholtz.de"
    if vo.eduperson_entitlement == vo_id:
        user.is_superuser = False
        user.save()

Let’s say you want to display a message in the frontend when a user logged in for the first time. Here you can use the aai_user_created signal:

from django.contrib import messages

from django_helmholtz_aai import models, signals

@receiver(signals.aai_user_created)
def created_user(
    sender,
    user: models.HelmholtzUser,
    request,
    **kwargs,
):
    messages.add_message(
        request, messages.success, f"Welcome on board {user}!"
    )

Customization via the HelmholtzAuthentificationView

Warning

Please bear in mind that this python package is still very new and we cannot guarantee that there won’t be breaking changes in the HelmholtzAuthentificationView class.

Another way to customize the login is via the HelmholtzAuthentificationView. Your starting point should be the following two methods, one for checking the permissions and one for performing the request:

get(request)

Login the Helmholtz AAI user and update the data.

has_permission()

Check if the user has permission to login.

For a more fine-grained control of the authentification (such as user creation or update), you can make use of the following methods and reimplement to your needs.

create_user(userinfo)

Create a Django user for a Helmholtz AAI User.

login_user(user)

Login the Helmholtz AAI user to the Django Application.

synchronize_vos()

Synchronize the memberships in the virtual organizations.

update_user()

Update the user from the userinfo provided by the Helmholtz AAI.

Example

Let’s say you want to approve users before you let them login to the website. One possibility is, to create a custom model with reference to a user and reimplement the django_helmholtz_aai.views.HelmholtzAuthentificationView.login_user(). Your custom app that reimplements this view then might look like

  • models.py

    from django.db import models
    from django_helmholtz_aai.models import HelmholtzUser
    
    
    class HelmholtzUserReview(models.Model):
        """A review of a helmholtz user"""
    
        class ReviewStatus(models.TextChoices):
    
            accepted = "accepted"
            rejected = "rejected"
    
        user = models.OneToOneField(HelmholtzUser, on_delete=models.CASCADE)
    
        review_status = models.CharField(
            choices=ReviewStatus.choices, blank=True, null=True
        )
    
  • views.py

    from django.contrib import messages
    from django_helmholtz_aai.views import HelmholtzAuthentificationView
    from django_helmholtz_aai.models import HelmholtzUser
    from .models import HelmholtzUserReview
    
    
    class CustomHelmholtzAuthentificationView(HelmholtzAuthentificationView):
        def login_user(self, user: HelmholtzUser):
            review = HelmholtzUserReview.objects.get_or_create(user=user)[0]
            if (
                review.review_status
                == HelmholtzUserReview.ReviewStatus.accepted
            ):
                super().login_user(user)
            elif (
                review.review_status
                == HelmholtzUserReview.ReviewStatus.rejected
            ):
                messages.add_message(
                    self.request,
                    messages.error,
                    f"Your account creation request has been rejected.",
                )
            else:
                messages.add_message(
                    self.request,
                    messages.success,
                    f"Your account creation request is currently under review.",
                )
    
  • urls.py

    from django.urls import include, path
    from .views import CustomHelmholtzAuthentificationView
    
    urlpatterns = [
        path(
            "helmholtz-aai/auth/",
            CustomHelmholtzAuthentificationView.as_view(),
        ),
        path("helmholtz-aai/", include("django_helmholtz_aai.urls")),
    ]