From 3c0a5e6e04d39aab655f8309ef2d173344977874 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Wed, 9 Mar 2016 12:11:59 -0300 Subject: [PATCH 1/6] Bump version v0.3.1. --- CHANGELOG.md | 5 +++++ LICENSE | 2 +- setup.py | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae386af..d2c88b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. ### [Unreleased] +### [0.3.1] - 2016-03-09 + +##### Fixed +- response_type was not being validated (OpenID request). + ### [0.3.0] - 2016-02-23 ##### Added diff --git a/LICENSE b/LICENSE index cc208c6..eef5213 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Juan Ignacio Fiorentino +Copyright (c) 2014-2016 Juan Ignacio Fiorentino Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/setup.py b/setup.py index 66813ef..cb1a60e 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) setup( name='django-oidc-provider', - version='0.3.0', + version='0.3.1', packages=[ 'oidc_provider', 'oidc_provider/lib', 'oidc_provider/lib/endpoints', 'oidc_provider/lib/utils', 'oidc_provider/tests', 'oidc_provider/tests/app', From f8dce31fa2c7676928963bfb2337c1d7a39fd6e6 Mon Sep 17 00:00:00 2001 From: Nick Mohoric Date: Thu, 17 Mar 2016 14:31:41 -0400 Subject: [PATCH 2/6] Changed logging from error to debug --- oidc_provider/lib/endpoints/authorize.py | 10 +++++----- oidc_provider/lib/endpoints/token.py | 16 ++++++++-------- oidc_provider/lib/utils/oauth2.py | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/oidc_provider/lib/endpoints/authorize.py b/oidc_provider/lib/endpoints/authorize.py index f571c81..56972a4 100644 --- a/oidc_provider/lib/endpoints/authorize.py +++ b/oidc_provider/lib/endpoints/authorize.py @@ -60,15 +60,15 @@ class AuthorizeEndpoint(object): try: self.client = Client.objects.get(client_id=self.params.client_id) except Client.DoesNotExist: - logger.error('[Authorize] Invalid client identifier: %s', self.params.client_id) + logger.debug('[Authorize] Invalid client identifier: %s', self.params.client_id) raise ClientIdError() if self.is_authentication and not self.params.redirect_uri: - logger.error('[Authorize] Missing redirect uri.') + logger.debug('[Authorize] Missing redirect uri.') raise RedirectUriError() if not self.grant_type: - logger.error('[Authorize] Invalid response type: %s', self.params.response_type) + logger.debug('[Authorize] Invalid response type: %s', self.params.response_type) raise AuthorizeError(self.params.redirect_uri, 'unsupported_response_type', self.grant_type) @@ -83,7 +83,7 @@ class AuthorizeEndpoint(object): clean_redirect_uri = urlsplit(self.params.redirect_uri) clean_redirect_uri = urlunsplit(clean_redirect_uri._replace(query='')) if not (clean_redirect_uri in self.client.redirect_uris): - logger.error('[Authorize] Invalid redirect uri: %s', self.params.redirect_uri) + logger.debug('[Authorize] Invalid redirect uri: %s', self.params.redirect_uri) raise RedirectUriError() @@ -138,7 +138,7 @@ class AuthorizeEndpoint(object): query_fragment['state'] = self.params.state if self.params.state else '' except Exception as error: - logger.error('[Authorize] Error when trying to create response uri: %s', error) + logger.debug('[Authorize] Error when trying to create response uri: %s', error) raise AuthorizeError( self.params.redirect_uri, 'server_error', diff --git a/oidc_provider/lib/endpoints/token.py b/oidc_provider/lib/endpoints/token.py index a134f4f..a981eee 100644 --- a/oidc_provider/lib/endpoints/token.py +++ b/oidc_provider/lib/endpoints/token.py @@ -65,34 +65,34 @@ class TokenEndpoint(object): try: self.client = Client.objects.get(client_id=self.params.client_id) except Client.DoesNotExist: - logger.error('[Token] Client does not exist: %s', self.params.client_id) + logger.debug('[Token] Client does not exist: %s', self.params.client_id) raise TokenError('invalid_client') if not (self.client.client_secret == self.params.client_secret): - logger.error('[Token] Invalid client secret: client %s do not have secret %s', + logger.debug('[Token] Invalid client secret: client %s do not have secret %s', self.client.client_id, self.client.client_secret) raise TokenError('invalid_client') if self.params.grant_type == 'authorization_code': if not (self.params.redirect_uri in self.client.redirect_uris): - logger.error('[Token] Invalid redirect uri: %s', self.params.redirect_uri) + logger.debug('[Token] Invalid redirect uri: %s', self.params.redirect_uri) raise TokenError('invalid_client') try: self.code = Code.objects.get(code=self.params.code) except Code.DoesNotExist: - logger.error('[Token] Code does not exist: %s', self.params.code) + logger.debug('[Token] Code does not exist: %s', self.params.code) raise TokenError('invalid_grant') if not (self.code.client == self.client) \ or self.code.has_expired(): - logger.error('[Token] Invalid code: invalid client or code has expired', + logger.debug('[Token] Invalid code: invalid client or code has expired', self.params.redirect_uri) raise TokenError('invalid_grant') elif self.params.grant_type == 'refresh_token': if not self.params.refresh_token: - logger.error('[Token] Missing refresh token') + logger.debug('[Token] Missing refresh token') raise TokenError('invalid_grant') try: @@ -100,11 +100,11 @@ class TokenEndpoint(object): client=self.client) except Token.DoesNotExist: - logger.error('[Token] Refresh token does not exist: %s', self.params.refresh_token) + logger.debug('[Token] Refresh token does not exist: %s', self.params.refresh_token) raise TokenError('invalid_grant') else: - logger.error('[Token] Invalid grant type: %s', self.params.grant_type) + logger.debug('[Token] Invalid grant type: %s', self.params.grant_type) raise TokenError('unsupported_grant_type') def create_response_dic(self): diff --git a/oidc_provider/lib/utils/oauth2.py b/oidc_provider/lib/utils/oauth2.py index 9d54e75..eba482c 100644 --- a/oidc_provider/lib/utils/oauth2.py +++ b/oidc_provider/lib/utils/oauth2.py @@ -42,15 +42,15 @@ def protected_resource_view(scopes=[]): try: kwargs['token'] = Token.objects.get(access_token=access_token) except Token.DoesNotExist: - logger.error('[UserInfo] Token does not exist: %s', access_token) + logger.debug('[UserInfo] Token does not exist: %s', access_token) raise BearerTokenError('invalid_token') if kwargs['token'].has_expired(): - logger.error('[UserInfo] Token has expired: %s', access_token) + logger.debug('[UserInfo] Token has expired: %s', access_token) raise BearerTokenError('invalid_token') if not set(scopes).issubset(set(kwargs['token'].scope)): - logger.error('[UserInfo] Missing openid scope.') + logger.debug('[UserInfo] Missing openid scope.') raise BearerTokenError('insufficient_scope') except (BearerTokenError) as error: response = HttpResponse(status=error.status) From 1a74bcbc5cdc10a40bd6b252ef59836b6c39c959 Mon Sep 17 00:00:00 2001 From: Ignacio Fiorentino Date: Mon, 4 Apr 2016 17:19:49 -0300 Subject: [PATCH 3/6] Add client type to client creation form. --- .../migrations/0011_client_client_type.py | 20 +++++++++++++++++++ oidc_provider/models.py | 9 +++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 oidc_provider/migrations/0011_client_client_type.py diff --git a/oidc_provider/migrations/0011_client_client_type.py b/oidc_provider/migrations/0011_client_client_type.py new file mode 100644 index 0000000..26e9fc3 --- /dev/null +++ b/oidc_provider/migrations/0011_client_client_type.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-04-04 19:56 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('oidc_provider', '0010_code_is_authentication'), + ] + + operations = [ + migrations.AddField( + model_name='client', + name='client_type', + field=models.CharField(choices=[(b'confidential', b'Confidential'), (b'public', b'Public')], default=b'confidential', help_text='Confidential clients are capable of maintaining the confidentiality of their credentials. Public clients are incapable.', max_length=30), + ), + ] diff --git a/oidc_provider/models.py b/oidc_provider/models.py index 68ace73..69dcc39 100644 --- a/oidc_provider/models.py +++ b/oidc_provider/models.py @@ -10,6 +10,11 @@ from django.conf import settings class Client(models.Model): + CLIENT_TYPE_CHOICES = [ + ('confidential', 'Confidential'), + ('public', 'Public'), + ] + RESPONSE_TYPE_CHOICES = [ ('code', 'code (Authorization Code Flow)'), ('id_token', 'id_token (Implicit Flow)'), @@ -17,10 +22,10 @@ class Client(models.Model): ] name = models.CharField(max_length=100, default='') + client_type = models.CharField(max_length=30, choices=CLIENT_TYPE_CHOICES, default='confidential', help_text=_(u'Confidential clients are capable of maintaining the confidentiality of their credentials. Public clients are incapable.')) client_id = models.CharField(max_length=255, unique=True) client_secret = models.CharField(max_length=255, unique=True) - response_type = models.CharField(max_length=30, - choices=RESPONSE_TYPE_CHOICES) + response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES) date_created = models.DateField(auto_now_add=True) _redirect_uris = models.TextField(default='', verbose_name=_(u'Redirect URI'), help_text=_(u'Enter each URI on a new line.')) From fa2c7d314de541a435ab205b1120fb345074756f Mon Sep 17 00:00:00 2001 From: Ignacio Fiorentino Date: Mon, 4 Apr 2016 17:25:28 -0300 Subject: [PATCH 4/6] Edit CHANGELOG. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c88b7..7a2b927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. ### [Unreleased] +##### Added +- Choose type of client on creation. + ### [0.3.1] - 2016-03-09 ##### Fixed From a3247db273fd26b787dca71432cf3f9b699a5882 Mon Sep 17 00:00:00 2001 From: Ignacio Fiorentino Date: Tue, 5 Apr 2016 18:31:08 -0300 Subject: [PATCH 5/6] Improve handle of client_secret with client_types. --- oidc_provider/admin.py | 15 ++++++++++++-- .../migrations/0012_auto_20160405_2041.py | 20 +++++++++++++++++++ oidc_provider/models.py | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 oidc_provider/migrations/0012_auto_20160405_2041.py diff --git a/oidc_provider/admin.py b/oidc_provider/admin.py index 9963b35..9b3bd0a 100644 --- a/oidc_provider/admin.py +++ b/oidc_provider/admin.py @@ -30,10 +30,21 @@ class ClientForm(ModelForm): def clean_client_secret(self): instance = getattr(self, 'instance', None) + + secret = '' + + print self.cleaned_data + if instance and instance.pk: - return instance.client_secret + if (self.cleaned_data['client_type'] == 'confidential') and not instance.client_secret: + secret = md5(uuid4().hex.encode()).hexdigest() + elif (self.cleaned_data['client_type'] == 'confidential') and instance.client_secret: + secret = instance.client_secret else: - return md5(uuid4().hex.encode()).hexdigest() + if (instance.client_type == 'confidential'): + secret = md5(uuid4().hex.encode()).hexdigest() + + return secret @admin.register(Client) diff --git a/oidc_provider/migrations/0012_auto_20160405_2041.py b/oidc_provider/migrations/0012_auto_20160405_2041.py new file mode 100644 index 0000000..c04b613 --- /dev/null +++ b/oidc_provider/migrations/0012_auto_20160405_2041.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-04-05 20:41 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('oidc_provider', '0011_client_client_type'), + ] + + operations = [ + migrations.AlterField( + model_name='client', + name='client_secret', + field=models.CharField(blank=True, default=b'', max_length=255), + ), + ] diff --git a/oidc_provider/models.py b/oidc_provider/models.py index 69dcc39..8d9ad39 100644 --- a/oidc_provider/models.py +++ b/oidc_provider/models.py @@ -24,7 +24,7 @@ class Client(models.Model): name = models.CharField(max_length=100, default='') client_type = models.CharField(max_length=30, choices=CLIENT_TYPE_CHOICES, default='confidential', help_text=_(u'Confidential clients are capable of maintaining the confidentiality of their credentials. Public clients are incapable.')) client_id = models.CharField(max_length=255, unique=True) - client_secret = models.CharField(max_length=255, unique=True) + client_secret = models.CharField(max_length=255, blank=True, default='') response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES) date_created = models.DateField(auto_now_add=True) From 2c4ab6695e2f781ee2314637a2509f6a59e2f0a6 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Fiorentino Date: Tue, 5 Apr 2016 19:08:49 -0300 Subject: [PATCH 6/6] Removing print. --- oidc_provider/admin.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/oidc_provider/admin.py b/oidc_provider/admin.py index 9b3bd0a..2a4fc61 100644 --- a/oidc_provider/admin.py +++ b/oidc_provider/admin.py @@ -33,8 +33,6 @@ class ClientForm(ModelForm): secret = '' - print self.cleaned_data - if instance and instance.pk: if (self.cleaned_data['client_type'] == 'confidential') and not instance.client_secret: secret = md5(uuid4().hex.encode()).hexdigest()