Add session creation and return mechanism to API
Part of #6 (closed)
Note: This MR is in draft status to prevent someone accidentally clicking on "merge" after approving before everyone in the teamIdentity had the chance to review this MR, as per acceptance criteria. However, this MR is ready to be reviewed and is not actually in draft.
Description
Based on work done in !19 (closed), this MR introduces the mechanism to exchange account details for a token that can then be used to authenticate against other API endpoints in this application.
It follows the specification outlined in #6 (comment 709470).
Authentication backend
Unlike the proof of concept and the diagram in the Miro board, I opted not to use a custom authentication_classes
for the LoginView
. Reason being is because the authentication backend would only be for one single view being the LoginView
(KISS) and using a serializer in a authentication_classes
would not allow the view (and schema) to know about the accepted/expected fields for the POST
request. Using a serializer will also make sure we don't have to write some validation logic ourselves, it comes with the serializer.
CRSid check logic
We had some logic that allowed the frontend to talk to the backend to check whether we can actually talk to each other. Since we had to remove this logic from the frontend, it's also not really needed in the backend anymore. And it wouldn't work anyway because it would be an authenticated endpoint now. I removed all the logic we had in this area in this MR. The alternative was to keep it, and change the tests to handle authentication.
django.contrib.auth
I would've liked to remove this application from the INSTALLED_APPS
, but this is unfortunately not possible. That's because django-rest-knox
depends on django.contrib.auth
. But only in a way where the knox.models.AuthToken
model has a foreign key to the user model. Even though we set the KNOX_TOKEN_MODEL
and REST_KNOX.TOKEN_MODEL
to authentication.AuthToken
, the knox.models.AuthToken
still gets created because we include knox
in INSTALLED_APPS
. We don't use that model, we use our own, but there's also no way of not creating that model in the database.
How to test
- Create a new account through the shell (
poe manage shell
):
from activate_account.models import CRSId, Account
Account.objects.create(crsid=CRSId.objects.create(value="ab1234"), last_name="Smith", date_of_birth="1996-12-19", code="ABCDEF12345")
- Spin up the development instance (
poe manage up
) and request a token:
$ curl -X POST http://localhost:8000/token/ -H "Content-Type: application/x-www-form-urlencoded" --data "grant_type=urn%3Adevops.uis.cam.ac.uk%3Aparams%3Aoauth%3Agrant-type%3Anew-user-credentials&date_of_birth=1996-12-19&crsid=ab1234&code=ABCDEF12345"
- With the
access_token
, do an API request against a protected endpoint:
curl http://localhost:8000/ -H "Authorization: Bearer <access_token>"