def test_get_issuer(self):
        request = Request()

        # from default settings
        self.assertEqual(get_issuer(),
                         'http://localhost:8000/openid')

        # from custom settings
        with self.settings(SITE_URL='http://otherhost:8000'):
            self.assertEqual(get_issuer(),
                             'http://otherhost:8000/openid')

        # `SITE_URL` not set, from `request`
        with self.settings(SITE_URL=''):
            self.assertEqual(get_issuer(request=request),
                             'http://host-from-request:8888/openid')

        # use settings first if both are provided
        self.assertEqual(get_issuer(request=request),
                         'http://localhost:8000/openid')

        # `site_url` can even be overridden manually
        self.assertEqual(get_issuer(site_url='http://127.0.0.1:9000',
                                    request=request),
                         'http://127.0.0.1:9000/openid')
示例#2
0
    def test_get_issuer(self):
        request = Request()

        # from default settings
        self.assertEqual(get_issuer(),
                         'http://localhost:8000/openid')

        # from custom settings
        with self.settings(SITE_URL='http://otherhost:8000'):
            self.assertEqual(get_issuer(),
                             'http://otherhost:8000/openid')

        # `SITE_URL` not set, from `request`
        with self.settings(SITE_URL=''):
            self.assertEqual(get_issuer(request=request),
                             'http://host-from-request:8888/openid')

        # use settings first if both are provided
        self.assertEqual(get_issuer(request=request),
                         'http://localhost:8000/openid')

        # `site_url` can even be overridden manually
        self.assertEqual(get_issuer(site_url='http://127.0.0.1:9000',
                                    request=request),
                         'http://127.0.0.1:9000/openid')
示例#3
0
    def create_response_dic(self):

        sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR')(user=self.code.user)

        id_token_dic = create_id_token(iss=get_issuer(),
                                       sub=sub,
                                       aud=self.client.client_id,
                                       auth_time=self.code.user.last_login)

        token = create_token(user=self.code.user,
                             client=self.code.client,
                             id_token_dic=id_token_dic,
                             scope=self.code.scope)

        # Store the token.
        token.save()

        # We don't need to store the code anymore.
        self.code.delete()

        id_token = encode_id_token(id_token_dic, self.client.client_secret)

        dic = {
            'access_token': token.access_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': id_token,
        }

        return dic
    def create_response_dic(self):

        sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR')(
            user=self.code.user)

        id_token_dic = create_id_token(
            iss=get_issuer(),
            sub=sub,
            aud=self.client.client_id,
            auth_time=self.code.user.last_login)

        token = create_token(
            user=self.code.user,
            client=self.code.client,
            id_token_dic=id_token_dic,
            scope=self.code.scope)

        # Store the token.
        token.save()

        # We don't need to store the code anymore.
        self.code.delete()

        id_token = encode_id_token(id_token_dic, self.client.client_secret)

        dic = {
            'access_token': token.access_token,
            'token_type': 'bearer',
            'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
            'id_token': id_token,
        }

        return dic
示例#5
0
    def get(self, request, *args, **kwargs):
        dic = dict()

        dic['issuer'] = get_issuer()

        SITE_URL = settings.get('SITE_URL')

        dic['authorization_endpoint'] = SITE_URL + reverse(
            'oidc_provider:authorize')
        dic['token_endpoint'] = SITE_URL + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = SITE_URL + reverse('oidc_provider:userinfo')
        dic['end_session_endpoint'] = SITE_URL + reverse(
            'oidc_provider:logout')

        types_supported = [x[0] for x in Client.RESPONSE_TYPE_CHOICES]
        dic['response_types_supported'] = types_supported

        dic['jwks_uri'] = SITE_URL + reverse('oidc_provider:jwks')

        dic['id_token_signing_alg_values_supported'] = ['RS256']

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        dic['token_endpoint_auth_methods_supported'] = [
            'client_secret_post', 'client_secret_basic'
        ]

        return JsonResponse(dic)
    def get(self, request, *args, **kwargs):
        dic = dict()

        site_url = get_site_url(request=request)
        dic['issuer'] = get_issuer(site_url=site_url, request=request)

        dic['authorization_endpoint'] = site_url + reverse('oidc_provider:authorize')
        dic['token_endpoint'] = site_url + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = site_url + reverse('oidc_provider:userinfo')
        dic['end_session_endpoint'] = site_url + reverse('oidc_provider:end-session')

        types_supported = [x[0] for x in RESPONSE_TYPE_CHOICES]
        dic['response_types_supported'] = types_supported

        dic['jwks_uri'] = site_url + reverse('oidc_provider:jwks')

        dic['id_token_signing_alg_values_supported'] = ['HS256', 'RS256']

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        dic['token_endpoint_auth_methods_supported'] = ['client_secret_post',
                                                        'client_secret_basic']

        if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
            dic['check_session_iframe'] = site_url + reverse('oidc_provider:check-session-iframe')

        response = JsonResponse(dic)
        response['Access-Control-Allow-Origin'] = '*'

        return response
示例#7
0
def create_id_token(user, aud, nonce):
    """
    Receives a user object and aud (audience).
    Then creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken

    Return a dic.
    """
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR')(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = timezone.now()
    iat_time = int(time.mktime(now.timetuple()))
    exp_time = int(
        time.mktime((now + timedelta(seconds=expires_in)).timetuple()))
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(time.mktime(user_auth_time.timetuple()))

    dic = {
        'iss': get_issuer(),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    return dic
示例#8
0
    def get(self, request, *args, **kwargs):
        dic = dict()

        site_url = get_site_url(request=request)
        dic['issuer'] = get_issuer(site_url=site_url, request=request)

        dic['authorization_endpoint'] = site_url + reverse(
            'oidc_provider:authorize')
        dic['token_endpoint'] = site_url + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = site_url + reverse('oidc_provider:userinfo')
        dic['end_session_endpoint'] = site_url + reverse(
            'oidc_provider:logout')

        types_supported = [x[0] for x in RESPONSE_TYPE_CHOICES]
        dic['response_types_supported'] = types_supported

        dic['jwks_uri'] = site_url + reverse('oidc_provider:jwks')

        dic['id_token_signing_alg_values_supported'] = ['HS256', 'RS256']

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        dic['token_endpoint_auth_methods_supported'] = [
            'client_secret_post', 'client_secret_basic'
        ]

        response = JsonResponse(dic)
        response['Access-Control-Allow-Origin'] = '*'

        return response
示例#9
0
    def get(self, request, *args, **kwargs):
        dic = dict()

        site_url = get_site_url(request=request)
        dic['issuer'] = get_issuer(site_url=site_url, request=request)

        dic['authorization_endpoint'] = site_url + reverse('oidc_provider:authorize')
        dic['token_endpoint'] = site_url + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = site_url + reverse('oidc_provider:userinfo')
        dic['end_session_endpoint'] = site_url + reverse('oidc_provider:logout')

        types_supported = [x[0] for x in RESPONSE_TYPE_CHOICES]
        dic['response_types_supported'] = types_supported

        dic['jwks_uri'] = site_url + reverse('oidc_provider:jwks')

        dic['id_token_signing_alg_values_supported'] = ['HS256', 'RS256']

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        dic['token_endpoint_auth_methods_supported'] = [ 'client_secret_post',
                                                         'client_secret_basic' ]

        return JsonResponse(dic)
示例#10
0
def create_id_token(user, aud, nonce):
    """
    Receives a user object and aud (audience).
    Then creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken

    Return a dic.
    """
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR')(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = timezone.now()
    iat_time = int(time.mktime(now.timetuple()))
    exp_time = int(time.mktime((now + timedelta(seconds=expires_in)).timetuple()))
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(time.mktime(user_auth_time.timetuple()))

    dic = {
        'iss': get_issuer(),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    return dic
示例#11
0
def create_id_token(token,
                    user,
                    aud,
                    nonce='',
                    at_hash='',
                    request=None,
                    scope=None):
    """
    Creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
    Return a dic.
    """
    if scope is None:
        scope = []
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR',
                       import_str=True)(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = int(time.time())
    iat_time = now
    exp_time = int(now + expires_in)
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(dateformat.format(user_auth_time, 'U'))

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    if at_hash:
        dic['at_hash'] = at_hash

    # Inlude (or not) user standard claims in the id_token.
    if settings.get('OIDC_IDTOKEN_INCLUDE_CLAIMS'):
        if settings.get('OIDC_EXTRA_SCOPE_CLAIMS'):
            custom_claims = settings.get('OIDC_EXTRA_SCOPE_CLAIMS',
                                         import_str=True)(token)
            claims = custom_claims.create_response_dic()
        else:
            claims = StandardScopeClaims(token).create_response_dic()
        dic.update(claims)

    dic = run_processing_hook(dic,
                              'OIDC_IDTOKEN_PROCESSING_HOOK',
                              user=user,
                              token=token,
                              request=request)

    return dic
示例#12
0
def create_id_token(user, aud, nonce='', at_hash='', request=None, scope=[]):
    """
    Creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
    Return a dic.
    """
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR',
                       import_str=True)(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = int(time.time())
    iat_time = now
    exp_time = int(now + expires_in)
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(dateformat.format(user_auth_time, 'U'))

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    if at_hash:
        dic['at_hash'] = at_hash

    if settings.get('OIDC_EXTRA_SCOPE_CLAIMS'):
        custom_claims = settings.get('OIDC_EXTRA_SCOPE_CLAIMS',
                                     import_str=True)(user, scope)
        claims = custom_claims.create_response_dic()
    else:
        claims = StandardScopeClaims(user=user,
                                     scope=scope).create_response_dic()

    dic.update(claims)  # modifies dic, adding all requested claims

    processing_hook = settings.get('OIDC_IDTOKEN_PROCESSING_HOOK')

    if isinstance(processing_hook, (list, tuple)):
        for hook in processing_hook:
            dic = settings.import_from_str(hook)(dic, user=user)
    else:
        dic = settings.import_from_str(processing_hook)(dic, user=user)

    return dic
示例#13
0
def create_id_token(token, user, aud, nonce='', at_hash='', request=None, scope=None):
    """
    Creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
    Return a dic.
    """
    if scope is None:
        scope = []
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR', import_str=True)(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = int(time.time())
    iat_time = now
    exp_time = int(now + expires_in)
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(dateformat.format(user_auth_time, 'U'))

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    if at_hash:
        dic['at_hash'] = at_hash

    # Inlude (or not) user standard claims in the id_token.
    if settings.get('OIDC_IDTOKEN_INCLUDE_CLAIMS'):
        if settings.get('OIDC_EXTRA_SCOPE_CLAIMS'):
            custom_claims = settings.get('OIDC_EXTRA_SCOPE_CLAIMS', import_str=True)(token)
            claims = custom_claims.create_response_dic()
        else:
            claims = StandardScopeClaims(token).create_response_dic()
        dic.update(claims)

    dic = run_processing_hook(
        dic, 'OIDC_IDTOKEN_PROCESSING_HOOK',
        user=user, token=token, request=request)

    return dic
示例#14
0
def create_id_token(user, aud, nonce='', at_hash='', request=None, scope=None):
    """
    Creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
    Return a dic.
    """
    if scope is None:
        scope = []
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR',
                       import_str=True)(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = int(time.time())
    iat_time = now
    exp_time = int(now + expires_in)
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(dateformat.format(user_auth_time, 'U'))

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    if at_hash:
        dic['at_hash'] = at_hash

    if ('email' in scope) and getattr(user, 'email', None):
        dic['email'] = user.email

    processing_hook = settings.get('OIDC_IDTOKEN_PROCESSING_HOOK')

    if isinstance(processing_hook, (list, tuple)):
        for hook in processing_hook:
            dic = settings.import_from_str(hook)(dic, user=user)
    else:
        dic = settings.import_from_str(processing_hook)(dic, user=user)

    return dic
示例#15
0
def create_id_token(user, aud, nonce, at_hash=None, request=None):
    """
    Receives a user object and aud (audience).
    Then creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken

    Return a dic.
    """
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR',
                       import_str=True)(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = timezone.now()
    iat_time = int(time.mktime(now.timetuple()))
    exp_time = int(
        time.mktime((now + timedelta(seconds=expires_in)).timetuple()))
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(time.mktime(user_auth_time.timetuple()))

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    if at_hash:
        dic['at_hash'] = at_hash

    processing_hook = settings.get('OIDC_IDTOKEN_PROCESSING_HOOK')

    if isinstance(processing_hook, (list, tuple)):
        for hook in processing_hook:
            dic = settings.import_from_str(hook)(dic, user=user)
    else:
        dic = settings.import_from_str(processing_hook)(dic, user=user)

    return dic
示例#16
0
def create_token(user, client, scope, id_token_dic=None):
    """
    Create and populate a Token object.
    Return a Token object.
    """
    token = Token()
    token.user = user
    token.client = client

    payload = {
        'iss':
        get_issuer(request=None),
        'client':
        client.name,
        'scope':
        ' '.join(map(str, scope)),
        'exp':
        timezone.now() + timedelta(seconds=settings.get('OIDC_TOKEN_EXPIRE'))
    }

    if id_token_dic is not None:
        payload['id_token_dic'] = id_token_dic

    if user is not None:
        payload['user'] = user

    kid = settings.get('OIDC_SECRET_KEY')
    myToken = jwt.encode(payload,
                         settings.get('OIDC_SECRET_KEY'),
                         headers={'kid': kid})
    logging.error(myToken.decode())

    token.access_token = myToken.decode()

    if id_token_dic is not None:
        token.id_token = id_token_dic

    token.refresh_token = uuid.uuid4().hex
    token.expires_at = timezone.now() + timedelta(
        seconds=settings.get('OIDC_TOKEN_EXPIRE'))
    token.token_refresh_expires_at = timezone.now() + timedelta(
        seconds=settings.get('OIDC_TOKEN_REFRESH_EXPIRE'))
    token.scope = scope

    return token
示例#17
0
def create_id_token(user, aud, nonce='', at_hash='', request=None, scope=[]):
    """
    Creates the id_token dictionary.
    See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
    Return a dic.
    """
    sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR', import_str=True)(user=user)

    expires_in = settings.get('OIDC_IDTOKEN_EXPIRE')

    # Convert datetimes into timestamps.
    now = timezone.now()
    iat_time = int(time.mktime(now.timetuple()))
    exp_time = int(time.mktime((now + timedelta(seconds=expires_in)).timetuple()))
    user_auth_time = user.last_login or user.date_joined
    auth_time = int(time.mktime(user_auth_time.timetuple()))

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'exp': exp_time,
        'iat': iat_time,
        'auth_time': auth_time,
    }

    if nonce:
        dic['nonce'] = str(nonce)

    if at_hash:
        dic['at_hash'] = at_hash

    if ('email' in scope) and getattr(user, 'email', None):
        dic['email'] = user.email

    processing_hook = settings.get('OIDC_IDTOKEN_PROCESSING_HOOK')

    if isinstance(processing_hook, (list, tuple)):
        for hook in processing_hook:
            dic = settings.import_from_str(hook)(dic, user=user)
    else:
        dic = settings.import_from_str(processing_hook)(dic, user=user)

    return dic
示例#18
0
    def get(self, request, *args, **kwargs):
        dic = dict()

        site_url = get_site_url(request=request)
        dic['issuer'] = get_issuer(site_url=site_url, request=request)

        dic['authorization_endpoint'] = site_url + reverse(
            'oidc_provider:authorize')
        dic['token_endpoint'] = site_url + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = site_url + reverse('oidc_provider:userinfo')
        dic['end_session_endpoint'] = site_url + reverse(
            'oidc_provider:end-session')
        dic['introspection_endpoint'] = site_url + reverse(
            'oidc_provider:token-introspection')

        types_supported = [
            response_type.value
            for response_type in ResponseType.objects.all()
        ]
        dic['response_types_supported'] = types_supported

        dic['jwks_uri'] = site_url + reverse('oidc_provider:jwks')

        dic['id_token_signing_alg_values_supported'] = ['HS256', 'RS256']

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        dic['token_endpoint_auth_methods_supported'] = [
            'client_secret_post', 'client_secret_basic'
        ]

        if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
            dic['check_session_iframe'] = site_url + reverse(
                'oidc_provider:check-session-iframe')

        if settings.get('OIDC_ACR_VALUES'):
            dic['acr_values_supported'] = settings.get('OIDC_ACR_VALUES')

        response = JsonResponse(dic)
        response['Access-Control-Allow-Origin'] = '*'

        return response
示例#19
0
def create_logout_token(user, aud, sid, request=None) -> dict:
    """
    Creates the logout token dictionary.
    See: https://openid.net/specs/openid-connect-backchannel-1_0.html#LogoutToken
    Return a dic.
    """
    sub = settings.get(
        'OIDC_IDTOKEN_SUB_GENERATOR',
        import_str=True,
    )(user=user)

    dic = {
        'iss': get_issuer(request=request),
        'sub': sub,
        'aud': str(aud),
        'iat': int(time.time()),
        'jti': md5(uuid.uuid4().hex.encode()).hexdigest(),
        'events': 'http://schemas.openid.net/event/backchannel-logout',
        'sid': sid,
    }

    return dic
    def create_response_dic(cls):
        dic = {}

        dic['issuer'] = get_issuer()

        SITE_URL = settings.get('SITE_URL')

        dic['authorization_endpoint'] = SITE_URL + reverse('oidc_provider:authorize')
        dic['token_endpoint'] = SITE_URL + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = SITE_URL + reverse('oidc_provider:userinfo')

        from oidc_provider.models import Client
        types_supported = [x[0] for x in Client.RESPONSE_TYPE_CHOICES]
        dic['response_types_supported'] = types_supported

        # TODO:
        #dic['jwks_uri'] = None

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        return dic
示例#21
0
    def create_response_dic(cls):
        dic = {}

        dic['issuer'] = get_issuer()

        SITE_URL = settings.get('SITE_URL')

        dic['authorization_endpoint'] = SITE_URL + reverse(
            'oidc_provider:authorize')
        dic['token_endpoint'] = SITE_URL + reverse('oidc_provider:token')
        dic['userinfo_endpoint'] = SITE_URL + reverse('oidc_provider:userinfo')

        from oidc_provider.models import Client
        types_supported = [x[0] for x in Client.RESPONSE_TYPE_CHOICES]
        dic['response_types_supported'] = types_supported

        # TODO:
        #dic['jwks_uri'] = None

        # See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
        dic['subject_types_supported'] = ['public']

        return dic
示例#22
0
 def test_get_issuer(self):
     issuer = get_issuer()
     self.assertEqual(issuer, settings.SITE_URL + '/openid')
    def create_response_uri(self, allow):

        if not allow:
            raise AuthorizeError(
                self.params.redirect_uri,
                'access_denied',
                self.grant_type)

        try:
            self.validate_params()

            if self.grant_type == 'authorization_code':

                code = create_code(
                    user=self.request.user,
                    client=self.client,
                    scope=self.params.scope)
                
                code.save()

                # Create the response uri.
                uri = self.params.redirect_uri + '?code={0}'.format(code.code)

            else:  # Implicit Flow

                # TODO refactor since it's the same as the token endpoint
                sub = settings.get('OIDC_IDTOKEN_SUB_GENERATOR')(
                    user=self.request.user)

                id_token_dic = create_id_token(
                    iss=get_issuer(),
                    sub=sub,
                    aud=self.client.client_id,
                    auth_time=self.request.user.last_login)

                token = create_token(
                    user=self.request.user,
                    client=self.client,
                    id_token_dic=id_token_dic,
                    scope=self.params.scope)

                # Store the token.
                token.save()

                id_token = encode_id_token(
                    id_token_dic, self.client.client_secret)

                # Create the response uri.
                uri = self.params.redirect_uri + \
                    '#token_type={0}&id_token={1}&expires_in={2}'.format(
                        'bearer',
                        id_token,
                        60 * 10,
                    )

                # Check if response_type is 'id_token token' then
                # add access_token to the fragment.
                if self.params.response_type == 'id_token token':
                    uri += '&access_token={0}'.format(token.access_token)
        except:
            raise AuthorizeError(
                self.params.redirect_uri,
                'server_error',
                self.grant_type)

        # Add state if present.
        uri += ('&state={0}'.format(self.params.state) if self.params.state else '')

        return uri