diff --git a/README.rst b/README.rst index 7707fa6..2f9167a 100644 --- a/README.rst +++ b/README.rst @@ -46,9 +46,29 @@ Add the provider urls. # ... ) -Finally, add a login view and ensure that has the same url defined in `LOGIN_URL` setting. +******** +Settings +******** + +Add required variables to your project settings. + +.. code:: python + + # REQUIRED. + + # Your server provider url. + SITE_URL = 'http://localhost:8000' + + # Used to log the user in. + # See: https://docs.djangoproject.com/en/1.7/ref/settings/#login-url + LOGIN_URL = '/accounts/login/' + + # OPTIONAL. + + DOP_CODE_EXPIRE = 60*10 # 10 min. + DOP_IDTOKEN_EXPIRE = 60*10, # 10 min. + DOP_TOKEN_EXPIRE = 60*60 # 1 hour. -See: https://docs.djangoproject.com/en/1.7/ref/settings/#login-url ******************** Create User & Client @@ -61,7 +81,7 @@ Then let's create a Client. Start django shell: ``python manage.py shell``. .. code:: python >>> from openid_provider.models import Client - >>> c = Client(name='Some Client', client_id='123', client_secret='456', client_type='confidential', response_type='code', redirect_uris=['http://example.com/']) + >>> c = Client(name='Some Client', client_id='123', client_secret='456', response_type='code', redirect_uris=['http://example.com/']) >>> c.save() ******************* diff --git a/openid_provider/lib/endpoints/authorize.py b/openid_provider/lib/endpoints/authorize.py index 49ade1d..31f4006 100644 --- a/openid_provider/lib/endpoints/authorize.py +++ b/openid_provider/lib/endpoints/authorize.py @@ -4,6 +4,8 @@ from datetime import timedelta from django.utils import timezone +from openid_provider import settings + from ..errors import * from ..utils.params import * from ..utils.token import * @@ -99,7 +101,8 @@ class AuthorizeEndpoint(object): code.user = self.request.user code.client = self.client 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=settings.get('DOP_CODE_EXPIRE')) code.scope = self.params.scope code.save() @@ -109,7 +112,7 @@ class AuthorizeEndpoint(object): id_token_dic = create_id_token_dic( self.request.user, - 'http://localhost:8000', # TODO: Add this into settings. + settings.get('SITE_URL'), self.client.client_id) token = create_token( @@ -121,14 +124,15 @@ class AuthorizeEndpoint(object): # Store the token. token.save() - id_token = encode_id_token(id_token_dic, self.client.client_secret) - + id_token = encode_id_token( + id_token_dic, self.client.client_secret) + # TODO: Check if response_type is 'id_token token' then # add access_token to the fragment. uri = self.params.redirect_uri + '#token_type={0}&id_token={1}&expires_in={2}'.format( 'bearer', id_token, - 60*10 + 60 * 10 ) except: raise AuthorizeError( @@ -137,6 +141,8 @@ class AuthorizeEndpoint(object): self.grant_type) # Add state if present. - uri = uri + ('&state={0}'.format(self.params.state) if self.params.state else '') + uri = uri + \ + ('&state={0}'.format(self.params.state) + if self.params.state else '') - return uri \ No newline at end of file + return uri diff --git a/openid_provider/lib/endpoints/token.py b/openid_provider/lib/endpoints/token.py index 1ae224c..6521de3 100644 --- a/openid_provider/lib/endpoints/token.py +++ b/openid_provider/lib/endpoints/token.py @@ -4,6 +4,8 @@ try: # JsonResponse is only available in Django > 1.7 from django.http import JsonResponse except ImportError: from ..utils.http import JsonResponse + +from openid_provider import settings from ..utils.http import JsonResponse from ..errors import * @@ -27,7 +29,8 @@ class TokenEndpoint(object): self.params.client_id = query_dict.get('client_id', '') self.params.client_secret = query_dict.get('client_secret', '') - self.params.redirect_uri = urllib.unquote(query_dict.get('redirect_uri', '')) + self.params.redirect_uri = urllib.unquote( + query_dict.get('redirect_uri', '')) self.params.grant_type = query_dict.get('grant_type', '') self.params.code = query_dict.get('code', '') self.params.state = query_dict.get('state', '') @@ -48,7 +51,8 @@ class TokenEndpoint(object): self.code = Code.objects.get(code=self.params.code) - if not (self.code.client == self.client) and not self.code.has_expired(): + if not (self.code.client == self.client) and \ + not self.code.has_expired(): raise TokenError('invalid_grant') except Client.DoesNotExist: @@ -61,16 +65,14 @@ class TokenEndpoint(object): id_token_dic = create_id_token_dic( self.code.user, - 'http://localhost:8000', # TODO: Add this into settings. - self.client.client_id - ) + settings.get('SITE_URL'), + self.client.client_id) token = create_token( user=self.code.user, client=self.code.client, id_token_dic=id_token_dic, - scope=self.code.scope - ) + scope=self.code.scope) # Store the token. token.save() @@ -83,7 +85,7 @@ class TokenEndpoint(object): dic = { 'access_token': token.access_token, 'token_type': 'bearer', - 'expires_in': 60*60, # TODO: Add this into settings. + 'expires_in': settings.get('DOP_TOKEN_EXPIRE'), 'id_token': id_token, } @@ -98,4 +100,4 @@ class TokenEndpoint(object): response['Cache-Control'] = 'no-store' response['Pragma'] = 'no-cache' - return response \ No newline at end of file + return response diff --git a/openid_provider/lib/utils/token.py b/openid_provider/lib/utils/token.py index 6adf7ed..c6be891 100644 --- a/openid_provider/lib/utils/token.py +++ b/openid_provider/lib/utils/token.py @@ -4,6 +4,7 @@ import uuid from datetime import timedelta +from openid_provider import settings from django.utils import timezone from openid_provider.models import * @@ -16,7 +17,7 @@ def create_id_token_dic(user, iss, aud): Return a dic. """ - expires_in = 60*10 + expires_in = settings.get('DOP_IDTOKEN_EXPIRE') now = timezone.now() @@ -62,7 +63,8 @@ def create_token(user, client, id_token_dic, scope): token.id_token = id_token_dic 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=settings.get('DOP_TOKEN_EXPIRE')) token.scope = scope - return token \ No newline at end of file + return token diff --git a/openid_provider/settings.py b/openid_provider/settings.py new file mode 100644 index 0000000..3662d10 --- /dev/null +++ b/openid_provider/settings.py @@ -0,0 +1,27 @@ +from django.conf import settings + + +# Here goes all the package default settings. +default_settings = { + 'DOP_CODE_EXPIRE': 60 * 10, # 10 min. + 'DOP_IDTOKEN_EXPIRE': 60 * 10, # 10 min. + 'DOP_TOKEN_EXPIRE': 60 * 60, # 1 hour. + 'LOGIN_URL': None, + 'SITE_URL': None, +} + + +def get(name): + """ + Helper function to use inside the package. + :param name: + :return: + """ + try: + value = default_settings[name] + value = getattr(settings, name) + except AttributeError: + if value == None: + raise Exception('You must set ' + name + ' in your settings.') + + return value diff --git a/openid_provider/views.py b/openid_provider/views.py index 8311321..03b29ad 100644 --- a/openid_provider/views.py +++ b/openid_provider/views.py @@ -15,6 +15,8 @@ from .lib.endpoints.authorize import * from .lib.endpoints.token import * from .lib.endpoints.userinfo import * +from openid_provider import settings + class AuthorizeView(View): @@ -39,7 +41,7 @@ class AuthorizeView(View): else: path = request.get_full_path() return redirect_to_login( - path, settings.LOGIN_URL, REDIRECT_FIELD_NAME) + path, settings.get('LOGIN_URL'), REDIRECT_FIELD_NAME) except (ClientIdError, RedirectUriError) as error: context = { @@ -105,4 +107,4 @@ def userinfo(request): return UserInfoEndpoint.error_response( error.code, error.description, - error.status) \ No newline at end of file + error.status)