Merge branch 'master' of https://github.com/juanifioren/django-oidc-provider into v0.1.x
This commit is contained in:
commit
3e22e44462
3 changed files with 65 additions and 20 deletions
|
@ -1,4 +1,6 @@
|
||||||
|
from base64 import b64decode
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
try:
|
try:
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -24,15 +26,38 @@ class TokenEndpoint(object):
|
||||||
self._extract_params()
|
self._extract_params()
|
||||||
|
|
||||||
def _extract_params(self):
|
def _extract_params(self):
|
||||||
query_dict = self.request.POST
|
client_id, client_secret = self._extract_client_auth()
|
||||||
|
|
||||||
self.params.client_id = query_dict.get('client_id', '')
|
self.params.client_id = client_id
|
||||||
self.params.client_secret = query_dict.get('client_secret', '')
|
self.params.client_secret = client_secret
|
||||||
self.params.redirect_uri = unquote(
|
self.params.redirect_uri = unquote(
|
||||||
query_dict.get('redirect_uri', ''))
|
self.request.POST.get('redirect_uri', ''))
|
||||||
self.params.grant_type = query_dict.get('grant_type', '')
|
self.params.grant_type = self.request.POST.get('grant_type', '')
|
||||||
self.params.code = query_dict.get('code', '')
|
self.params.code = self.request.POST.get('code', '')
|
||||||
self.params.state = query_dict.get('state', '')
|
self.params.state = self.request.POST.get('state', '')
|
||||||
|
|
||||||
|
def _extract_client_auth(self):
|
||||||
|
"""
|
||||||
|
Get client credentials using HTTP Basic Authentication method.
|
||||||
|
Or try getting parameters via POST.
|
||||||
|
See: http://tools.ietf.org/html/rfc6750#section-2.1
|
||||||
|
|
||||||
|
Return a string.
|
||||||
|
"""
|
||||||
|
auth_header = self.request.META.get('HTTP_AUTHORIZATION', '')
|
||||||
|
|
||||||
|
if re.compile('^Basic\s{1}.+$').match(auth_header):
|
||||||
|
b64_user_pass = auth_header.split()[1]
|
||||||
|
try:
|
||||||
|
user_pass = b64decode(b64_user_pass).decode('utf-8').split(':')
|
||||||
|
client_id, client_secret = tuple(user_pass)
|
||||||
|
except:
|
||||||
|
client_id = client_secret = ''
|
||||||
|
else:
|
||||||
|
client_id = self.request.POST.get('client_id', '')
|
||||||
|
client_secret = self.request.POST.get('client_secret', '')
|
||||||
|
|
||||||
|
return (client_id, client_secret)
|
||||||
|
|
||||||
def validate_params(self):
|
def validate_params(self):
|
||||||
if not (self.params.grant_type == 'authorization_code'):
|
if not (self.params.grant_type == 'authorization_code'):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import re
|
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from base64 import b64encode
|
||||||
import json
|
import json
|
||||||
try:
|
try:
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
@ -44,7 +45,7 @@ class TokenTestCase(TestCase):
|
||||||
|
|
||||||
return post_data
|
return post_data
|
||||||
|
|
||||||
def _post_request(self, post_data):
|
def _post_request(self, post_data, extras={}):
|
||||||
"""
|
"""
|
||||||
Makes a request to the token endpoint by sending the
|
Makes a request to the token endpoint by sending the
|
||||||
`post_data` parameters using the 'application/x-www-form-urlencoded'
|
`post_data` parameters using the 'application/x-www-form-urlencoded'
|
||||||
|
@ -54,7 +55,8 @@ class TokenTestCase(TestCase):
|
||||||
|
|
||||||
request = self.factory.post(url,
|
request = self.factory.post(url,
|
||||||
data=urlencode(post_data),
|
data=urlencode(post_data),
|
||||||
content_type='application/x-www-form-urlencoded')
|
content_type='application/x-www-form-urlencoded',
|
||||||
|
**extras)
|
||||||
|
|
||||||
response = TokenView.as_view()(request)
|
response = TokenView.as_view()(request)
|
||||||
|
|
||||||
|
@ -113,12 +115,10 @@ class TokenTestCase(TestCase):
|
||||||
post_data = self._post_data(code=code.code)
|
post_data = self._post_data(code=code.code)
|
||||||
|
|
||||||
response = self._post_request(post_data)
|
response = self._post_request(post_data)
|
||||||
response_dic = json.loads(response.content.decode('utf-8'))
|
|
||||||
|
|
||||||
self.assertEqual('access_token' in response_dic, True,
|
self.assertEqual('invalid_client' in response.content.decode('utf-8'),
|
||||||
msg='"access_token" key is missing in response.')
|
False,
|
||||||
self.assertEqual('error' in response_dic, False,
|
msg='Client authentication fails using request-body credentials.')
|
||||||
msg='"error" key should not exists in response.')
|
|
||||||
|
|
||||||
# Now, test with an invalid client_id.
|
# Now, test with an invalid client_id.
|
||||||
invalid_data = post_data.copy()
|
invalid_data = post_data.copy()
|
||||||
|
@ -129,12 +129,32 @@ class TokenTestCase(TestCase):
|
||||||
invalid_data['code'] = code.code
|
invalid_data['code'] = code.code
|
||||||
|
|
||||||
response = self._post_request(invalid_data)
|
response = self._post_request(invalid_data)
|
||||||
response_dic = json.loads(response.content.decode('utf-8'))
|
|
||||||
|
|
||||||
self.assertEqual('error' in response_dic, True,
|
self.assertEqual('invalid_client' in response.content.decode('utf-8'),
|
||||||
msg='"error" key should exists in response.')
|
True,
|
||||||
self.assertEqual(response_dic.get('error') == 'invalid_client', True,
|
msg='Client authentication success with an invalid "client_id".')
|
||||||
msg='"error" key value should be "invalid_client".')
|
|
||||||
|
# Now, test using HTTP Basic Authentication method.
|
||||||
|
basicauth_data = post_data.copy()
|
||||||
|
|
||||||
|
# Create another grant code.
|
||||||
|
code = self._create_code()
|
||||||
|
basicauth_data['code'] = code.code
|
||||||
|
|
||||||
|
del basicauth_data['client_id']
|
||||||
|
del basicauth_data['client_secret']
|
||||||
|
|
||||||
|
# Generate HTTP Basic Auth header with id and secret.
|
||||||
|
user_pass = self.client.client_id + ':' + self.client.client_secret
|
||||||
|
auth_header = b'Basic ' + b64encode(user_pass.encode('utf-8'))
|
||||||
|
response = self._post_request(basicauth_data, {
|
||||||
|
'HTTP_AUTHORIZATION': auth_header.decode('utf-8'),
|
||||||
|
})
|
||||||
|
response.content.decode('utf-8')
|
||||||
|
|
||||||
|
self.assertEqual('invalid_client' in response.content.decode('utf-8'),
|
||||||
|
False,
|
||||||
|
msg='Client authentication fails using HTTP Basic Auth.')
|
||||||
|
|
||||||
def test_access_token_contains_nonce(self):
|
def test_access_token_contains_nonce(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue