blob: 6f32b239b290c6e2b72aec1441627c80cce362b9 [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
36class Credentials(credentials.Scoped, credentials.Signing,
37 credentials.Credentials):
38 """App Engine standard environment credentials.
39
40 These credentials use the App Engine App Identity API to obtain access
41 tokens.
42 """
43
44 def __init__(self, scopes=None, service_account_id=None):
45 """
46 Args:
47 scopes (Sequence[str]): Scopes to request from the App Identity
48 API.
49 service_account_id (str): The service account ID passed into
50 :func:`google.appengine.api.app_identity.get_access_token`.
51 If not specified, the default application service account
52 ID will be used.
53
54 Raises:
55 EnvironmentError: If the App Engine APIs are unavailable.
56 """
57 if app_identity is None:
58 raise EnvironmentError(
59 'The App Engine APIs are not available.')
60
61 super(Credentials, self).__init__()
62 self._scopes = scopes
63 self._service_account_id = service_account_id
64
65 @_helpers.copy_docstring(credentials.Credentials)
66 def refresh(self, request):
67 # pylint: disable=unused-argument
68 token, ttl = app_identity.get_access_token(
69 self._scopes, self._service_account_id)
70 expiry = _helpers.utcnow() + datetime.timedelta(seconds=ttl)
71
72 self.token, self.expiry = token, expiry
73
74 @property
75 def requires_scopes(self):
76 """Checks if the credentials requires scopes.
77
78 Returns:
79 bool: True if there are no scopes set otherwise False.
80 """
81 return not self._scopes
82
83 @_helpers.copy_docstring(credentials.Scoped)
84 def with_scopes(self, scopes):
85 return Credentials(
86 scopes=scopes, service_account_id=self._service_account_id)
87
88 @_helpers.copy_docstring(credentials.Signing)
89 def sign_bytes(self, message):
90 return app_identity.sign_blob(message)