Pull request PEP8 compliant from nicchub:master.
This commit is contained in:
parent
c323b0829b
commit
be741e79e3
11 changed files with 125 additions and 71 deletions
|
@ -50,6 +50,8 @@ Add the provider urls.
|
||||||
Settings
|
Settings
|
||||||
********
|
********
|
||||||
|
|
||||||
|
Add required variables to your project settings.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
# REQUIRED. Your server provider url.
|
# REQUIRED. Your server provider url.
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
import uuid
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from openid_provider.lib.errors import *
|
from openid_provider.lib.errors import *
|
||||||
from openid_provider.lib.utils.params import *
|
from openid_provider.lib.utils.params import *
|
||||||
from openid_provider.lib.utils.token import *
|
from openid_provider.lib.utils.token import *
|
||||||
from openid_provider.models import *
|
from openid_provider.models import *
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class AuthorizeEndpoint(object):
|
class AuthorizeEndpoint(object):
|
||||||
|
@ -17,8 +20,7 @@ class AuthorizeEndpoint(object):
|
||||||
|
|
||||||
# Because in this endpoint we handle both GET
|
# Because in this endpoint we handle both GET
|
||||||
# and POST request.
|
# and POST request.
|
||||||
self.query_dict = (self.request.POST if self.request.method == 'POST'
|
self.query_dict = (self.request.POST if self.request.method == 'POST' else self.request.GET)
|
||||||
else self.request.GET)
|
|
||||||
|
|
||||||
self._extract_params()
|
self._extract_params()
|
||||||
|
|
||||||
|
@ -32,12 +34,12 @@ class AuthorizeEndpoint(object):
|
||||||
self.grant_type = None
|
self.grant_type = None
|
||||||
|
|
||||||
def _extract_params(self):
|
def _extract_params(self):
|
||||||
'''
|
"""
|
||||||
Get all the params used by the Authorization Code Flow
|
Get all the params used by the Authorization Code Flow
|
||||||
(and also for the Implicit).
|
(and also for the Implicit).
|
||||||
|
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
||||||
'''
|
"""
|
||||||
self.params.client_id = self.query_dict.get('client_id', '')
|
self.params.client_id = self.query_dict.get('client_id', '')
|
||||||
self.params.redirect_uri = self.query_dict.get('redirect_uri', '')
|
self.params.redirect_uri = self.query_dict.get('redirect_uri', '')
|
||||||
self.params.response_type = self.query_dict.get('response_type', '')
|
self.params.response_type = self.query_dict.get('response_type', '')
|
||||||
|
@ -45,11 +47,11 @@ class AuthorizeEndpoint(object):
|
||||||
self.params.state = self.query_dict.get('state', '')
|
self.params.state = self.query_dict.get('state', '')
|
||||||
|
|
||||||
def _extract_implicit_params(self):
|
def _extract_implicit_params(self):
|
||||||
'''
|
"""
|
||||||
Get specific params used by the Implicit Flow.
|
Get specific params used by the Implicit Flow.
|
||||||
|
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest
|
See: http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthRequest
|
||||||
'''
|
"""
|
||||||
self.params.nonce = self.query_dict.get('nonce', '')
|
self.params.nonce = self.query_dict.get('nonce', '')
|
||||||
|
|
||||||
def validate_params(self):
|
def validate_params(self):
|
||||||
|
@ -69,8 +71,7 @@ class AuthorizeEndpoint(object):
|
||||||
if not (self.params.redirect_uri in self.client.redirect_uris):
|
if not (self.params.redirect_uri in self.client.redirect_uris):
|
||||||
raise RedirectUriError()
|
raise RedirectUriError()
|
||||||
|
|
||||||
if not (self.grant_type) or \
|
if not self.grant_type or not (self.params.response_type == self.client.response_type):
|
||||||
not (self.params.response_type == self.client.response_type):
|
|
||||||
|
|
||||||
raise AuthorizeError(
|
raise AuthorizeError(
|
||||||
self.params.redirect_uri,
|
self.params.redirect_uri,
|
||||||
|
@ -91,23 +92,23 @@ class AuthorizeEndpoint(object):
|
||||||
try:
|
try:
|
||||||
self.validate_params()
|
self.validate_params()
|
||||||
|
|
||||||
if (self.grant_type == 'authorization_code'):
|
if self.grant_type == 'authorization_code':
|
||||||
|
|
||||||
code = Code()
|
code = Code()
|
||||||
code.user = self.request.user
|
code.user = self.request.user
|
||||||
code.client = self.client
|
code.client = self.client
|
||||||
code.code = uuid.uuid4().hex
|
code.code = uuid.uuid4().hex
|
||||||
code.expires_at = timezone.now() + timedelta(seconds=60*10) # TODO: Add this into settings.
|
code.expires_at = timezone.now() + timedelta(seconds=60*10) # TODO: Add this into settings.
|
||||||
code.scope = self.params.scope
|
code.scope = self.params.scope
|
||||||
code.save()
|
code.save()
|
||||||
|
|
||||||
uri = self.params.redirect_uri + '?code={0}'.format(code.code)
|
uri = self.params.redirect_uri + '?code={0}'.format(code.code)
|
||||||
|
|
||||||
else: # Implicit Flow
|
else: # Implicit Flow
|
||||||
|
|
||||||
id_token_dic = create_id_token_dic(
|
id_token_dic = create_id_token_dic(
|
||||||
self.request.user,
|
self.request.user,
|
||||||
'http://localhost:8000', # TODO: Add this into settings.
|
'http://localhost:8000', # TODO: Add this into settings.
|
||||||
self.client.client_id)
|
self.client.client_id)
|
||||||
|
|
||||||
token = create_token(
|
token = create_token(
|
||||||
|
@ -123,11 +124,11 @@ class AuthorizeEndpoint(object):
|
||||||
|
|
||||||
# TODO: Check if response_type is 'id_token token' then
|
# TODO: Check if response_type is 'id_token token' then
|
||||||
# add access_token to the fragment.
|
# add access_token to the fragment.
|
||||||
uri = self.params.redirect_uri + \
|
uri = self.params.redirect_uri + '#token_type={0}&id_token={1}&expires_in={2}'.format(
|
||||||
'#token_type={0}&id_token={1}&expires_in={2}'.format(
|
'bearer',
|
||||||
'bearer',
|
id_token,
|
||||||
id_token,
|
60*10
|
||||||
60*10)
|
)
|
||||||
except:
|
except:
|
||||||
raise AuthorizeError(
|
raise AuthorizeError(
|
||||||
self.params.redirect_uri,
|
self.params.redirect_uri,
|
||||||
|
@ -135,7 +136,6 @@ class AuthorizeEndpoint(object):
|
||||||
self.grant_type)
|
self.grant_type)
|
||||||
|
|
||||||
# Add state if present.
|
# Add state if present.
|
||||||
uri = uri + ('&state={0}'.format(self.params.state)
|
uri = uri + ('&state={0}'.format(self.params.state) if self.params.state else '')
|
||||||
if self.params.state else '')
|
|
||||||
|
|
||||||
return uri
|
return uri
|
|
@ -1,10 +1,12 @@
|
||||||
|
import urllib
|
||||||
|
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
|
|
||||||
from openid_provider.lib.errors import *
|
from openid_provider.lib.errors import *
|
||||||
from openid_provider.lib.utils.params import *
|
from openid_provider.lib.utils.params import *
|
||||||
from openid_provider.lib.utils.token import *
|
from openid_provider.lib.utils.token import *
|
||||||
from openid_provider.models import *
|
from openid_provider.models import *
|
||||||
from openid_provider import settings
|
from openid_provider import settings
|
||||||
import urllib
|
|
||||||
|
|
||||||
|
|
||||||
class TokenEndpoint(object):
|
class TokenEndpoint(object):
|
||||||
|
@ -54,15 +56,15 @@ class TokenEndpoint(object):
|
||||||
def create_response_dic(self):
|
def create_response_dic(self):
|
||||||
|
|
||||||
id_token_dic = create_id_token_dic(
|
id_token_dic = create_id_token_dic(
|
||||||
self.code.user,
|
self.code.user,
|
||||||
settings.get('SITE_URL'),
|
settings.get('SITE_URL'),
|
||||||
self.client.client_id)
|
self.client.client_id)
|
||||||
|
|
||||||
token = create_token(
|
token = create_token(
|
||||||
user=self.code.user,
|
user=self.code.user,
|
||||||
client=self.code.client,
|
client=self.code.client,
|
||||||
id_token_dic=id_token_dic,
|
id_token_dic=id_token_dic,
|
||||||
scope=self.code.scope)
|
scope=self.code.scope)
|
||||||
|
|
||||||
# Store the token.
|
# Store the token.
|
||||||
token.save()
|
token.save()
|
||||||
|
@ -75,7 +77,7 @@ class TokenEndpoint(object):
|
||||||
dic = {
|
dic = {
|
||||||
'access_token': token.access_token,
|
'access_token': token.access_token,
|
||||||
'token_type': 'bearer',
|
'token_type': 'bearer',
|
||||||
'expires_in': 60*60, # TODO: Add this into settings.
|
'expires_in': 60*60, # TODO: Add this into settings.
|
||||||
'id_token': id_token,
|
'id_token': id_token,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +85,11 @@ class TokenEndpoint(object):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def response(self, dic, status=200):
|
def response(self, dic, status=200):
|
||||||
'''
|
"""
|
||||||
Create and return a response object.
|
Create and return a response object.
|
||||||
'''
|
"""
|
||||||
response = JsonResponse(dic, status=status)
|
response = JsonResponse(dic, status=status)
|
||||||
response['Cache-Control'] = 'no-store'
|
response['Cache-Control'] = 'no-store'
|
||||||
response['Pragma'] = 'no-cache'
|
response['Pragma'] = 'no-cache'
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
import re
|
||||||
|
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
|
||||||
from openid_provider.lib.errors import *
|
from openid_provider.lib.errors import *
|
||||||
from openid_provider.lib.scopes import *
|
from openid_provider.lib.scopes import *
|
||||||
from openid_provider.lib.utils.params import *
|
from openid_provider.lib.utils.params import *
|
||||||
from openid_provider.models import *
|
from openid_provider.models import *
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
class UserInfoEndpoint(object):
|
class UserInfoEndpoint(object):
|
||||||
|
@ -21,12 +23,12 @@ class UserInfoEndpoint(object):
|
||||||
self.params.access_token = self._get_access_token()
|
self.params.access_token = self._get_access_token()
|
||||||
|
|
||||||
def _get_access_token(self):
|
def _get_access_token(self):
|
||||||
'''
|
"""
|
||||||
Get the access token using Authorization Request Header Field method.
|
Get the access token using Authorization Request Header Field method.
|
||||||
See: http://tools.ietf.org/html/rfc6750#section-2.1
|
See: http://tools.ietf.org/html/rfc6750#section-2.1
|
||||||
|
|
||||||
Return a string.
|
Return a string.
|
||||||
'''
|
"""
|
||||||
auth_header = self.request.META.get('HTTP_AUTHORIZATION', '')
|
auth_header = self.request.META.get('HTTP_AUTHORIZATION', '')
|
||||||
|
|
||||||
if re.compile('^Bearer\s{1}.+$').match(auth_header):
|
if re.compile('^Bearer\s{1}.+$').match(auth_header):
|
||||||
|
@ -45,12 +47,12 @@ class UserInfoEndpoint(object):
|
||||||
raise UserInfoError('invalid_token')
|
raise UserInfoError('invalid_token')
|
||||||
|
|
||||||
def create_response_dic(self):
|
def create_response_dic(self):
|
||||||
'''
|
"""
|
||||||
Create a diccionary with all the requested claims about the End-User.
|
Create a diccionary with all the requested claims about the End-User.
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
|
See: http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
|
||||||
|
|
||||||
Return a diccionary.
|
Return a diccionary.
|
||||||
'''
|
"""
|
||||||
dic = {
|
dic = {
|
||||||
'sub': self.token.id_token.get('sub'),
|
'sub': self.token.id_token.get('sub'),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,33 +6,52 @@ class RedirectUriError(Exception):
|
||||||
error = 'Redirect URI Error'
|
error = 'Redirect URI Error'
|
||||||
description = 'The request fails due to a missing, invalid, or mismatching redirection URI (redirect_uri).'
|
description = 'The request fails due to a missing, invalid, or mismatching redirection URI (redirect_uri).'
|
||||||
|
|
||||||
|
|
||||||
class ClientIdError(Exception):
|
class ClientIdError(Exception):
|
||||||
|
|
||||||
error = 'Client ID Error'
|
error = 'Client ID Error'
|
||||||
description = 'The client identifier (client_id) is missing or invalid.'
|
description = 'The client identifier (client_id) is missing or invalid.'
|
||||||
|
|
||||||
|
|
||||||
class AuthorizeError(Exception):
|
class AuthorizeError(Exception):
|
||||||
|
|
||||||
_errors = {
|
_errors = {
|
||||||
# Oauth2 errors.
|
# Oauth2 errors.
|
||||||
# https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
# https://tools.ietf.org/html/rfc6749#section-4.1.2.1
|
||||||
'invalid_request': 'The request is otherwise malformed',
|
'invalid_request': 'The request is otherwise malformed',
|
||||||
|
|
||||||
'unauthorized_client': 'The client is not authorized to request an authorization code using this method',
|
'unauthorized_client': 'The client is not authorized to request an authorization code using this method',
|
||||||
|
|
||||||
'access_denied': 'The resource owner or authorization server denied the request',
|
'access_denied': 'The resource owner or authorization server denied the request',
|
||||||
'unsupported_response_type': 'The authorization server does not support obtaining an authorization code using this method',
|
|
||||||
|
'unsupported_response_type': 'The authorization server does not support obtaining an authorization code using '
|
||||||
|
'this method',
|
||||||
|
|
||||||
'invalid_scope': 'The requested scope is invalid, unknown, or malformed',
|
'invalid_scope': 'The requested scope is invalid, unknown, or malformed',
|
||||||
|
|
||||||
'server_error': 'The authorization server encountered an error',
|
'server_error': 'The authorization server encountered an error',
|
||||||
'temporarily_unavailable': 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server',
|
|
||||||
|
'temporarily_unavailable': 'The authorization server is currently unable to handle the request due to a '
|
||||||
|
'temporary overloading or maintenance of the server',
|
||||||
|
|
||||||
# OpenID errors.
|
# OpenID errors.
|
||||||
# http://openid.net/specs/openid-connect-core-1_0.html#AuthError
|
# http://openid.net/specs/openid-connect-core-1_0.html#AuthError
|
||||||
'interaction_required': 'The Authorization Server requires End-User interaction of some form to proceed',
|
'interaction_required': 'The Authorization Server requires End-User interaction of some form to proceed',
|
||||||
|
|
||||||
'login_required': 'The Authorization Server requires End-User authentication',
|
'login_required': 'The Authorization Server requires End-User authentication',
|
||||||
|
|
||||||
'account_selection_required': 'The End-User is required to select a session at the Authorization Server',
|
'account_selection_required': 'The End-User is required to select a session at the Authorization Server',
|
||||||
|
|
||||||
'consent_required': 'The Authorization Server requires End-User consent',
|
'consent_required': 'The Authorization Server requires End-User consent',
|
||||||
|
|
||||||
'invalid_request_uri': 'The request_uri in the Authorization Request returns an error or contains invalid data',
|
'invalid_request_uri': 'The request_uri in the Authorization Request returns an error or contains invalid data',
|
||||||
|
|
||||||
'invalid_request_object': 'The request parameter contains an invalid Request Object',
|
'invalid_request_object': 'The request parameter contains an invalid Request Object',
|
||||||
|
|
||||||
'request_not_supported': 'The provider does not support use of the request parameter',
|
'request_not_supported': 'The provider does not support use of the request parameter',
|
||||||
|
|
||||||
'request_uri_not_supported': 'The provider does not support use of the request_uri parameter',
|
'request_uri_not_supported': 'The provider does not support use of the request_uri parameter',
|
||||||
|
|
||||||
'registration_not_supported': 'The provider does not support use of the registration parameter',
|
'registration_not_supported': 'The provider does not support use of the registration parameter',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,17 +84,26 @@ class AuthorizeError(Exception):
|
||||||
def response(self):
|
def response(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TokenError(Exception):
|
class TokenError(Exception):
|
||||||
|
|
||||||
_errors = {
|
_errors = {
|
||||||
# Oauth2 errors.
|
# Oauth2 errors.
|
||||||
# https://tools.ietf.org/html/rfc6749#section-5.2
|
# https://tools.ietf.org/html/rfc6749#section-5.2
|
||||||
'invalid_request': 'The request is otherwise malformed',
|
'invalid_request': 'The request is otherwise malformed',
|
||||||
'invalid_client': 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)',
|
|
||||||
'invalid_grant': 'The provided authorization grant or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client',
|
'invalid_client': 'Client authentication failed (e.g., unknown client, no client authentication included, '
|
||||||
|
'or unsupported authentication method)',
|
||||||
|
|
||||||
|
'invalid_grant': 'The provided authorization grant or refresh token is invalid, expired, revoked, does not '
|
||||||
|
'match the redirection URI used in the authorization request, or was issued to another client',
|
||||||
|
|
||||||
'unauthorized_client': 'The authenticated client is not authorized to use this authorization grant type',
|
'unauthorized_client': 'The authenticated client is not authorized to use this authorization grant type',
|
||||||
|
|
||||||
'unsupported_grant_type': 'The authorization grant type is not supported by the authorization server',
|
'unsupported_grant_type': 'The authorization grant type is not supported by the authorization server',
|
||||||
'invalid_scope': 'The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner',
|
|
||||||
|
'invalid_scope': 'The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the '
|
||||||
|
'resource owner',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, error):
|
def __init__(self, error):
|
||||||
|
@ -92,14 +120,20 @@ class TokenError(Exception):
|
||||||
|
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
class UserInfoError(Exception):
|
|
||||||
|
|
||||||
|
class UserInfoError(Exception):
|
||||||
_errors = {
|
_errors = {
|
||||||
# Oauth2 errors.
|
# Oauth2 errors.
|
||||||
# https://tools.ietf.org/html/rfc6750#section-3.1
|
# https://tools.ietf.org/html/rfc6750#section-3.1
|
||||||
'invalid_request': ('The request is otherwise malformed', 400),
|
'invalid_request': (
|
||||||
'invalid_token': ('The access token provided is expired, revoked, malformed, or invalid for other reasons', 401),
|
'The request is otherwise malformed', 400
|
||||||
'insufficient_scope': ('The request requires higher privileges than provided by the access token', 403),
|
),
|
||||||
|
'invalid_token': (
|
||||||
|
'The access token provided is expired, revoked, malformed, or invalid for other reasons', 401
|
||||||
|
),
|
||||||
|
'insufficient_scope': (
|
||||||
|
'The request requires higher privileges than provided by the access token', 403
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, code):
|
def __init__(self, code):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from openid_provider.models import UserInfo
|
from openid_provider.models import UserInfo
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,10 +33,10 @@ class StandardClaims(object):
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
def _scopes_registered(self):
|
def _scopes_registered(self):
|
||||||
'''
|
"""
|
||||||
Return a list that contains all the scopes registered
|
Return a list that contains all the scopes registered
|
||||||
in the class.
|
in the class.
|
||||||
'''
|
"""
|
||||||
scopes = []
|
scopes = []
|
||||||
|
|
||||||
for name in self.__class__.__dict__:
|
for name in self.__class__.__dict__:
|
||||||
|
@ -47,9 +48,9 @@ class StandardClaims(object):
|
||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
def _clean_dic(self, dic):
|
def _clean_dic(self, dic):
|
||||||
'''
|
"""
|
||||||
Clean recursively all empty or None values inside a dict.
|
Clean recursively all empty or None values inside a dict.
|
||||||
'''
|
"""
|
||||||
aux_dic = dic.copy()
|
aux_dic = dic.copy()
|
||||||
for key, value in dic.iteritems():
|
for key, value in dic.iteritems():
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
|
|
||||||
class Params(object):
|
class Params(object):
|
||||||
'''
|
"""
|
||||||
The purpose of this class is for accesing params via dot notation.
|
The purpose of this class is for accesing params via dot notation.
|
||||||
'''
|
"""
|
||||||
pass
|
pass
|
|
@ -1,19 +1,21 @@
|
||||||
from datetime import timedelta
|
|
||||||
from django.utils import timezone
|
|
||||||
import jwt
|
|
||||||
from openid_provider.models import *
|
|
||||||
import time
|
import time
|
||||||
|
import jwt
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from django.utils import timezone
|
||||||
|
from openid_provider.models import *
|
||||||
|
|
||||||
|
|
||||||
def create_id_token_dic(user, iss, aud):
|
def create_id_token_dic(user, iss, aud):
|
||||||
'''
|
"""
|
||||||
Receives a user object, iss (issuer) and aud (audience).
|
Receives a user object, iss (issuer) and aud (audience).
|
||||||
Then creates the id_token dic.
|
Then creates the id_token dic.
|
||||||
See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
|
||||||
|
|
||||||
Return a dic.
|
Return a dic.
|
||||||
'''
|
"""
|
||||||
expires_in = 60*10
|
expires_in = 60*10
|
||||||
|
|
||||||
now = timezone.now()
|
now = timezone.now()
|
||||||
|
@ -34,22 +36,24 @@ def create_id_token_dic(user, iss, aud):
|
||||||
|
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
|
|
||||||
def encode_id_token(id_token_dic, client_secret):
|
def encode_id_token(id_token_dic, client_secret):
|
||||||
'''
|
"""
|
||||||
Represent the ID Token as a JSON Web Token (JWT).
|
Represent the ID Token as a JSON Web Token (JWT).
|
||||||
|
|
||||||
Return a hash.
|
Return a hash.
|
||||||
'''
|
"""
|
||||||
id_token_hash = jwt.encode(id_token_dic, client_secret)
|
id_token_hash = jwt.encode(id_token_dic, client_secret)
|
||||||
|
|
||||||
return id_token_hash
|
return id_token_hash
|
||||||
|
|
||||||
|
|
||||||
def create_token(user, client, id_token_dic, scope):
|
def create_token(user, client, id_token_dic, scope):
|
||||||
'''
|
"""
|
||||||
Create and populate a Token object.
|
Create and populate a Token object.
|
||||||
|
|
||||||
Return a Token object.
|
Return a Token object.
|
||||||
'''
|
"""
|
||||||
token = Token()
|
token = Token()
|
||||||
token.user = user
|
token.user = user
|
||||||
token.client = client
|
token.client = client
|
||||||
|
@ -58,7 +62,7 @@ def create_token(user, client, id_token_dic, scope):
|
||||||
token.id_token = id_token_dic
|
token.id_token = id_token_dic
|
||||||
|
|
||||||
token.refresh_token = uuid.uuid4().hex
|
token.refresh_token = uuid.uuid4().hex
|
||||||
token.expires_at = timezone.now() + timedelta(seconds=60*60) # TODO: Add this into settings.
|
token.expires_at = timezone.now() + timedelta(seconds=60*60) # TODO: Add this into settings.
|
||||||
token.scope = scope
|
token.scope = scope
|
||||||
|
|
||||||
return token
|
return token
|
|
@ -1,7 +1,8 @@
|
||||||
from django.contrib.auth.models import User
|
import json
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
import json
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
class Client(models.Model):
|
class Client(models.Model):
|
||||||
|
@ -18,6 +19,7 @@ class Client(models.Model):
|
||||||
response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES)
|
response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES)
|
||||||
|
|
||||||
_redirect_uris = models.TextField(default='')
|
_redirect_uris = models.TextField(default='')
|
||||||
|
|
||||||
def redirect_uris():
|
def redirect_uris():
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return self._redirect_uris.splitlines()
|
return self._redirect_uris.splitlines()
|
||||||
|
@ -30,6 +32,7 @@ class Client(models.Model):
|
||||||
def default_redirect_uri(self):
|
def default_redirect_uri(self):
|
||||||
return self.redirect_uris[0] if self.redirect_uris else ''
|
return self.redirect_uris[0] if self.redirect_uris else ''
|
||||||
|
|
||||||
|
|
||||||
class Code(models.Model):
|
class Code(models.Model):
|
||||||
|
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
|
@ -38,6 +41,7 @@ class Code(models.Model):
|
||||||
expires_at = models.DateTimeField()
|
expires_at = models.DateTimeField()
|
||||||
|
|
||||||
_scope = models.TextField(default='')
|
_scope = models.TextField(default='')
|
||||||
|
|
||||||
def scope():
|
def scope():
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return self._scope.split()
|
return self._scope.split()
|
||||||
|
@ -49,6 +53,7 @@ class Code(models.Model):
|
||||||
def has_expired(self):
|
def has_expired(self):
|
||||||
return timezone.now() >= self.expires_at
|
return timezone.now() >= self.expires_at
|
||||||
|
|
||||||
|
|
||||||
class Token(models.Model):
|
class Token(models.Model):
|
||||||
|
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
|
@ -57,6 +62,7 @@ class Token(models.Model):
|
||||||
expires_at = models.DateTimeField()
|
expires_at = models.DateTimeField()
|
||||||
|
|
||||||
_scope = models.TextField(default='')
|
_scope = models.TextField(default='')
|
||||||
|
|
||||||
def scope():
|
def scope():
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return self._scope.split()
|
return self._scope.split()
|
||||||
|
@ -66,6 +72,7 @@ class Token(models.Model):
|
||||||
scope = property(**scope())
|
scope = property(**scope())
|
||||||
|
|
||||||
_id_token = models.TextField()
|
_id_token = models.TextField()
|
||||||
|
|
||||||
def id_token():
|
def id_token():
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return json.loads(self._id_token)
|
return json.loads(self._id_token)
|
||||||
|
@ -74,6 +81,7 @@ class Token(models.Model):
|
||||||
return locals()
|
return locals()
|
||||||
id_token = property(**id_token())
|
id_token = property(**id_token())
|
||||||
|
|
||||||
|
|
||||||
class UserInfo(models.Model):
|
class UserInfo(models.Model):
|
||||||
|
|
||||||
user = models.OneToOneField(User, primary_key=True)
|
user = models.OneToOneField(User, primary_key=True)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from django.conf.urls import patterns, include, url
|
from django.conf.urls import patterns, include, url
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
from openid_provider.views import *
|
from openid_provider.views import *
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
|
url(r'^authorize/$', AuthorizeView.as_view(), name='authorize'),
|
||||||
url(r'^authorize/$', AuthorizeView.as_view(), name='authorize'),
|
url(r'^token/$', csrf_exempt(TokenView.as_view()), name='token'),
|
||||||
url(r'^token/$', csrf_exempt(TokenView.as_view()), name='token'),
|
url(r'^userinfo/$', csrf_exempt(userinfo), name='userinfo'),
|
||||||
url(r'^userinfo/$', csrf_exempt(userinfo), name='userinfo'),
|
|
||||||
|
|
||||||
)
|
)
|
|
@ -5,7 +5,7 @@ from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
import urllib
|
|
||||||
from openid_provider.lib.errors import *
|
from openid_provider.lib.errors import *
|
||||||
from openid_provider.lib.endpoints.authorize import *
|
from openid_provider.lib.endpoints.authorize import *
|
||||||
from openid_provider.lib.endpoints.token import *
|
from openid_provider.lib.endpoints.token import *
|
||||||
|
@ -69,6 +69,7 @@ class AuthorizeView(View):
|
||||||
|
|
||||||
return HttpResponseRedirect(uri)
|
return HttpResponseRedirect(uri)
|
||||||
|
|
||||||
|
|
||||||
class TokenView(View):
|
class TokenView(View):
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
@ -101,4 +102,4 @@ def userinfo(request):
|
||||||
return UserInfoEndpoint.error_response(
|
return UserInfoEndpoint.error_response(
|
||||||
error.code,
|
error.code,
|
||||||
error.description,
|
error.description,
|
||||||
error.status)
|
error.status)
|
||||||
|
|
Loading…
Reference in a new issue