Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
 def setUp(self):
     self.oidc_handler = OpenIDHandler(OPENID_CONNECT_PROVIDERS['msft'])
Ejemplo n.º 6
0
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)