def expire(self, request, **kwargs): # pylint: disable=no-self-use """ This endpoint ends an Open ID Connect authenticated user session """ provider_config = retrieve_provider_config(**kwargs)[0] if provider_config: oidc_handler = OpenIDHandler(provider_config) return oidc_handler.end_openid_provider_session() else: return HttpResponseBadRequest()
def test_gets_claim_values(self): """ Test the the get_claim_values function returns the correct claim values """ decoded_token = { 'at_hash': 'mU342-Fsdsk', 'sub': '*****@*****.**', 'amr': ["Basic Authenticator"], 'iss': 'http://test.msft.oidc.com/oauth2/token', 'nonce': '12232', 'lname': 'User', 'given_name': 'Ted' } claim_values = self.oidc_handler.get_claim_values( ['email', 'given_name', 'family_name'], decoded_token) values = { 'email': decoded_token.get('sub'), 'given_name': decoded_token.get('given_name'), 'family_name': decoded_token.get('lname') } self.assertEqual(values, claim_values) # Test retrieves default values if claim is not set config = OPENID_CONNECT_PROVIDERS['msft'] config.pop('claims') oidc_handler = OpenIDHandler(config) decoded_token = { 'at_hash': 'mU342-Fsdsk', 'sub': 'sdadasdasda', 'amr': ["Basic Authenticator"], 'iss': 'http://test.msft.oidc.com/oauth2/token', 'nonce': '12232', 'email': '*****@*****.**', 'family_name': 'User', 'given_name': 'Ted' } claim_values = oidc_handler.get_claim_values( ['email', 'given_name', 'family_name'], decoded_token) values = { 'email': decoded_token.get('email'), 'given_name': decoded_token.get('given_name'), 'family_name': decoded_token.get('family_name') } self.assertEqual(values, claim_values)
def initiate_oidc_flow( # pylint: disable=no-self-use self, request, **kwargs): """ This endpoint initiates the OpenID Connect Flow by generating a request to the OpenID Connect Provider with a cached none for verification of the returned request """ provider_config, openid_provider = retrieve_provider_config(**kwargs) if provider_config: nonce = secrets.randbits(16) cache.set(nonce, openid_provider) return OpenIDHandler(provider_config).make_login_request( nonce=nonce) else: return HttpResponseBadRequest()
def callback(self, request, **kwargs): # pylint: disable=no-self-use """ This endpoint handles all callback requests made by an Open ID Connect Provider. Verifies that the request from the provider is valid and creates or gets a User """ id_token = None user = None provider_config, openid_provider = retrieve_provider_config(**kwargs) id_token = request.POST.get('id_token') data = { 'logo_data_uri': getattr(settings, 'OIDC_LOGO_DATA_URI', 'https://ona.io/img/onadata-logo.png') } if not provider_config: return HttpResponseBadRequest() oidc_handler = OpenIDHandler(provider_config) if not id_token: # Use Authorization code if present to retrieve ID Token if request.query_params.get('code'): id_token = oidc_handler.obtain_id_token_from_code( request.query_params.get('code'), openid_provider=openid_provider) else: return HttpResponseBadRequest() data.update({"id_token": id_token}) username = request.POST.get('username') decoded_token = oidc_handler.verify_and_decode_id_token( id_token, cached_nonce=True, openid_provider=openid_provider) claim_values = oidc_handler.get_claim_values( [EMAIL, FIRST_NAME, LAST_NAME], decoded_token) if username: if get_user({"username__iexact": username}): error_msg = _("The username provided already exists. " "Please choose a different one.") data = {'error_msg': error_msg, 'id_token': id_token} else: email = claim_values.get(EMAIL) if not email: data.update({ 'missing_data': 'email', 'error_resolver': 'Please set an email as an alias on your Open ID' + ' Connect providers({}) User page'.format( openid_provider) }) return Response(data, template_name='missing_oidc_detail.html') first_name = claim_values.get(FIRST_NAME) last_name = claim_values.get(LAST_NAME) user = create_or_get_user(first_name, last_name, email, username) else: user = get_user({'email': claim_values.get(EMAIL)}) if user: # On Successful login delete the cached nonce cache.delete(claim_values.get(NONCE)) return get_redirect_sso_response( redirect_uri=provider_config.get('target_url_after_auth'), email=user.email, domain=provider_config.get('domain_cookie')) elif data.get('id_token'): return Response(data, template_name='oidc_username_entry.html') else: return HttpResponseBadRequest()
def setUp(self): self.oidc_handler = OpenIDHandler(OPENID_CONNECT_PROVIDERS['msft'])
class TestOpenIDConnectTools(TestBase): def setUp(self): self.oidc_handler = OpenIDHandler(OPENID_CONNECT_PROVIDERS['msft']) def test_gets_claim_values(self): """ Test the the get_claim_values function returns the correct claim values """ decoded_token = { 'at_hash': 'mU342-Fsdsk', 'sub': '*****@*****.**', 'amr': ["Basic Authenticator"], 'iss': 'http://test.msft.oidc.com/oauth2/token', 'nonce': '12232', 'lname': 'User', 'given_name': 'Ted' } claim_values = self.oidc_handler.get_claim_values( ['email', 'given_name', 'family_name'], decoded_token) values = { 'email': decoded_token.get('sub'), 'given_name': decoded_token.get('given_name'), 'family_name': decoded_token.get('lname') } self.assertEqual(values, claim_values) # Test retrieves default values if claim is not set config = OPENID_CONNECT_PROVIDERS['msft'] config.pop('claims') oidc_handler = OpenIDHandler(config) decoded_token = { 'at_hash': 'mU342-Fsdsk', 'sub': 'sdadasdasda', 'amr': ["Basic Authenticator"], 'iss': 'http://test.msft.oidc.com/oauth2/token', 'nonce': '12232', 'email': '*****@*****.**', 'family_name': 'User', 'given_name': 'Ted' } claim_values = oidc_handler.get_claim_values( ['email', 'given_name', 'family_name'], decoded_token) values = { 'email': decoded_token.get('email'), 'given_name': decoded_token.get('given_name'), 'family_name': decoded_token.get('family_name') } self.assertEqual(values, claim_values) def test_make_login_request(self): """ Test that the make_login_request function returns a HttpResponseRedirect object pointing to the correct url """ response = self.oidc_handler.make_login_request(nonce=12323) expected_url = ('http://test.msft.oidc.com/authorize?nonce=12323' '&client_id=test&redirect_uri=http://127.0.0.1:8000' '/oidc/msft/callback&scope=openid&' 'response_type=idtoken&response_mode=form-post') self.assertEqual(response.status_code, 302) self.assertEqual(response.url, expected_url)