token_utils.py 2.43 KB
Newer Older
1 2 3 4 5 6 7 8
"""Utilities for working with ID tokens."""
import datetime

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
import jwt
from provider.oauth2.models import Client

9
from student.models import UserProfile, anonymous_id_for_user
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43


def get_id_token(user, client_name):
    """Construct a JWT for use with the named client.

    The JWT is signed with the named client's secret, and includes the following claims:

        preferred_username (str): The user's username. The claim name is borrowed from edx-oauth2-provider.
        name (str): The user's full name.
        email (str): The user's email address.
        administrator (Boolean): Whether the user has staff permissions.
        iss (str): Registered claim. Identifies the principal that issued the JWT.
        exp (int): Registered claim. Identifies the expiration time on or after which
            the JWT must NOT be accepted for processing.
        iat (int): Registered claim. Identifies the time at which the JWT was issued.
        aud (str): Registered claim. Identifies the recipients that the JWT is intended for. This implementation
            uses the named client's ID.
        sub (int): Registered claim.  Identifies the user.  This implementation uses the raw user id.

    Arguments:
        user (User): User for which to generate the JWT.
        client_name (unicode): Name of the OAuth2 Client for which the token is intended.

    Returns:
        str: the JWT

    Raises:
        ImproperlyConfigured: If no OAuth2 Client with the provided name exists.
    """
    try:
        client = Client.objects.get(name=client_name)
    except Client.DoesNotExist:
        raise ImproperlyConfigured('OAuth2 Client with name [%s] does not exist' % client_name)

44 45 46 47 48 49
    try:
        # Service users may not have user profiles.
        full_name = UserProfile.objects.get(user=user).name
    except UserProfile.DoesNotExist:
        full_name = None

50 51 52 53 54
    now = datetime.datetime.utcnow()
    expires_in = getattr(settings, 'OAUTH_ID_TOKEN_EXPIRATION', 30)

    payload = {
        'preferred_username': user.username,
55
        'name': full_name,
56 57 58 59 60 61
        'email': user.email,
        'administrator': user.is_staff,
        'iss': settings.OAUTH_OIDC_ISSUER,
        'exp': now + datetime.timedelta(seconds=expires_in),
        'iat': now,
        'aud': client.client_id,
62
        'sub': anonymous_id_for_user(user, None),
63 64 65
    }

    return jwt.encode(payload, client.client_secret)