Merge branch 'wojtek-fliposports-v0.4.x' into v0.4.x
This commit is contained in:
commit
b36dcf8442
6 changed files with 71 additions and 4 deletions
|
@ -25,6 +25,7 @@ from oidc_provider.models import (
|
||||||
UserConsent,
|
UserConsent,
|
||||||
)
|
)
|
||||||
from oidc_provider import settings
|
from oidc_provider import settings
|
||||||
|
from oidc_provider.lib.utils.common import cleanup_url_from_query_string
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -85,8 +86,7 @@ class AuthorizeEndpoint(object):
|
||||||
if self.is_authentication and not self.params['redirect_uri']:
|
if self.is_authentication and not self.params['redirect_uri']:
|
||||||
logger.debug('[Authorize] Missing redirect uri.')
|
logger.debug('[Authorize] Missing redirect uri.')
|
||||||
raise RedirectUriError()
|
raise RedirectUriError()
|
||||||
clean_redirect_uri = urlsplit(self.params['redirect_uri'])
|
clean_redirect_uri = cleanup_url_from_query_string(self.params['redirect_uri'])
|
||||||
clean_redirect_uri = urlunsplit(clean_redirect_uri._replace(query=''))
|
|
||||||
if not (clean_redirect_uri in self.client.redirect_uris):
|
if not (clean_redirect_uri in self.client.redirect_uris):
|
||||||
logger.debug('[Authorize] Invalid redirect uri: %s', self.params['redirect_uri'])
|
logger.debug('[Authorize] Invalid redirect uri: %s', self.params['redirect_uri'])
|
||||||
raise RedirectUriError()
|
raise RedirectUriError()
|
||||||
|
|
|
@ -2,6 +2,9 @@ from base64 import b64decode, urlsafe_b64encode
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from oidc_provider.lib.utils.common import cleanup_url_from_query_string
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -87,7 +90,8 @@ class TokenEndpoint(object):
|
||||||
raise TokenError('invalid_client')
|
raise TokenError('invalid_client')
|
||||||
|
|
||||||
if self.params['grant_type'] == 'authorization_code':
|
if self.params['grant_type'] == 'authorization_code':
|
||||||
if not (self.params['redirect_uri'] in self.client.redirect_uris):
|
clean_redirect_uri = cleanup_url_from_query_string(self.params['redirect_uri'])
|
||||||
|
if not (clean_redirect_uri in self.client.redirect_uris):
|
||||||
logger.debug('[Token] Invalid redirect uri: %s', self.params['redirect_uri'])
|
logger.debug('[Token] Invalid redirect uri: %s', self.params['redirect_uri'])
|
||||||
raise TokenError('invalid_client')
|
raise TokenError('invalid_client')
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,24 @@ from django.http import HttpResponse
|
||||||
|
|
||||||
from oidc_provider import settings
|
from oidc_provider import settings
|
||||||
|
|
||||||
|
try:
|
||||||
|
from urlparse import urlsplit, urlunsplit
|
||||||
|
except ImportError:
|
||||||
|
from urllib.parse import urlsplit, urlunsplit
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_url_from_query_string(uri):
|
||||||
|
"""
|
||||||
|
Function used to clean up the uri from any query string, used i.e. by endpoints to validate redirect_uri
|
||||||
|
|
||||||
|
:param uri: URI to clean from query string
|
||||||
|
:type uri: str
|
||||||
|
:return: cleaned URI without query string
|
||||||
|
"""
|
||||||
|
clean_uri = urlsplit(uri)
|
||||||
|
clean_uri = urlunsplit(clean_uri._replace(query=''))
|
||||||
|
return clean_uri
|
||||||
|
|
||||||
|
|
||||||
def redirect(uri):
|
def redirect(uri):
|
||||||
"""
|
"""
|
||||||
|
|
20
oidc_provider/migrations/0019_auto_20161005_1552.py
Normal file
20
oidc_provider/migrations/0019_auto_20161005_1552.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.2 on 2016-10-05 15:52
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('oidc_provider', '0018_hybridflow_and_clientattrs'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='client',
|
||||||
|
name='client_secret',
|
||||||
|
field=models.CharField(blank=True, max_length=255, verbose_name='Client SECRET'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -35,7 +35,7 @@ class Client(models.Model):
|
||||||
name = models.CharField(max_length=100, default='', verbose_name=_(u'Name'))
|
name = models.CharField(max_length=100, default='', verbose_name=_(u'Name'))
|
||||||
client_type = models.CharField(max_length=30, choices=CLIENT_TYPE_CHOICES, default='confidential', verbose_name=_(u'Client Type'), help_text=_(u'<b>Confidential</b> clients are capable of maintaining the confidentiality of their credentials. <b>Public</b> clients are incapable.'))
|
client_type = models.CharField(max_length=30, choices=CLIENT_TYPE_CHOICES, default='confidential', verbose_name=_(u'Client Type'), 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, verbose_name=_(u'Client ID'))
|
client_id = models.CharField(max_length=255, unique=True, verbose_name=_(u'Client ID'))
|
||||||
client_secret = models.CharField(max_length=255, blank=True, default='', verbose_name=_(u'Client SECRET'))
|
client_secret = models.CharField(max_length=255, blank=True, verbose_name=_(u'Client SECRET'))
|
||||||
response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES, verbose_name=_(u'Response Type'))
|
response_type = models.CharField(max_length=30, choices=RESPONSE_TYPE_CHOICES, verbose_name=_(u'Response Type'))
|
||||||
jwt_alg = models.CharField(max_length=10, choices=JWT_ALGS, default='RS256', verbose_name=_(u'JWT Algorithm'), help_text=_(u'Algorithm used to encode ID Tokens.'))
|
jwt_alg = models.CharField(max_length=10, choices=JWT_ALGS, default='RS256', verbose_name=_(u'JWT Algorithm'), help_text=_(u'Algorithm used to encode ID Tokens.'))
|
||||||
date_created = models.DateField(auto_now_add=True, verbose_name=_(u'Date Created'))
|
date_created = models.DateField(auto_now_add=True, verbose_name=_(u'Date Created'))
|
||||||
|
|
|
@ -213,6 +213,31 @@ class TokenTestCase(TestCase):
|
||||||
response = self._post_request(post_data)
|
response = self._post_request(post_data)
|
||||||
self.assertIn('invalid_grant', response.content.decode('utf-8'))
|
self.assertIn('invalid_grant', response.content.decode('utf-8'))
|
||||||
|
|
||||||
|
def test_client_redirect_url(self):
|
||||||
|
"""
|
||||||
|
Validate that client redirect URIs with query strings match registered
|
||||||
|
URIs, and that unregistered URIs are rejected.
|
||||||
|
|
||||||
|
source: https://github.com/jerrykan/django-oidc-provider/blob/2f54e537666c689dd8448f8bbc6a3a0244b01a97/oidc_provider/tests/test_token_endpoint.py
|
||||||
|
"""
|
||||||
|
SIGKEYS = self._get_keys()
|
||||||
|
code = self._create_code()
|
||||||
|
post_data = self._auth_code_post_data(code=code.code)
|
||||||
|
|
||||||
|
# Unregistered URI
|
||||||
|
post_data['redirect_uri'] = 'http://invalid.example.org'
|
||||||
|
|
||||||
|
response = self._post_request(post_data)
|
||||||
|
|
||||||
|
self.assertIn('invalid_client', response.content.decode('utf-8')),
|
||||||
|
|
||||||
|
# Registered URI contained a query string
|
||||||
|
post_data['redirect_uri'] = 'http://example.com/?client=OidcClient'
|
||||||
|
|
||||||
|
response = self._post_request(post_data)
|
||||||
|
|
||||||
|
self.assertNotIn('invalid_client', response.content.decode('utf-8')),
|
||||||
|
|
||||||
def test_request_methods(self):
|
def test_request_methods(self):
|
||||||
"""
|
"""
|
||||||
Client sends an HTTP POST request to the Token Endpoint. Other request
|
Client sends an HTTP POST request to the Token Endpoint. Other request
|
||||||
|
|
Loading…
Reference in a new issue