93420461b4
* 'develop' of github.com:juanifioren/django-oidc-provider: Update changelog.rst include request in password grant authenticate call Update setup.py Update changelog.rst Update changelog.rst Adjust import order and method order in introspection tests Replace resource with client in docs. Update settings docs to add extra introspection setting Update README.md Update README.md Remove the Resource model Skip csrf protection on introspection endpoint Add token introspection endpoint to satisfy https://tools.ietf.org/html/rfc7662 Test docs with tox. Remove Django 1.7 for travis. Drop support for Django 1.7. Move extract_client_auth to oauth2 utils. Remove duplicate link in docs. Bump version v0.6.0. Fix BaseCodeTokenModel and user attr. Update README.md Edit README and contribute doc. Edit changelog. Update changelog.rst Add protected_resource_view test using client_credentials. Fix docs. Improve docs. Client credentials implementation. Move changelog into docs. Update README.md Update CHANGELOG.md Fixed infinite callback loop in check-session iframe Fix PEP8. New migration. Update example project. Fix PEP8. Fix PEP8. PEP8 errors and urls. PEP8 models. Fix contribute docs. Fix tox for checking PEP8 all files. Update README.md Update README.md Simplify test suit. Update CHANGELOG.md Bump version 0.5.3. Update installation.rst Update CHANGELOG.md Fixed wrong Object in Template Update project to support Django 2.0 Now passing along the token to create_id_token function. Made token and token_refresh endpoint return requested claims. Sphinx documentation fixes (#219) Use request.user.is_authenticated as a bool with recent Django (#216) Fixed client id retrieval when aud is a list of str. (#210) Add owner field to Client (#211) Update CHANGELOG removed tab char Add pep8 compliance and checker Bump version Update CHANGELOG.md Preparing v0.5.2 (#201) Fix Django 2.0 deprecation warnings (#185) Fix infinite login loop if "prompt=login" (#198) fixed typos Bump version Fix scope handling of token endpoint (#193) Fixes #192 Use stored user consent for public clients too (#189) Redirect URIs must match exactly. (#191) Bug #187 prompt handling (#188) Don't pin exact versions in install_requires.
152 lines
4.1 KiB
Python
152 lines
4.1 KiB
Python
import random
|
|
import string
|
|
|
|
import django
|
|
from django.contrib.auth.backends import ModelBackend
|
|
|
|
try:
|
|
from urlparse import parse_qs, urlsplit
|
|
except ImportError:
|
|
from urllib.parse import parse_qs, urlsplit
|
|
|
|
from django.utils import timezone
|
|
from django.contrib.auth.models import User
|
|
|
|
from oidc_provider.models import (
|
|
Client,
|
|
Code,
|
|
Token)
|
|
|
|
|
|
FAKE_NONCE = 'cb584e44c43ed6bd0bc2d9c7e242837d'
|
|
FAKE_RANDOM_STRING = ''.join(
|
|
random.choice(string.ascii_uppercase + string.digits) for _ in range(32))
|
|
FAKE_CODE_CHALLENGE = 'YlYXEqXuRm-Xgi2BOUiK50JW1KsGTX6F1TDnZSC8VTg'
|
|
FAKE_CODE_VERIFIER = 'SmxGa0XueyNh5bDgTcSrqzAh2_FmXEqU8kDT6CuXicw'
|
|
|
|
|
|
def create_fake_user():
|
|
"""
|
|
Create a test user.
|
|
|
|
Return a User object.
|
|
"""
|
|
user = User()
|
|
user.username = 'johndoe'
|
|
user.email = 'johndoe@example.com'
|
|
user.first_name = 'John'
|
|
user.last_name = 'Doe'
|
|
user.set_password('1234')
|
|
|
|
user.save()
|
|
|
|
return user
|
|
|
|
|
|
def create_fake_client(response_type, is_public=False, require_consent=True):
|
|
"""
|
|
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'
|
|
client.client_id = str(random.randint(1, 999999)).zfill(6)
|
|
if is_public:
|
|
client.client_type = 'public'
|
|
client.client_secret = ''
|
|
else:
|
|
client.client_secret = str(random.randint(1, 999999)).zfill(6)
|
|
client.response_type = response_type
|
|
client.redirect_uris = ['http://example.com/']
|
|
client.require_consent = require_consent
|
|
|
|
client.save()
|
|
|
|
return client
|
|
|
|
|
|
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
|
|
|
|
|
|
def is_code_valid(url, user, client):
|
|
"""
|
|
Check if the code inside the url is valid. Supporting both query string and fragment.
|
|
"""
|
|
try:
|
|
parsed = urlsplit(url)
|
|
params = parse_qs(parsed.query or parsed.fragment)
|
|
code = params['code'][0]
|
|
code = Code.objects.get(code=code)
|
|
is_code_ok = (code.client == client) and (code.user == user)
|
|
except Exception:
|
|
is_code_ok = False
|
|
|
|
return is_code_ok
|
|
|
|
|
|
def userinfo(claims, user):
|
|
"""
|
|
Fake function for setting OIDC_USERINFO.
|
|
"""
|
|
claims['given_name'] = 'John'
|
|
claims['family_name'] = 'Doe'
|
|
claims['name'] = '{0} {1}'.format(claims['given_name'], claims['family_name'])
|
|
claims['email'] = user.email
|
|
claims['email_verified'] = True
|
|
claims['address']['country'] = 'Argentina'
|
|
return claims
|
|
|
|
|
|
def fake_sub_generator(user):
|
|
"""
|
|
Fake function for setting OIDC_IDTOKEN_SUB_GENERATOR.
|
|
"""
|
|
return user.email
|
|
|
|
|
|
def fake_idtoken_processing_hook(id_token, user, scope=None):
|
|
"""
|
|
Fake function for inserting some keys into token. Testing OIDC_IDTOKEN_PROCESSING_HOOK.
|
|
"""
|
|
id_token['test_idtoken_processing_hook'] = FAKE_RANDOM_STRING
|
|
id_token['test_idtoken_processing_hook_user_email'] = user.email
|
|
return id_token
|
|
|
|
|
|
def fake_idtoken_processing_hook2(id_token, user, scope=None):
|
|
"""
|
|
Fake function for inserting some keys into token.
|
|
Testing OIDC_IDTOKEN_PROCESSING_HOOK - tuple or list as param
|
|
"""
|
|
id_token['test_idtoken_processing_hook2'] = FAKE_RANDOM_STRING
|
|
id_token['test_idtoken_processing_hook_user_email2'] = user.email
|
|
return id_token
|
|
|
|
|
|
def fake_idtoken_processing_hook3(id_token, user, scope=None):
|
|
"""
|
|
Fake function for checking scope is passed to processing hook.
|
|
"""
|
|
id_token['scope_passed_to_processing_hook'] = scope
|
|
return id_token
|
|
|
|
|
|
def fake_introspection_processing_hook(response_dict, client, id_token):
|
|
response_dict['test_introspection_processing_hook'] = FAKE_RANDOM_STRING
|
|
return response_dict
|
|
|
|
|
|
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)
|