Merge pull request #4 from juanifioren/v0.3.x

merge v0.3.x branch
This commit is contained in:
Wojciech Bartosiak 2016-04-06 18:06:23 +01:00
commit 68ce127e31
10 changed files with 85 additions and 23 deletions

View file

@ -4,6 +4,14 @@ 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
- response_type was not being validated (OpenID request).
### [0.3.0] - 2016-02-23
##### Added

View file

@ -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

View file

@ -30,10 +30,19 @@ class ClientForm(ModelForm):
def clean_client_secret(self):
instance = getattr(self, 'instance', None)
secret = ''
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)

View file

@ -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',

View file

@ -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):

View file

@ -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)

View file

@ -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='<b>Confidential</b> clients are capable of maintaining the confidentiality of their credentials. <b>Public</b> clients are incapable.', max_length=30),
),
]

View file

@ -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),
),
]

View file

@ -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'<b>Confidential</b> clients are capable of maintaining the confidentiality of their credentials. <b>Public</b> 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)
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)
_redirect_uris = models.TextField(default='', verbose_name=_(u'Redirect URI'), help_text=_(u'Enter each URI on a new line.'))

View file

@ -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',