Skip to content

Commit

Permalink
Merge pull request #5 from learningequality/add_roles_when_creating_user
Browse files Browse the repository at this point in the history
Add more fields to the user creation and add roles if they are provided
  • Loading branch information
indirectlylit committed Jul 13, 2020
2 parents c7d9982 + 5c454ff commit 7c1d8a7
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
24 changes: 24 additions & 0 deletions README.md
Expand Up @@ -19,6 +19,30 @@ This package provides Kolibri users with the ability to authenticate against an
3. Restart Kolibri


## Used claims

This plugin will create a new user in the Kolibri database after it authenticates using the OIDC provider.
From the [standard OIDC claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) the plugin will fetch the following fields and add the information to the Kolibri user database:

- `nickname` (or `username`)
- `given_name`
- `family_name`
- `email`
- `birthdate`
- `gender`

In case `birthdate`is provided, the accepted format is [ISO8601‑2004] YYYY-MM-DD. However Kolibri only stores the year of birth.

Apart from these standard claims, the plugin will accept a `roles` in the user_info token provided as a list. Allowed roles are only `admin` or `coach`.
If the role is not provided the user is created as a learner.

As an user_info token payload example:
```json
{"email":"jhon@doe.com", "username":"jdoe", "roles":"['coach']", "family_name":"Doe"}

```


## Plugin configuration

This plugin is based on the [Mozilla Django OIDC library](https://mozilla-django-oidc.readthedocs.io/en/stable/). The plugin has been set to work with a standard OpenID Connect provider, so most of the library options have already been set and are not optional.
Expand Down
38 changes: 31 additions & 7 deletions kolibri_oidc_client_plugin/auth.py
@@ -1,6 +1,6 @@
import logging
from uuid import uuid4

from kolibri.core.auth.errors import InvalidRoleKind
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
from mozilla_django_oidc.auth import SuspiciousOperation

Expand All @@ -9,7 +9,9 @@

class OIDCKolibriAuthenticationBackend(OIDCAuthenticationBackend):
def get_username(self, claim):
username = claim.get("nickname") # according to https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
username = claim.get(
"nickname"
) # according to https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
if not username: # according to OLIP implementation
username = claim.get("username")
return username
Expand Down Expand Up @@ -66,12 +68,34 @@ def create_user(self, claims):
username = self.get_username(claims)
full_name = claims.get("name", "")
if not full_name:
full_name = '{} {}'.format(claims.get('given_name', ""), claims.get('family_name', ""))
full_name = "{} {}".format(
claims.get("given_name", ""), claims.get("family_name", "")
)
# not needed in Kolibri, email is not mandatory:
email = username
email = claims.get("email", username)
# Kolibri doesn't allow an empty password. This isn't going to be used:
password = uuid4().hex

return self.UserModel.objects.create_user(
username, email=email, full_name=full_name, password=password
# birthdate format is [ISO8601‑2004] YYYY-MM-DD
birthdate = (
claims.get("birthdate")[:4] if "birthdate" in claims else "NOT_SPECIFIED"
)
gender = claims.get("gender", "NOT_SPECIFIED").upper()
user = self.UserModel.objects.create_user(
username,
email=email,
full_name=full_name,
password=password,
birth_year=birthdate,
gender=gender,
)

# check if the user has assigned roles and assign them in such case
roles = claims.get("roles", [])
for role in roles:
if role.lower() in ("admin", "coach"):
try:
user.facility.add_role(user, role.lower())
except InvalidRoleKind:
pass # The role does not exist in Kolibri

return user

0 comments on commit 7c1d8a7

Please sign in to comment.