blob: 608651d848cf0f5c7da0f78e248566d9744fe316 [file] [log] [blame]
Jon Wayne Parrott04714752016-10-24 10:00:58 -07001# Copyright 2016 Google Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Google App Engine standard environment credentials.
16
17This module provides authentication for application running on App Engine in
18the standard environment using the `App Identity API`_.
19
20
21.. _App Identity API:
22 https://cloud.google.com/appengine/docs/python/appidentity/
23"""
24
25import datetime
26
27from google.auth import _helpers
28from google.auth import credentials
29
30try:
31 from google.appengine.api import app_identity
32except ImportError:
33 app_identity = None
34
35
Jon Wayne Parrott2148fde2016-10-24 13:44:25 -070036def get_project_id():
37 """Gets the project ID for the current App Engine application.
38
39 Returns:
40 str: The project ID
41
42 Raises:
43 EnvironmentError: If the App Engine APIs are unavailable.
44 """
45 if app_identity is None:
46 raise EnvironmentError(
47 'The App Engine APIs are not available.')
48 return app_identity.get_application_id()
49
50
Jon Wayne Parrott04714752016-10-24 10:00:58 -070051class Credentials(credentials.Scoped, credentials.Signing,
52 credentials.Credentials):
53 """App Engine standard environment credentials.
54
55 These credentials use the App Engine App Identity API to obtain access
56 tokens.
57 """
58
59 def __init__(self, scopes=None, service_account_id=None):
60 """
61 Args:
62 scopes (Sequence[str]): Scopes to request from the App Identity
63 API.
64 service_account_id (str): The service account ID passed into
65 :func:`google.appengine.api.app_identity.get_access_token`.
66 If not specified, the default application service account
67 ID will be used.
68
69 Raises:
70 EnvironmentError: If the App Engine APIs are unavailable.
71 """
72 if app_identity is None:
73 raise EnvironmentError(
74 'The App Engine APIs are not available.')
75
76 super(Credentials, self).__init__()
77 self._scopes = scopes
78 self._service_account_id = service_account_id
79
80 @_helpers.copy_docstring(credentials.Credentials)
81 def refresh(self, request):
82 # pylint: disable=unused-argument
83 token, ttl = app_identity.get_access_token(
84 self._scopes, self._service_account_id)
85 expiry = _helpers.utcnow() + datetime.timedelta(seconds=ttl)
86
87 self.token, self.expiry = token, expiry
88
89 @property
Jon Wayne Parrott61ffb052016-11-08 09:30:30 -080090 def service_account_email(self):
91 """The service account email."""
92 if self._service_account_id is None:
93 self._service_account_id = app_identity.get_service_account_name()
94 return self._service_account_id
95
96 @property
Jon Wayne Parrott04714752016-10-24 10:00:58 -070097 def requires_scopes(self):
98 """Checks if the credentials requires scopes.
99
100 Returns:
101 bool: True if there are no scopes set otherwise False.
102 """
103 return not self._scopes
104
105 @_helpers.copy_docstring(credentials.Scoped)
106 def with_scopes(self, scopes):
107 return Credentials(
108 scopes=scopes, service_account_id=self._service_account_id)
109
110 @_helpers.copy_docstring(credentials.Signing)
111 def sign_bytes(self, message):
112 return app_identity.sign_blob(message)
Jon Wayne Parrott4c883f02016-12-02 14:26:33 -0800113
114 @property
115 @_helpers.copy_docstring(credentials.Signing)
116 def signer_email(self):
117 return self.service_account_email