Add GAE to application default credentials.
diff --git a/google/auth/_default.py b/google/auth/_default.py
index 3f6993a..74b96b3 100644
--- a/google/auth/_default.py
+++ b/google/auth/_default.py
@@ -23,6 +23,7 @@
import os
from google.auth import _cloud_sdk
+from google.auth import app_engine
from google.auth import compute_engine
from google.auth import environment_vars
from google.auth import exceptions
@@ -150,7 +151,12 @@
def _get_gae_credentials():
"""Gets Google App Engine App Identity credentials and project ID."""
- return None, None
+ try:
+ credentials = app_engine.Credentials()
+ project_id = app_engine.get_project_id()
+ return credentials, project_id
+ except EnvironmentError:
+ return None, None
def _get_gce_credentials(request=None):
diff --git a/google/auth/app_engine.py b/google/auth/app_engine.py
index 6f32b23..d20ddf6 100644
--- a/google/auth/app_engine.py
+++ b/google/auth/app_engine.py
@@ -33,6 +33,21 @@
app_identity = None
+def get_project_id():
+ """Gets the project ID for the current App Engine application.
+
+ Returns:
+ str: The project ID
+
+ Raises:
+ EnvironmentError: If the App Engine APIs are unavailable.
+ """
+ if app_identity is None:
+ raise EnvironmentError(
+ 'The App Engine APIs are not available.')
+ return app_identity.get_application_id()
+
+
class Credentials(credentials.Scoped, credentials.Signing,
credentials.Credentials):
"""App Engine standard environment credentials.
diff --git a/tests/test__default.py b/tests/test__default.py
index 137fdcd..747bfa4 100644
--- a/tests/test__default.py
+++ b/tests/test__default.py
@@ -19,6 +19,7 @@
import pytest
from google.auth import _default
+from google.auth import app_engine
from google.auth import compute_engine
from google.auth import environment_vars
from google.auth import exceptions
@@ -188,7 +189,25 @@
assert project_id is None
-def test__get_gae_credentials():
+@pytest.fixture
+def app_identity_mock(monkeypatch):
+ """Mocks the app_identity module for google.auth.app_engine."""
+ app_identity_mock = mock.Mock()
+ monkeypatch.setattr(
+ app_engine, 'app_identity', app_identity_mock)
+ yield app_identity_mock
+
+
+def test__get_gae_credentials(app_identity_mock):
+ app_identity_mock.get_application_id.return_value = mock.sentinel.project
+
+ credentials, project_id = _default._get_gae_credentials()
+
+ assert isinstance(credentials, app_engine.Credentials)
+ assert project_id == mock.sentinel.project
+
+
+def test__get_gae_credentials_no_apis():
assert _default._get_gae_credentials() == (None, None)
diff --git a/tests/test_app_engine.py b/tests/test_app_engine.py
index a9844b0..e1189ed 100644
--- a/tests/test_app_engine.py
+++ b/tests/test_app_engine.py
@@ -29,6 +29,18 @@
yield app_identity_mock
+def test_get_project_id(app_identity_mock):
+ app_identity_mock.get_application_id.return_value = mock.sentinel.project
+ assert app_engine.get_project_id() == mock.sentinel.project
+
+
+def test_get_project_id_missing_apis():
+ with pytest.raises(EnvironmentError) as excinfo:
+ assert app_engine.get_project_id()
+
+ assert excinfo.match(r'App Engine APIs are not available')
+
+
class TestCredentials(object):
def test_missing_apis(self):
with pytest.raises(EnvironmentError) as excinfo: