blob: 2de63884070c070bbe5fb46a6b367f315291e188 [file] [log] [blame]
C.J. Collier37141e42020-02-13 13:49:49 -08001# Copyright 2016 Google LLC
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -07002#
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
15import datetime
16
Tres Seaverb096a3d2017-10-30 16:12:37 -040017import pytest
18
Jon Wayne Parrotte60c1242017-03-23 16:00:24 -070019from google.auth import _helpers
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070020from google.auth import credentials
21
22
23class CredentialsImpl(credentials.Credentials):
24 def refresh(self, request):
25 self.token = request
26
Bu Sun Kim3dda7b22020-07-09 10:39:39 -070027 def with_quota_project(self, quota_project_id):
28 raise NotImplementedError()
29
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070030
31def test_credentials_constructor():
32 credentials = CredentialsImpl()
33 assert not credentials.token
34 assert not credentials.expiry
35 assert not credentials.expired
36 assert not credentials.valid
37
38
39def test_expired_and_valid():
40 credentials = CredentialsImpl()
Bu Sun Kim9eec0912019-10-21 17:04:21 -070041 credentials.token = "token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070042
43 assert credentials.valid
44 assert not credentials.expired
45
Jon Wayne Parrott7af9f662017-05-08 09:40:56 -070046 # Set the expiration to one second more than now plus the clock skew
47 # accomodation. These credentials should be valid.
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070048 credentials.expiry = (
arithmetic1728738611b2021-09-09 17:09:54 -070049 datetime.datetime.utcnow()
50 + _helpers.REFRESH_THRESHOLD
51 + datetime.timedelta(seconds=1)
Bu Sun Kim9eec0912019-10-21 17:04:21 -070052 )
Jon Wayne Parrotte60c1242017-03-23 16:00:24 -070053
54 assert credentials.valid
55 assert not credentials.expired
56
Jon Wayne Parrott7af9f662017-05-08 09:40:56 -070057 # Set the credentials expiration to now. Because of the clock skew
58 # accomodation, these credentials should report as expired.
59 credentials.expiry = datetime.datetime.utcnow()
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070060
61 assert not credentials.valid
62 assert credentials.expired
63
64
65def test_before_request():
66 credentials = CredentialsImpl()
Bu Sun Kim9eec0912019-10-21 17:04:21 -070067 request = "token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070068 headers = {}
69
70 # First call should call refresh, setting the token.
Bu Sun Kim9eec0912019-10-21 17:04:21 -070071 credentials.before_request(request, "http://example.com", "GET", headers)
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070072 assert credentials.valid
Bu Sun Kim9eec0912019-10-21 17:04:21 -070073 assert credentials.token == "token"
74 assert headers["authorization"] == "Bearer token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070075
Bu Sun Kim9eec0912019-10-21 17:04:21 -070076 request = "token2"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070077 headers = {}
78
79 # Second call shouldn't call refresh.
Bu Sun Kim9eec0912019-10-21 17:04:21 -070080 credentials.before_request(request, "http://example.com", "GET", headers)
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070081 assert credentials.valid
Bu Sun Kim9eec0912019-10-21 17:04:21 -070082 assert credentials.token == "token"
83 assert headers["authorization"] == "Bearer token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070084
85
Tres Seaverb096a3d2017-10-30 16:12:37 -040086def test_anonymous_credentials_ctor():
87 anon = credentials.AnonymousCredentials()
88 assert anon.token is None
89 assert anon.expiry is None
90 assert not anon.expired
91 assert anon.valid
92
93
94def test_anonymous_credentials_refresh():
95 anon = credentials.AnonymousCredentials()
96 request = object()
97 with pytest.raises(ValueError):
98 anon.refresh(request)
99
100
101def test_anonymous_credentials_apply_default():
102 anon = credentials.AnonymousCredentials()
103 headers = {}
104 anon.apply(headers)
105 assert headers == {}
106 with pytest.raises(ValueError):
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700107 anon.apply(headers, token="TOKEN")
Tres Seaverb096a3d2017-10-30 16:12:37 -0400108
109
110def test_anonymous_credentials_before_request():
111 anon = credentials.AnonymousCredentials()
112 request = object()
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700113 method = "GET"
114 url = "https://example.com/api/endpoint"
Tres Seaverb096a3d2017-10-30 16:12:37 -0400115 headers = {}
116 anon.before_request(request, method, url, headers)
117 assert headers == {}
118
119
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700120class ReadOnlyScopedCredentialsImpl(credentials.ReadOnlyScoped, CredentialsImpl):
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700121 @property
122 def requires_scopes(self):
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700123 return super(ReadOnlyScopedCredentialsImpl, self).requires_scopes
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700124
125
Tres Seaver42468322017-09-11 15:36:53 -0400126def test_readonly_scoped_credentials_constructor():
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700127 credentials = ReadOnlyScopedCredentialsImpl()
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700128 assert credentials._scopes is None
129
130
Tres Seaver42468322017-09-11 15:36:53 -0400131def test_readonly_scoped_credentials_scopes():
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700132 credentials = ReadOnlyScopedCredentialsImpl()
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700133 credentials._scopes = ["one", "two"]
134 assert credentials.scopes == ["one", "two"]
135 assert credentials.has_scopes(["one"])
136 assert credentials.has_scopes(["two"])
137 assert credentials.has_scopes(["one", "two"])
138 assert not credentials.has_scopes(["three"])
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700139
140
Tres Seaver42468322017-09-11 15:36:53 -0400141def test_readonly_scoped_credentials_requires_scopes():
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700142 credentials = ReadOnlyScopedCredentialsImpl()
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700143 assert not credentials.requires_scopes
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700144
145
146class RequiresScopedCredentialsImpl(credentials.Scoped, CredentialsImpl):
Bu Sun Kimbf5ce0c2021-02-01 15:17:49 -0700147 def __init__(self, scopes=None, default_scopes=None):
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700148 super(RequiresScopedCredentialsImpl, self).__init__()
149 self._scopes = scopes
Bu Sun Kimbf5ce0c2021-02-01 15:17:49 -0700150 self._default_scopes = default_scopes
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700151
152 @property
153 def requires_scopes(self):
154 return not self.scopes
155
Bu Sun Kimbf5ce0c2021-02-01 15:17:49 -0700156 def with_scopes(self, scopes, default_scopes=None):
157 return RequiresScopedCredentialsImpl(
158 scopes=scopes, default_scopes=default_scopes
159 )
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700160
161
162def test_create_scoped_if_required_scoped():
163 unscoped_credentials = RequiresScopedCredentialsImpl()
164 scoped_credentials = credentials.with_scopes_if_required(
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700165 unscoped_credentials, ["one", "two"]
166 )
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700167
168 assert scoped_credentials is not unscoped_credentials
169 assert not scoped_credentials.requires_scopes
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700170 assert scoped_credentials.has_scopes(["one", "two"])
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700171
172
173def test_create_scoped_if_required_not_scopes():
174 unscoped_credentials = CredentialsImpl()
175 scoped_credentials = credentials.with_scopes_if_required(
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700176 unscoped_credentials, ["one", "two"]
177 )
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700178
179 assert scoped_credentials is unscoped_credentials