django_authgroupex

An authentication backend for Django based on Polytechnique.org's auth-groupe-x SSO protocol.


Keywords
sso, authentication, django, authgroupex
License
BSD-3-Clause
Install
pip install django_authgroupex==0.4.1

Documentation

django-authgroupex

This library provides a Django authentication backend based on Polytechnique.org's auth-groupe-x SSO protocol.

https://travis-ci.org/Polytechnique-org/django-authgroupex.svg?branch=master

Setup

The django-authgroupex package requires only a minimal pair of settings to work:

# Enable AuthGroupeX authentication backend
AUTHENTICATION_BACKENDS = (
    'django_authgroupex.auth.AuthGroupeXBackend',
    'django.contrib.auth.backends.ModelBackend',  # Optional
)

# Read secret key from file
AUTHGROUPEX_KEY = open('authgroupex.key', 'r').readline()

It should also be included in your projects urls.py file:

urlpatterns = patterns('',
    # Usual suspects here
    url(r'^xorgauth/', include('django_authgroupex.urls', namespace='authgroupex')),
)

Note

The app must be installed under the authgroupex namespace.

If you're using the django.contrib.admin app, you may also override its login form:

from django.contrib import admin
admin.site.login_template = 'authgroupex/admin_login.html'

Note

This setting requires django_authgroupex to be part of your INSTALLED_APPS.

Configuring django-authgroupex

django-authgroupex provides the following settings:

Connection

  • AUTHGROUPEX_KEY: Required, the secret key used to connect to an AuthGroupeX-compatible server.
  • AUTHGROUPEX_ENDPOINT: The remote endpoint (an AuthGroupeX-compatible server). Default: https://www.polytechnique.org/auth-groupex/utf8
  • AUTHGROUPEX_FIELDS: The list of profile fields to require upon connection; order matters. Default: ('username', 'firstname', 'lastname', 'email')

Models

  • AUTHGROUPEX_USER_MODEL: Model storing users. Default: auth.User
  • AUTHGROUPEX_GROUP_MODEL: Model storing groups. Default: auth.Group

Note

The AuthGroupeXBackend authentication backend expects a :class:`~django.contrib.auth.AbstractUser` subclass in that model. This behaviour can be tuned by writing your own subclass, inheriting from :class:`~django_authgroupex.auth.AuthGroupeXMixin`.

Permissions

django_authgroupex uses the 4 permissions from the AuthGroupeX SSO:

These (remote) permissions can be mapped to Django access rights through the following settings:

  • AUTHGROUPEX_SUPERADMIN_PERMS: A list of AuthGroupeX permissions that enable the is_admin flag on this server. Default: ()
  • AUTHGROUPEX_STAFF_PERMS: A list of AuthGroupeX permissions that enable the is_staff flag on this server.
  • AUTHGROUPEX_DISABLE_DEADS: Whether a user connecting from a "dead" account should be switched to is_active=False Default: False
  • AUTHGROUPEX_GROUP: Name of the AuthGroupeX group to use for a single-group website. Default: ''
  • AUTHGROUPEX_MAP_GROUPS: Dict mapping an AuthGroupeX permission to a list of local group names. Default: {}

URLs

The usual setup of django-authgroupex is to use :meth:`~django_authgroupex.views.AuthGroupeXUniqueView.login_view` for authentication, either as "login" page (thus enabling transparent authentication) or through a "connect through X.org" link from the usual login page.

This behaviour can be tuned through the following settings:

  • AUTHGROUPEX_RETURN_URL: Name of the (local) return url for successful logins. Default: settings.LOGIN_URL
  • AUTHGROUPEX_LOGIN_REDIRECT_URL: Name of the URL to redirect the user to after a successful login without a ?next= parameter Default: settings.LOGIN_REDIRECT_URL

If :meth:`~django_authgroupex.views.AuthGroupeXUniqueView.login_view` is used, AUTHGROUPEX_RETURN_URL must point to that view.

If :meth:`~django_authgroupex.views.AuthGroupeXBaseView.login_begin_view` and :meth:`~django_authgroupex.views.AuthGroupeXBaseView.login_return_view` are used AUTHGROUPEX_RETURN_URL must point to login_return_view.

Examples

Here are several real usecases of websites using django-authgroupex.

  • For a website managed by the admininstrators of the login provider (Polytechnique.org), PERM_ADMINS needs to be mapped to user.is_superuser and user.is_staff is meaningless. The settings may contain:

    AUTHGROUPEX_FIELDS = ('username', 'firstname', 'lastname', 'email', 'perms')
    AUTHGROUPEX_SUPERADMIN_PERMS = ('admin',)
    
  • A website managed by a specific group, let's say "MyGroup", can use user.is_staff for the members and user.is_superuser for the admins of the group:

    AUTHGROUPEX_FIELDS = ('username', 'firstname', 'lastname', 'email', 'grpauth')
    AUTHGROUPEX_GROUP = 'MyGroup'
    AUTHGROUPEX_SUPERADMIN_PERMS = ('grpadmin',)
    AUTHGROUPEX_STAFF_PERMS = ('grpmember',)
    
  • It is of course possible to mix the above usecases, for example to set user.is_superuser for administrators:

    AUTHGROUPEX_FIELDS = ('username', 'firstname', 'lastname', 'email', 'perms', 'grpauth')
    AUTHGROUPEX_GROUP = 'MyGroup'
    AUTHGROUPEX_SUPERADMIN_PERMS = ('admin', 'grpadmin')
    AUTHGROUPEX_STAFF_PERMS = ('grpmember',)
    

Testing

For testing purposes, it is advised to not use a production private key.

django_authgroupex has a special, "fake" mode for such cases. That fake mode adds a couple of URLs handling a local endpoint where the end user can choose custom values for requested fields.

Installation requires a couple of extra settings:

# settings.py
AUTHGROUPEX_FAKE = True
AUTHGROUPEX_ENDPOINT = 'authgroupex:fake_endpoint'
INSTALLED_APPS = (
    '...',
    'django_authgroupex',
)

The AUTHGROUPEX_FAKE setting will enable two views for handling fake requests:

  • One validates the input (which can also be used to validate external clients)
  • The second provides a dynamic form based on AUTHGROUPEX_FIELDS, enabling users to select their preferred response.

The AUTHGROUPEX_ENDPOINT setting should include the namespace at which django_authgroupex.urls was inserted.

It is also possible to add preset accounts for the fake endpoint, with AUTHGROUPEX_FAKE_ACCOUNTS. This variable is a tuple of dicts defining the values for each field of AUTHGROUPEX_FIELDS. An extra optional field, displayname, is available to give a "name" for the preset account. If displayname is not set, username is used to refer to the account.

AUTHGROUPEX_FAKE_ACCOUNTS = (
    {
        'displayname': "Jean Dupont (utilisateur)",
        'username': 'jean.dupont.1901',
        'firstname': "Jean",
        'lastname': "Dupont",
        'email': 'jean.dupont.1901@polytechnique.org',
        'perms': 'user',
    },
)