2016-02-12 16:02:35 +00:00
|
|
|
import random
|
|
|
|
import string
|
2017-11-22 17:40:58 +00:00
|
|
|
|
|
|
|
import django
|
|
|
|
from django.contrib.auth.backends import ModelBackend
|
|
|
|
|
2015-07-10 10:22:25 +00:00
|
|
|
try:
|
|
|
|
from urlparse import parse_qs, urlsplit
|
|
|
|
except ImportError:
|
|
|
|
from urllib.parse import parse_qs, urlsplit
|
2016-01-25 20:52:24 +00:00
|
|
|
|
2016-10-12 19:23:57 +00:00
|
|
|
from django.utils import timezone
|
2016-01-25 20:52:24 +00:00
|
|
|
from django.contrib.auth.models import User
|
|
|
|
|
2016-08-11 22:05:13 +00:00
|
|
|
from oidc_provider.models import (
|
|
|
|
Client,
|
|
|
|
Code,
|
2018-08-15 20:43:48 +00:00
|
|
|
Token,
|
|
|
|
ResponseType)
|
2015-02-11 18:37:51 +00:00
|
|
|
|
|
|
|
|
2016-02-12 16:02:35 +00:00
|
|
|
FAKE_NONCE = 'cb584e44c43ed6bd0bc2d9c7e242837d'
|
2018-03-23 18:46:12 +00:00
|
|
|
FAKE_RANDOM_STRING = ''.join(
|
|
|
|
random.choice(string.ascii_uppercase + string.digits) for _ in range(32))
|
2016-04-07 19:18:47 +00:00
|
|
|
FAKE_CODE_CHALLENGE = 'YlYXEqXuRm-Xgi2BOUiK50JW1KsGTX6F1TDnZSC8VTg'
|
|
|
|
FAKE_CODE_VERIFIER = 'SmxGa0XueyNh5bDgTcSrqzAh2_FmXEqU8kDT6CuXicw'
|
2015-07-16 18:04:33 +00:00
|
|
|
|
2015-08-11 18:59:57 +00:00
|
|
|
|
2015-02-11 18:37:51 +00:00
|
|
|
def create_fake_user():
|
2015-06-23 19:32:12 +00:00
|
|
|
"""
|
|
|
|
Create a test user.
|
2015-02-11 18:37:51 +00:00
|
|
|
|
2015-06-23 19:32:12 +00:00
|
|
|
Return a User object.
|
|
|
|
"""
|
|
|
|
user = User()
|
|
|
|
user.username = 'johndoe'
|
|
|
|
user.email = 'johndoe@example.com'
|
2017-07-07 18:58:05 +00:00
|
|
|
user.first_name = 'John'
|
|
|
|
user.last_name = 'Doe'
|
2015-06-23 19:32:12 +00:00
|
|
|
user.set_password('1234')
|
2015-02-11 18:37:51 +00:00
|
|
|
|
2015-06-23 19:32:12 +00:00
|
|
|
user.save()
|
2015-02-11 18:37:51 +00:00
|
|
|
|
2015-06-23 19:32:12 +00:00
|
|
|
return user
|
2015-02-11 18:37:51 +00:00
|
|
|
|
2015-08-11 18:59:57 +00:00
|
|
|
|
2017-03-31 16:34:03 +00:00
|
|
|
def create_fake_client(response_type, is_public=False, require_consent=True):
|
2015-06-23 19:32:12 +00:00
|
|
|
"""
|
|
|
|
Create a test client, response_type argument MUST be:
|
|
|
|
'code', 'id_token' or 'id_token token'.
|
|
|
|
|
|
|
|
Return a Client object.
|
|
|
|
"""
|
|
|
|
client = Client()
|
|
|
|
client.name = 'Some Client'
|
2016-04-14 19:22:38 +00:00
|
|
|
client.client_id = str(random.randint(1, 999999)).zfill(6)
|
2016-04-08 21:09:24 +00:00
|
|
|
if is_public:
|
|
|
|
client.client_type = 'public'
|
|
|
|
client.client_secret = ''
|
|
|
|
else:
|
2016-04-14 19:22:38 +00:00
|
|
|
client.client_secret = str(random.randint(1, 999999)).zfill(6)
|
2015-06-23 19:32:12 +00:00
|
|
|
client.redirect_uris = ['http://example.com/']
|
2017-03-31 16:34:03 +00:00
|
|
|
client.require_consent = require_consent
|
2015-06-23 19:32:12 +00:00
|
|
|
|
|
|
|
client.save()
|
|
|
|
|
2018-08-16 20:46:50 +00:00
|
|
|
# check if response_type is a string in a python 2 and 3 compatible way
|
2018-08-15 20:43:48 +00:00
|
|
|
if isinstance(response_type, ("".__class__, u"".__class__)):
|
|
|
|
response_type = (response_type,)
|
|
|
|
for value in response_type:
|
|
|
|
client.response_types.add(ResponseType.objects.get(value=value))
|
|
|
|
|
2015-06-23 19:32:12 +00:00
|
|
|
return client
|
|
|
|
|
2015-08-11 18:59:57 +00:00
|
|
|
|
2016-10-12 19:23:57 +00:00
|
|
|
def create_fake_token(user, scopes, client):
|
|
|
|
expires_at = timezone.now() + timezone.timedelta(seconds=60)
|
|
|
|
token = Token(user=user, client=client, expires_at=expires_at)
|
|
|
|
token.scope = scopes
|
|
|
|
|
|
|
|
token.save()
|
|
|
|
|
|
|
|
return token
|
|
|
|
|
|
|
|
|
2015-06-23 19:32:12 +00:00
|
|
|
def is_code_valid(url, user, client):
|
|
|
|
"""
|
2016-09-08 20:15:25 +00:00
|
|
|
Check if the code inside the url is valid. Supporting both query string and fragment.
|
2015-06-23 19:32:12 +00:00
|
|
|
"""
|
|
|
|
try:
|
2015-07-10 10:22:25 +00:00
|
|
|
parsed = urlsplit(url)
|
2016-09-08 20:15:25 +00:00
|
|
|
params = parse_qs(parsed.query or parsed.fragment)
|
2015-07-10 10:22:25 +00:00
|
|
|
code = params['code'][0]
|
2015-06-23 19:32:12 +00:00
|
|
|
code = Code.objects.get(code=code)
|
2016-09-08 20:15:25 +00:00
|
|
|
is_code_ok = (code.client == client) and (code.user == user)
|
2018-03-23 18:46:12 +00:00
|
|
|
except Exception:
|
2015-06-23 19:32:12 +00:00
|
|
|
is_code_ok = False
|
|
|
|
|
|
|
|
return is_code_ok
|
2015-08-11 18:59:57 +00:00
|
|
|
|
|
|
|
|
2016-07-07 15:50:27 +00:00
|
|
|
def userinfo(claims, user):
|
2016-01-12 18:17:22 +00:00
|
|
|
"""
|
2016-07-07 15:50:27 +00:00
|
|
|
Fake function for setting OIDC_USERINFO.
|
2016-01-12 18:17:22 +00:00
|
|
|
"""
|
2016-07-07 15:50:27 +00:00
|
|
|
claims['given_name'] = 'John'
|
|
|
|
claims['family_name'] = 'Doe'
|
|
|
|
claims['name'] = '{0} {1}'.format(claims['given_name'], claims['family_name'])
|
|
|
|
claims['email'] = user.email
|
2017-12-14 17:03:15 +00:00
|
|
|
claims['email_verified'] = True
|
2016-07-07 15:50:27 +00:00
|
|
|
claims['address']['country'] = 'Argentina'
|
|
|
|
return claims
|
2016-01-12 18:17:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
def fake_sub_generator(user):
|
|
|
|
"""
|
|
|
|
Fake function for setting OIDC_IDTOKEN_SUB_GENERATOR.
|
|
|
|
"""
|
|
|
|
return user.email
|
2016-02-12 16:02:35 +00:00
|
|
|
|
|
|
|
|
2018-05-23 21:24:52 +00:00
|
|
|
def fake_idtoken_processing_hook(id_token, user, **kwargs):
|
2016-02-12 16:02:35 +00:00
|
|
|
"""
|
2016-02-12 17:51:43 +00:00
|
|
|
Fake function for inserting some keys into token. Testing OIDC_IDTOKEN_PROCESSING_HOOK.
|
2016-02-12 16:02:35 +00:00
|
|
|
"""
|
2016-02-12 17:51:43 +00:00
|
|
|
id_token['test_idtoken_processing_hook'] = FAKE_RANDOM_STRING
|
2016-02-17 22:28:08 +00:00
|
|
|
id_token['test_idtoken_processing_hook_user_email'] = user.email
|
2016-02-12 17:51:43 +00:00
|
|
|
return id_token
|
2016-03-01 17:54:57 +00:00
|
|
|
|
|
|
|
|
2018-05-23 21:24:52 +00:00
|
|
|
def fake_idtoken_processing_hook2(id_token, user, **kwargs):
|
2016-03-01 17:54:57 +00:00
|
|
|
"""
|
2018-03-23 18:46:12 +00:00
|
|
|
Fake function for inserting some keys into token.
|
|
|
|
Testing OIDC_IDTOKEN_PROCESSING_HOOK - tuple or list as param
|
2016-03-01 17:54:57 +00:00
|
|
|
"""
|
|
|
|
id_token['test_idtoken_processing_hook2'] = FAKE_RANDOM_STRING
|
|
|
|
id_token['test_idtoken_processing_hook_user_email2'] = user.email
|
|
|
|
return id_token
|
2017-07-07 19:55:18 +00:00
|
|
|
|
|
|
|
|
2018-05-31 07:23:58 +00:00
|
|
|
def fake_idtoken_processing_hook3(id_token, user, token, **kwargs):
|
2017-07-07 19:55:18 +00:00
|
|
|
"""
|
|
|
|
Fake function for checking scope is passed to processing hook.
|
|
|
|
"""
|
2018-05-31 07:23:58 +00:00
|
|
|
id_token['scope_of_token_passed_to_processing_hook'] = token.scope
|
2017-07-07 19:55:18 +00:00
|
|
|
return id_token
|
2018-05-23 21:16:26 +00:00
|
|
|
|
|
|
|
|
2018-05-23 21:24:52 +00:00
|
|
|
def fake_idtoken_processing_hook4(id_token, user, **kwargs):
|
|
|
|
"""
|
|
|
|
Fake function for checking kwargs passed to processing hook.
|
|
|
|
"""
|
|
|
|
id_token['kwargs_passed_to_processing_hook'] = {
|
|
|
|
key: repr(value)
|
|
|
|
for (key, value) in kwargs.items()
|
|
|
|
}
|
|
|
|
return id_token
|
|
|
|
|
|
|
|
|
2018-04-23 13:59:56 +00:00
|
|
|
def fake_introspection_processing_hook(response_dict, client, id_token):
|
2018-02-05 15:29:08 +00:00
|
|
|
response_dict['test_introspection_processing_hook'] = FAKE_RANDOM_STRING
|
|
|
|
return response_dict
|
2017-11-22 17:40:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TestAuthBackend:
|
|
|
|
def authenticate(self, *args, **kwargs):
|
|
|
|
if django.VERSION[0] >= 2 or (django.VERSION[0] == 1 and django.VERSION[1] >= 11):
|
|
|
|
assert len(args) > 0 and args[0]
|
|
|
|
return ModelBackend().authenticate(*args, **kwargs)
|