commit
af57fd0056
6 changed files with 94 additions and 1 deletions
|
@ -207,7 +207,7 @@ class AuthorizeEndpoint(object):
|
||||||
query_fragment['session_state'] = session_state
|
query_fragment['session_state'] = session_state
|
||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logger.debug('[Authorize] Error when trying to create response uri: %s', error)
|
logger.exception('[Authorize] Error when trying to create response uri: %s', error)
|
||||||
raise AuthorizeError(self.params['redirect_uri'], 'server_error', self.grant_type)
|
raise AuthorizeError(self.params['redirect_uri'], 'server_error', self.grant_type)
|
||||||
|
|
||||||
uri = uri._replace(query=urlencode(query_params, doseq=True), fragment=uri.fragment + urlencode(query_fragment, doseq=True))
|
uri = uri._replace(query=urlencode(query_params, doseq=True), fragment=uri.fragment + urlencode(query_fragment, doseq=True))
|
||||||
|
|
|
@ -84,6 +84,33 @@ def default_after_userlogin_hook(request, user, client):
|
||||||
"""
|
"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def default_post_end_session_hook(request, id_token=None, post_logout_redirect_uri=None, state=None, client=None, next_page=None):
|
||||||
|
"""
|
||||||
|
Default function for setting OIDC_POST_END_SESSION_HOOK.
|
||||||
|
|
||||||
|
:param request: Django request object
|
||||||
|
:type request: django.http.HttpRequest
|
||||||
|
|
||||||
|
:param id_token: token passed by `id_token_hint` url query param - do NOT trust this param or validate token
|
||||||
|
:type id_token: str
|
||||||
|
|
||||||
|
:param post_logout_redirect_uri: redirect url from url query param - do NOT trust this param
|
||||||
|
:type post_logout_redirect_uri: str
|
||||||
|
|
||||||
|
:param state: state param from url query params
|
||||||
|
:type state: str
|
||||||
|
|
||||||
|
:param client: If id_token has `aud` param and associated Client exists, this is an instance of it - do NOT trust this param
|
||||||
|
:type client: oidc_provider.models.Client
|
||||||
|
|
||||||
|
:param next_page: calculated next_page redirection target
|
||||||
|
:type next_page: str
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def default_idtoken_processing_hook(id_token, user):
|
def default_idtoken_processing_hook(id_token, user):
|
||||||
"""
|
"""
|
||||||
Hook to perform some additional actions ti `id_token` dictionary just before serialization.
|
Hook to perform some additional actions ti `id_token` dictionary just before serialization.
|
||||||
|
|
|
@ -30,6 +30,14 @@ class DefaultSettings(object):
|
||||||
"""
|
"""
|
||||||
return 'oidc_provider.lib.utils.common.default_after_userlogin_hook'
|
return 'oidc_provider.lib.utils.common.default_after_userlogin_hook'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_POST_END_SESSION_HOOK(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL. Provide a way to plug into the end session process just before calling
|
||||||
|
Django's logout function, typically to perform some business logic.
|
||||||
|
"""
|
||||||
|
return 'oidc_provider.lib.utils.common.default_post_end_session_hook'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def OIDC_CODE_EXPIRE(self):
|
def OIDC_CODE_EXPIRE(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -7,6 +7,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from urlparse import parse_qs, urlsplit
|
from urlparse import parse_qs, urlsplit
|
||||||
import uuid
|
import uuid
|
||||||
|
from mock import patch
|
||||||
|
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
|
@ -26,6 +27,7 @@ from oidc_provider.tests.app.utils import (
|
||||||
is_code_valid,
|
is_code_valid,
|
||||||
)
|
)
|
||||||
from oidc_provider.views import AuthorizeView
|
from oidc_provider.views import AuthorizeView
|
||||||
|
from oidc_provider.lib.endpoints.authorize import AuthorizeEndpoint
|
||||||
|
|
||||||
|
|
||||||
class AuthorizeEndpointMixin(object):
|
class AuthorizeEndpointMixin(object):
|
||||||
|
@ -498,3 +500,40 @@ class AuthorizationHybridFlowTestCase(TestCase, AuthorizeEndpointMixin):
|
||||||
response = self._auth_request('post', self.data, is_user_authenticated=True)
|
response = self._auth_request('post', self.data, is_user_authenticated=True)
|
||||||
|
|
||||||
self.assertIn('expires_in=36000', response['Location'])
|
self.assertIn('expires_in=36000', response['Location'])
|
||||||
|
|
||||||
|
|
||||||
|
class TestCreateResponseURI(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
url = reverse('oidc_provider:authorize')
|
||||||
|
user = create_fake_user()
|
||||||
|
client = create_fake_client(response_type='code', is_public=True)
|
||||||
|
|
||||||
|
# Base data to create a uri response
|
||||||
|
data = {
|
||||||
|
'client_id': client.client_id,
|
||||||
|
'redirect_uri': client.default_redirect_uri,
|
||||||
|
'response_type': client.response_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
factory = RequestFactory()
|
||||||
|
self.request = factory.post(url, data=data)
|
||||||
|
self.request.user = user
|
||||||
|
|
||||||
|
@patch('oidc_provider.lib.endpoints.authorize.create_code')
|
||||||
|
@patch('oidc_provider.lib.endpoints.authorize.logger.exception')
|
||||||
|
def test_create_response_uri_logs_to_error(self, log_exception, create_code):
|
||||||
|
"""
|
||||||
|
A lot can go wrong when creating a response uri and this is caught with a general Exception error. The
|
||||||
|
information contained within this error should show up in the error log so production servers have something
|
||||||
|
to work with when things don't work as expected.
|
||||||
|
"""
|
||||||
|
exception = Exception("Something went wrong!")
|
||||||
|
create_code.side_effect = exception
|
||||||
|
|
||||||
|
authorization_endpoint = AuthorizeEndpoint(self.request)
|
||||||
|
authorization_endpoint.validate_params()
|
||||||
|
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
authorization_endpoint.create_response_uri()
|
||||||
|
|
||||||
|
log_exception.assert_called_once_with('[Authorize] Error when trying to create response uri: %s', exception)
|
||||||
|
|
|
@ -11,6 +11,7 @@ from oidc_provider.tests.app.utils import (
|
||||||
create_fake_client,
|
create_fake_client,
|
||||||
create_fake_user,
|
create_fake_user,
|
||||||
)
|
)
|
||||||
|
import mock
|
||||||
|
|
||||||
|
|
||||||
class EndSessionTestCase(TestCase):
|
class EndSessionTestCase(TestCase):
|
||||||
|
@ -44,3 +45,10 @@ class EndSessionTestCase(TestCase):
|
||||||
|
|
||||||
response = self.client.get(self.url, query_params)
|
response = self.client.get(self.url, query_params)
|
||||||
self.assertRedirects(response, self.LOGOUT_URL, fetch_redirect_response=False)
|
self.assertRedirects(response, self.LOGOUT_URL, fetch_redirect_response=False)
|
||||||
|
|
||||||
|
@mock.patch(settings.get('OIDC_POST_END_SESSION_HOOK'))
|
||||||
|
def test_call_post_end_session_hook(self, hook_function):
|
||||||
|
self.client.get(self.url)
|
||||||
|
self.assertTrue(hook_function.called, 'OIDC_POST_END_SESSION_HOOK should be called')
|
||||||
|
self.assertTrue(hook_function.call_count == 1, 'OIDC_POST_END_SESSION_HOOK should be called once but was {}'.format(hook_function.call_count))
|
||||||
|
|
||||||
|
|
|
@ -264,8 +264,10 @@ class EndSessionView(View):
|
||||||
id_token_hint = request.GET.get('id_token_hint', '')
|
id_token_hint = request.GET.get('id_token_hint', '')
|
||||||
post_logout_redirect_uri = request.GET.get('post_logout_redirect_uri', '')
|
post_logout_redirect_uri = request.GET.get('post_logout_redirect_uri', '')
|
||||||
state = request.GET.get('state', '')
|
state = request.GET.get('state', '')
|
||||||
|
client = None
|
||||||
|
|
||||||
next_page = settings.get('LOGIN_URL')
|
next_page = settings.get('LOGIN_URL')
|
||||||
|
post_end_session_hook = settings.get('OIDC_POST_END_SESSION_HOOK', import_str=True)
|
||||||
|
|
||||||
if id_token_hint:
|
if id_token_hint:
|
||||||
client_id = client_id_from_id_token(id_token_hint)
|
client_id = client_id_from_id_token(id_token_hint)
|
||||||
|
@ -283,6 +285,15 @@ class EndSessionView(View):
|
||||||
except Client.DoesNotExist:
|
except Client.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
post_end_session_hook(
|
||||||
|
request=request,
|
||||||
|
id_token=id_token_hint,
|
||||||
|
post_logout_redirect_uri=post_logout_redirect_uri,
|
||||||
|
state=state,
|
||||||
|
client=client,
|
||||||
|
next_page=next_page
|
||||||
|
)
|
||||||
|
|
||||||
return logout(request, next_page=next_page)
|
return logout(request, next_page=next_page)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue