Esempio n. 1
0
 def test_get_id_token_from_metadata_constructor(self):
     with pytest.raises(ValueError):
         credentials.IDTokenCredentials(
             mock.Mock(),
             "audience",
             use_metadata_identity_endpoint=True,
             token_uri="token_uri",
         )
     with pytest.raises(ValueError):
         credentials.IDTokenCredentials(
             mock.Mock(),
             "audience",
             use_metadata_identity_endpoint=True,
             signer=mock.Mock(),
         )
     with pytest.raises(ValueError):
         credentials.IDTokenCredentials(
             mock.Mock(),
             "audience",
             use_metadata_identity_endpoint=True,
             additional_claims={"key", "value"},
         )
     with pytest.raises(ValueError):
         credentials.IDTokenCredentials(
             mock.Mock(),
             "audience",
             use_metadata_identity_endpoint=True,
             service_account_email="*****@*****.**",
         )
Esempio n. 2
0
    def test_before_request_refreshes(self, id_token_jwt_grant, sign, get,
                                      utcnow):
        get.side_effect = [{
            "email": "*****@*****.**",
            "scopes": "one two"
        }]
        sign.side_effect = [b"signature"]
        id_token_jwt_grant.side_effect = [
            ("idtoken", datetime.datetime.utcfromtimestamp(3600), {})
        ]

        request = mock.create_autospec(transport.Request, instance=True)
        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://audience.com")

        # Credentials should start as invalid
        assert not self.credentials.valid

        # before_request should cause a refresh
        request = mock.create_autospec(transport.Request, instance=True)
        self.credentials.before_request(request, "GET",
                                        "http://example.com?a=1#3", {})

        # The refresh endpoint should've been called.
        assert get.called

        # Credentials should now be valid.
        assert self.credentials.valid
Esempio n. 3
0
    def test_refresh_success(self, id_token_jwt_grant, sign, get, utcnow):
        get.side_effect = [{
            "email": "*****@*****.**",
            "scopes": ["one", "two"]
        }]
        sign.side_effect = [b"signature"]
        id_token_jwt_grant.side_effect = [
            ("idtoken", datetime.datetime.utcfromtimestamp(3600), {})
        ]

        request = mock.create_autospec(transport.Request, instance=True)
        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://audience.com")

        # Refresh credentials
        self.credentials.refresh(None)

        # Check that the credentials have the token and proper expiration
        assert self.credentials.token == "idtoken"
        assert self.credentials.expiry == (
            datetime.datetime.utcfromtimestamp(3600))

        # Check the credential info
        assert self.credentials.service_account_email == "*****@*****.**"

        # Check that the credentials are valid (have a token and are not
        # expired)
        assert self.credentials.valid
Esempio n. 4
0
    def test_with_target_audience(self, sign, get, utcnow):
        get.side_effect = [{
            "email": "*****@*****.**",
            "scopes": ["one", "two"]
        }]
        sign.side_effect = [b"signature"]

        request = mock.create_autospec(transport.Request, instance=True)
        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://audience.com")
        self.credentials = self.credentials.with_target_audience(
            "https://actually.not")

        # Generate authorization grant:
        token = self.credentials._make_authorization_grant_assertion()
        payload = jwt.decode(token, verify=False)

        # The JWT token signature is 'signature' encoded in base 64:
        assert token.endswith(b".c2lnbmF0dXJl")

        # Check that the credentials have the token and proper expiration
        assert payload == {
            "aud": "https://www.googleapis.com/oauth2/v4/token",
            "exp": 3600,
            "iat": 0,
            "iss": "*****@*****.**",
            "target_audience": "https://actually.not",
        }
Esempio n. 5
0
    def test_with_target_audience(self, sign, get, utcnow):
        get.side_effect = [{
            'email': '*****@*****.**',
            'scopes': ['one', 'two']
        }]
        sign.side_effect = [b'signature']

        request = mock.create_autospec(transport.Request, instance=True)
        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://audience.com")
        self.credentials = (
            self.credentials.with_target_audience("https://actually.not"))

        # Generate authorization grant:
        token = self.credentials._make_authorization_grant_assertion()
        payload = jwt.decode(token, verify=False)

        # The JWT token signature is 'signature' encoded in base 64:
        assert token.endswith(b'.c2lnbmF0dXJl')

        # Check that the credentials have the token and proper expiration
        assert payload == {
            'aud': 'https://www.googleapis.com/oauth2/v4/token',
            'exp': 3600,
            'iat': 0,
            'iss': '*****@*****.**',
            'target_audience': 'https://actually.not'}
Esempio n. 6
0
    def test_invalid_id_token_from_metadata(self, get,
                                            get_service_account_info):
        get.return_value = "invalid_id_token"
        get_service_account_info.return_value = {"email": "*****@*****.**"}

        cred = credentials.IDTokenCredentials(
            mock.Mock(), "audience", use_metadata_identity_endpoint=True)

        with pytest.raises(ValueError):
            cred.refresh(request=mock.Mock())
Esempio n. 7
0
    def test_token_uri(self):
        request = mock.create_autospec(transport.Request, instance=True)

        self.credentials = credentials.IDTokenCredentials(
            request=request,
            signer=mock.Mock(),
            service_account_email="*****@*****.**",
            target_audience="https://audience.com",
        )
        assert self.credentials._token_uri == credentials._DEFAULT_TOKEN_URI

        self.credentials = credentials.IDTokenCredentials(
            request=request,
            signer=mock.Mock(),
            service_account_email="*****@*****.**",
            target_audience="https://audience.com",
            token_uri="https://example.com/token",
        )
        assert self.credentials._token_uri == "https://example.com/token"
Esempio n. 8
0
    def test_transport_error_from_metadata(self, get,
                                           get_service_account_info):
        get.side_effect = exceptions.TransportError("transport error")
        get_service_account_info.return_value = {"email": "*****@*****.**"}

        cred = credentials.IDTokenCredentials(
            mock.Mock(), "audience", use_metadata_identity_endpoint=True)

        with pytest.raises(exceptions.RefreshError) as excinfo:
            cred.refresh(request=mock.Mock())
        assert excinfo.match(r"transport error")
Esempio n. 9
0
    def test_id_token_with_quota_project(self, get_service_account_info):
        get_service_account_info.return_value = {"email": "*****@*****.**"}

        cred = credentials.IDTokenCredentials(
            mock.Mock(), "audience", use_metadata_identity_endpoint=True)
        cred = cred.with_quota_project("project-foo")

        assert cred._quota_project_id == "project-foo"
        assert cred._use_metadata_identity_endpoint
        assert cred._signer is None
        assert cred._token_uri is None
        assert cred._service_account_email == "*****@*****.**"
Esempio n. 10
0
    def test_with_target_audience_for_metadata(self, get_service_account_info):
        get_service_account_info.return_value = {"email": "*****@*****.**"}

        cred = credentials.IDTokenCredentials(
            mock.Mock(), "audience", use_metadata_identity_endpoint=True)
        cred = cred.with_target_audience("new_audience")

        assert cred._target_audience == "new_audience"
        assert cred._use_metadata_identity_endpoint
        assert cred._signer is None
        assert cred._token_uri is None
        assert cred._service_account_email == "*****@*****.**"
Esempio n. 11
0
    def test_default_state(self, get):
        get.side_effect = [{
            "email": "*****@*****.**",
            "scope": ["one", "two"]
        }]

        request = mock.create_autospec(transport.Request, instance=True)
        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://example.com")

        assert not self.credentials.valid
        # Expiration hasn't been set yet
        assert not self.credentials.expired
        # Service account email hasn't been populated
        assert self.credentials.service_account_email == "*****@*****.**"
        # Signer is initialized
        assert self.credentials.signer
        assert self.credentials.signer_email == "*****@*****.**"
Esempio n. 12
0
    def test_get_id_token_from_metadata(self, get, get_service_account_info):
        get.return_value = SAMPLE_ID_TOKEN
        get_service_account_info.return_value = {"email": "*****@*****.**"}

        cred = credentials.IDTokenCredentials(
            mock.Mock(), "audience", use_metadata_identity_endpoint=True)
        cred.refresh(request=mock.Mock())

        assert cred.token == SAMPLE_ID_TOKEN
        assert cred.expiry == datetime.datetime.fromtimestamp(
            SAMPLE_ID_TOKEN_EXP)
        assert cred._use_metadata_identity_endpoint
        assert cred._signer is None
        assert cred._token_uri is None
        assert cred._service_account_email == "*****@*****.**"
        assert cred._target_audience == "audience"
        with pytest.raises(ValueError):
            cred.sign_bytes(b"bytes")
Esempio n. 13
0
    def test_refresh_error(self, sign, get, utcnow):
        get.side_effect = [{
            "email": "*****@*****.**",
            "scopes": ["one", "two"]
        }]
        sign.side_effect = [b"signature"]

        request = mock.create_autospec(transport.Request, instance=True)
        response = mock.Mock()
        response.data = b'{"error": "http error"}'
        response.status = 500
        request.side_effect = [response]

        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://audience.com")

        with pytest.raises(exceptions.RefreshError) as excinfo:
            self.credentials.refresh(request)

        assert excinfo.match(r"http error")
Esempio n. 14
0
    def test_sign_bytes(self, sign, get):
        get.side_effect = [{
            "email": "*****@*****.**",
            "scopes": ["one", "two"]
        }]
        sign.side_effect = [b"signature"]

        request = mock.create_autospec(transport.Request, instance=True)
        response = mock.Mock()
        response.data = b'{"signature": "c2lnbmF0dXJl"}'
        response.status = 200
        request.side_effect = [response]

        self.credentials = credentials.IDTokenCredentials(
            request=request, target_audience="https://audience.com")

        # Generate authorization grant:
        signature = self.credentials.sign_bytes(b"some bytes")

        # The JWT token signature is 'signature' encoded in base 64:
        assert signature == b"signature"
Esempio n. 15
0
def new_creds(scopes=None):
    """Create credentials wih non-default scopes.

    The IAP API must be enabled, and the service account must have been
    granted permissions to create auth tokens (included in the Service Account
    Token Creator role).
    """
    if not in_production():
        # Local development.
        creds, _ = google.auth.default(scopes=scopes)
        return creds

    request = google.auth.transport.requests.Request()
    creds = credentials.IDTokenCredentials(request, None)
    signer = creds.signer
    service_account_email = creds.service_account_email
    token_uri = _DEFAULT_TOKEN_URI
    creds = service_account.Credentials(signer, service_account_email, token_uri)

    if scopes:
        creds = creds.with_scopes(scopes)

    return creds
Esempio n. 16
0
    def test_with_target_audience_integration(self):
        """ Test that it is possible to refresh credentials
        generated from `with_target_audience`.

        Instead of mocking the methods, the HTTP responses
        have been mocked.
        """

        # mock information about credentials
        responses.add(
            responses.GET,
            "http://metadata.google.internal/computeMetadata/v1/instance/"
            "service-accounts/default/?recursive=true",
            status=200,
            content_type="application/json",
            json={
                "scopes": "email",
                "email": "*****@*****.**",
                "aliases": ["default"],
            },
        )

        # mock token for credentials
        responses.add(
            responses.GET,
            "http://metadata.google.internal/computeMetadata/v1/instance/"
            "service-accounts/[email protected]/token",
            status=200,
            content_type="application/json",
            json={
                "access_token": "some-token",
                "expires_in": 3210,
                "token_type": "Bearer",
            },
        )

        # mock sign blob endpoint
        signature = base64.b64encode(b"some-signature").decode("utf-8")
        responses.add(
            responses.POST,
            "https://iam.googleapis.com/v1/projects/-/serviceAccounts/"
            "[email protected]:signBlob?alt=json",
            status=200,
            content_type="application/json",
            json={
                "keyId": "some-key-id",
                "signature": signature
            },
        )

        id_token = "{}.{}.{}".format(
            base64.b64encode(b'{"some":"some"}').decode("utf-8"),
            base64.b64encode(b'{"exp": 3210}').decode("utf-8"),
            base64.b64encode(b"token").decode("utf-8"),
        )

        # mock id token endpoint
        responses.add(
            responses.POST,
            "https://www.googleapis.com/oauth2/v4/token",
            status=200,
            content_type="application/json",
            json={
                "id_token": id_token,
                "expiry": 3210
            },
        )

        self.credentials = credentials.IDTokenCredentials(
            request=requests.Request(),
            service_account_email="*****@*****.**",
            target_audience="https://audience.com",
        )

        self.credentials = self.credentials.with_target_audience(
            "https://actually.not")

        self.credentials.refresh(requests.Request())

        assert self.credentials.token is not None