django-self-login 1.0.2
Django integration with Self Street for SSO.
License: BSD 3-Clause License
Keywords: django-self-login

# Self OpenID Client

Django plugin that replaces the standard Django user model and replaces it with Self Street OpenID integration.

**Note**: This project is open source but currently only being used within Column Street. If you would like to integrate Self logging into your website/app/project please reach out to us so we can discuss. 

## Use

This package is a thin layer on top of the `mozilla-django-oidc` project, therefore integration is very similar. 

### 1. Register Application with Self

Either contact an admin, or initiate it via the administrator board in Self.

### 2. Install Package

```
pip install django-self-login
```

### 3. Add & Modify Settings

The following settings need to be initialized. Inside your `INSTALLED_APPS` make sure to add `mozilla_django_oidc` and `django_self_login` right after `django.contrib.auth`. 

```python
INSTALLED_APPS = [
    ...,
    "django.contrib.auth",
    "mozilla_django_oidc",
    "django_self_login",
    ...
]
```

At the end of your settings file you can then add the following:

```python
# =======================================================================================================
# Self Street

# Custom User Model
# https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#substituting-a-custom-user-model
# This custom user model is used with the OIDC backend to ensure Self and Meta communicate properly.
AUTH_USER_MODEL = "django_self_login.User"

# Authentication Backend
# https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#specifying-authentication-backends
# Must be modified so that the OpenID plugin can automatically create users
# based on the login of the user from Self. We use a custom authentication so that
# we take care of user updates and uniqueness.
AUTHENTICATION_BACKENDS = ("django_self_login.auth.SelfAuthenticationBackend",)

# OpenID
# https://mozilla-django-oidc.readthedocs.io/en/stable/installation.html#choose-the-appropriate-algorithm
# These are settings related to the OpenID Connect Client.

# Client ID and Secret
OIDC_RP_CLIENT_ID = ""
OIDC_RP_CLIENT_SECRET = ""

# Server Endpoints
OIDC_OP_ENDPOINT = "https://self.st"
OIDC_OP_JWKS_ENDPOINT = OIDC_OP_ENDPOINT + "/o/jwks/"
OIDC_OP_AUTHORIZATION_ENDPOINT = OIDC_OP_ENDPOINT+ "/o/authorize/"
OIDC_OP_TOKEN_ENDPOINT = OIDC_OP_ENDPOINT + "/o/token/"
OIDC_OP_USER_ENDPOINT = OIDC_OP_ENDPOINT + "/o/userinfo/"

# Scopes
# https://github.com/mozilla/mozilla-django-oidc/blob/master/mozilla_django_oidc/auth.py#L84
# These are the default scopes that any OpenID Client with Self has access to. Add any extra if you have. 
OIDC_RP_SCOPES = "openid profile email"
# =======================================================================================================
```

Make sure to modify the following varaibles:

* `OIDC_RP_CLIENT_ID`: Client ID given and generated by Self.
* `OIDC_RP_CLIENT_SECRET`: Client secret given and generated by Self. Recommended to be passed as an env variable.

### 4. Create Migrations

```
python manage.py makemigrations
python manage.py migrate
```

### 5. Login

Logging can be done found via the router `oidc_authentication_init`, and logout via `oidc_logout`. This is defined in the `mozilla-django-oidc` docs [here](https://mozilla-django-oidc.readthedocs.io/en/stable/installation.html#enable-login-and-logout-functionality-in-templates). If you want to quickly test out the framework, you can use the following:

```html
<h1>ggwp</h1>

{% if request.user.is_authenticated %}
You are currently authenticated. Your user information is the following:

<ul>
    <li><b>Subject Identifier:</b> {{ request.user.sub }}</li>
    <li><b>Given Name:</b> {{ request.user.given_name }} </li>
    <li><b>Family Name:</b> {{ request.user.family_name }} </li>
    <li><b>Nick Name:</b> {{ request.user.nick_name }} </li>
    <li><b>Username:</b> {{ request.user.username }}</li>
    <li><b>Email:</b> {{ request.user.email }} </li>
    <li><b>Active:</b> {{ request.user.active }} </li>
    <li><b>Staff:</b> {{ request.user.staff }} </li>
    <li><b>Admin:</b> {{ request.user.admin }} </li>
</ul>
{% else %}
You are not authenticated. <br>
{% endif %}

<br>

{% if not request.user.is_authenticated %}
<a href="{% url 'oidc_authentication_init' %}">login</a>
{% else %}
 <form action="{% url 'oidc_logout' %}" method="post">
    {% csrf_token %}
    <input type="submit" value="logout">
</form>
{% endif %}
```