def check_login_required(request, authorize): """ Raises AuthorizeError or JustRedirect if login is required for this auth. """ if 'login' in authorize.params['prompt'] or request.user.is_anonymous: if 'none' in authorize.params['prompt']: raise AuthorizeError(authorize.params['redirect_uri'], 'login_required', authorize.grant_type) else: django_user_logout(request) full_path = strip_prompt_login(request.get_full_path()) raise JustRedirect( redirect_to_login(full_path, settings.get('OIDC_LOGIN_URL')))
def get(self, request, *args, **kwargs): authorize = self.authorize_endpoint_class(request) try: authorize.validate_params() if get_attr_or_callable(request.user, 'is_authenticated'): # Check if there's a hook setted. hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK', import_str=True)( request=request, user=request.user, client=authorize.client) if hook_resp: return hook_resp if 'login' in authorize.params['prompt']: if 'none' in authorize.params['prompt']: raise AuthorizeError(authorize.params['redirect_uri'], 'login_required', authorize.grant_type) else: django_user_logout(request) next_page = strip_prompt_login(request.get_full_path()) return redirect_to_login( next_page, settings.get('OIDC_LOGIN_URL')) if 'select_account' in authorize.params['prompt']: # TODO: see how we can support multiple accounts for the end-user. if 'none' in authorize.params['prompt']: raise AuthorizeError(authorize.params['redirect_uri'], 'account_selection_required', authorize.grant_type) else: django_user_logout(request) return redirect_to_login( request.get_full_path(), settings.get('OIDC_LOGIN_URL')) if {'none', 'consent'}.issubset(authorize.params['prompt']): raise AuthorizeError(authorize.params['redirect_uri'], 'consent_required', authorize.grant_type) if not authorize.client.require_consent and ( 'consent' not in authorize.params['prompt']): return redirect(authorize.create_response_uri()) if authorize.client.reuse_consent: # Check if user previously give consent. if authorize.client_has_user_consent() and ( 'consent' not in authorize.params['prompt']): return redirect(authorize.create_response_uri()) if 'none' in authorize.params['prompt']: raise AuthorizeError(authorize.params['redirect_uri'], 'consent_required', authorize.grant_type) # Generate hidden inputs for the form. context = { 'params': authorize.params, } hidden_inputs = render_to_string( 'oidc_provider/hidden_inputs.html', context) # Remove `openid` from scope list # since we don't need to print it. if 'openid' in authorize.params['scope']: authorize.params['scope'].remove('openid') context = { 'client': authorize.client, 'hidden_inputs': hidden_inputs, 'params': authorize.params, 'scopes': authorize.get_scopes_information(), } return render(request, OIDC_TEMPLATES['authorize'], context) else: if 'none' in authorize.params['prompt']: raise AuthorizeError(authorize.params['redirect_uri'], 'login_required', authorize.grant_type) if 'login' in authorize.params['prompt']: next_page = strip_prompt_login(request.get_full_path()) return redirect_to_login(next_page, settings.get('OIDC_LOGIN_URL')) return redirect_to_login(request.get_full_path(), settings.get('OIDC_LOGIN_URL')) except (ClientIdError, RedirectUriError) as error: context = { 'error': error.error, 'description': error.description, } return render(request, OIDC_TEMPLATES['error'], context) except AuthorizeError as error: uri = error.create_uri(authorize.params['redirect_uri'], authorize.params['state']) return redirect(uri)
def test_strip_prompt_login(self): """ Test for helper method test_strip_prompt_login. """ # Original paths path0 = 'http://idp.com/?prompt=login' path1 = 'http://idp.com/?prompt=consent login none' path2 = ('http://idp.com/?response_type=code&client' + '_id=112233&prompt=consent login') path3 = ('http://idp.com/?response_type=code&client' + '_id=112233&prompt=login none&redirect_uri' + '=http://localhost:8000') self.assertNotIn('prompt', strip_prompt_login(path0)) self.assertIn('prompt', strip_prompt_login(path1)) self.assertIn('consent', strip_prompt_login(path1)) self.assertIn('none', strip_prompt_login(path1)) self.assertNotIn('login', strip_prompt_login(path1)) self.assertIn('prompt', strip_prompt_login(path2)) self.assertIn('consent', strip_prompt_login(path1)) self.assertNotIn('login', strip_prompt_login(path2)) self.assertIn('prompt', strip_prompt_login(path3)) self.assertIn('none', strip_prompt_login(path3)) self.assertNotIn('login', strip_prompt_login(path3))
def get(self, request, *args, **kwargs): authorize = self.authorize_endpoint_class(request) try: authorize.validate_params() if get_attr_or_callable(request.user, 'is_authenticated'): # Check if there's a hook setted. hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK', import_str=True)( request=request, user=request.user, client=authorize.client) if hook_resp: return hook_resp if 'login' in authorize.params['prompt']: if 'none' in authorize.params['prompt']: raise AuthorizeError( authorize.params['redirect_uri'], 'login_required', authorize.grant_type) else: django_user_logout(request) next_page = strip_prompt_login(request.get_full_path()) return redirect_to_login(next_page, settings.get('OIDC_LOGIN_URL')) if 'select_account' in authorize.params['prompt']: # TODO: see how we can support multiple accounts for the end-user. if 'none' in authorize.params['prompt']: raise AuthorizeError( authorize.params['redirect_uri'], 'account_selection_required', authorize.grant_type) else: django_user_logout(request) return redirect_to_login( request.get_full_path(), settings.get('OIDC_LOGIN_URL')) if {'none', 'consent'}.issubset(authorize.params['prompt']): raise AuthorizeError( authorize.params['redirect_uri'], 'consent_required', authorize.grant_type) implicit_flow_resp_types = {'id_token', 'id_token token'} allow_skipping_consent = ( authorize.client.client_type != 'public' or authorize.params['response_type'] in implicit_flow_resp_types) if not authorize.client.require_consent and ( allow_skipping_consent and 'consent' not in authorize.params['prompt']): return redirect(authorize.create_response_uri()) if authorize.client.reuse_consent: # Check if user previously give consent. if authorize.client_has_user_consent() and ( allow_skipping_consent and 'consent' not in authorize.params['prompt']): return redirect(authorize.create_response_uri()) if 'none' in authorize.params['prompt']: raise AuthorizeError( authorize.params['redirect_uri'], 'consent_required', authorize.grant_type) # Generate hidden inputs for the form. context = { 'params': authorize.params, } hidden_inputs = render_to_string('oidc_provider/hidden_inputs.html', context) # Remove `openid` from scope list # since we don't need to print it. if 'openid' in authorize.params['scope']: authorize.params['scope'].remove('openid') context = { 'client': authorize.client, 'hidden_inputs': hidden_inputs, 'params': authorize.params, 'scopes': authorize.get_scopes_information(), } return render(request, OIDC_TEMPLATES['authorize'], context) else: if 'none' in authorize.params['prompt']: raise AuthorizeError( authorize.params['redirect_uri'], 'login_required', authorize.grant_type) if 'login' in authorize.params['prompt']: next_page = strip_prompt_login(request.get_full_path()) return redirect_to_login(next_page, settings.get('OIDC_LOGIN_URL')) return redirect_to_login(request.get_full_path(), settings.get('OIDC_LOGIN_URL')) except (ClientIdError, RedirectUriError) as error: context = { 'error': error.error, 'description': error.description, } return render(request, OIDC_TEMPLATES['error'], context) except AuthorizeError as error: uri = error.create_uri( authorize.params['redirect_uri'], authorize.params['state']) return redirect(uri)
def test_strip_prompt_login(self): """ Test for helper method test_strip_prompt_login. """ # Original paths path0 = 'http://idp.com/?prompt=login' path1 = 'http://idp.com/?prompt=consent login none' path2 = ('http://idp.com/?response_type=code&client' + '_id=112233&prompt=consent login') path3 = ('http://idp.com/?response_type=code&client' + '_id=112233&prompt=login none&redirect_uri' + '=http://localhost:8000') self.assertNotIn('prompt', strip_prompt_login(path0)) self.assertIn('prompt', strip_prompt_login(path1)) self.assertIn('consent', strip_prompt_login(path1)) self.assertIn('none', strip_prompt_login(path1)) self.assertNotIn('login', strip_prompt_login(path1)) self.assertIn('prompt', strip_prompt_login(path2)) self.assertIn('consent', strip_prompt_login(path1)) self.assertNotIn('login', strip_prompt_login(path2)) self.assertIn('prompt', strip_prompt_login(path3)) self.assertIn('none', strip_prompt_login(path3)) self.assertNotIn('login', strip_prompt_login(path3))