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 settings.py
file in the INSTALLED_APPS
section:
INSTALLED_APPS = [
"my_app",
"ispyb_dja",
'...',
"django_cas_ng",
"guardian"
]
Add the following settings to your apps settings.py
file, changing them where appropriate
# CAS parameters
CAS_SERVER_URL = "https://auth.diamond.ac.uk:443/cas/"
# Where to redirect to after user has logged in with CAS
CAS_REDIRECT_URL = "/"
CAS_FORCE_CHANGE_USERNAME_CASE = "lower"
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"django_cas_ng.backends.CASBackend",
"guardian.backends.ObjectPermissionBackend",
)
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 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_HOST=ssh.diamond.ac.uk
SSH_USER=<username for ssh into diamond>
SSH_PASSWORD=<password for ssh into diamond>
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')
To use the ISPyB-DJA authorization feature, instead of using a django or DRF view class, you use the custom
IspybSafeQuerySet
in your views.py
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
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"),
url(
r"^accounts/callback$",
django_cas_ng.views.CallbackView.as_view(),
name="cas_ng_proxy_callback",
),