DLS authorization & authentication: Django, CAS, ISPyB

pip install ispyb-dja==1.0.1


Authentication and authorization for XChem Web Apps

This repo contains everything you need to implement authentication (via CAS) and authorization (via ISPyB) for a web app with a django & django REST framework back-end that you want to connect to Diamond data


pip install ispyb_dja



Add ispyb_dja, django_cas_ng and guardian to your apps file in the INSTALLED_APPS section:


Add the following settings to your apps file, changing them where appropriate

# CAS parameters
# Where to redirect to after user has logged in with CAS

LOGIN_URL = "/accounts/login/"
LOGOUT_URL = "/accounts/logout/"

You may have to ask for your applications URL to be added to a list of allowed urls for CAS to work in production

Set environment variables/secrets

Set the following environment variables as secrets (they are secrets, so make sure they stay that way!)

ISPYB_USER=<Your ISPyB username>
ISPYB_PASSWORD=<Your ISPyB password>
ISPYB_HOST=<ispyb host address>
ISPYB_PORT=<ispyb port>
SECURITY_CONNECTOR=<ssh_ispyb for remote or ispyb for local>

If your app is running outside of Diamond, you will also need:
SSH_USER=<username for ssh into diamond>
SSH_PASSWORD=<password for ssh into diamond>

Use the ISPyB-DJA authorization model to define projects linked to proposals/visits

Use the django_auth.models.IspybAuthorization model to connect any sensitive data via. foreign key.

For example:

from ispyb_dja.django_auth.models import IspybAuthorization
from django.db import models

class SensitiveData(models.Model):
    related_project = models.ForeignKey(IspybAuthorization, on_delete=models.CASCADE)
    sensitive_data = models.CharField(max_length=200, unique=False)

The IspybAuthorization model includes three fields:

  • project - a charfield that you can use to give a project in your app a name
  • proposal_visit - the proposal number and visit that the data/project are related to (e.g. lb13385-10)
  • users - a ManyToMany field that is used by the authentication layer. Ignore this

So to create a new project and link our sensitive data, an example might be:

from ispyb_dja.django_auth.models import IspybAuthorization
from my_app.models import SensitiveData

new_project = IspybAuthorization(project='A sensitive bit of data', proposal_visit='lb13385-10')
new_data = SensitiveData(related_project=new_project, sensitive_data='something secret')

Use the IspybSafeQuerySet to secure serializers/views and provide authorization

To use the ISPyB-DJA authorization feature, instead of using a django or DRF view class, you use the custom IspybSafeQuerySet in your file:

from ispyb_dja.ispyb_auth.ispyb_djangoauth import ISpyBSafeQuerySet
from my_app.models import SensitiveData
from my_app.serializers import SensitiveDataSerializer

class TestAccessView(ISpyBSafeQuerySet):
    queryset = SensitiveData.objects.filter()
    serializer_class = SensitiveDataSerializer
    filter_permissions = "related_project_id"
    filter_fields = ("sensitive_data",)

where filter_permissions tells us which foreign key field in your model links to the IspybAuthorization model

Add login and logout urls to

url(r"^accounts/login/", django_cas_ng.views.LoginView.as_view(), name="cas_ng_login"),
    url(r"^accounts/logout/", django_cas_ng.views.LogoutView.as_view(), name="cas_ng_logout"),