blob: 2a89b01b6b66fdcc3292644fb94a25d195020209 [file] [log] [blame]
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -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
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
27
28def test_credentials_constructor():
29 credentials = CredentialsImpl()
30 assert not credentials.token
31 assert not credentials.expiry
32 assert not credentials.expired
33 assert not credentials.valid
34
35
36def test_expired_and_valid():
37 credentials = CredentialsImpl()
Bu Sun Kim9eec0912019-10-21 17:04:21 -070038 credentials.token = "token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070039
40 assert credentials.valid
41 assert not credentials.expired
42
Jon Wayne Parrott7af9f662017-05-08 09:40:56 -070043 # Set the expiration to one second more than now plus the clock skew
44 # accomodation. These credentials should be valid.
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070045 credentials.expiry = (
Bu Sun Kim9eec0912019-10-21 17:04:21 -070046 datetime.datetime.utcnow() + _helpers.CLOCK_SKEW + datetime.timedelta(seconds=1)
47 )
Jon Wayne Parrotte60c1242017-03-23 16:00:24 -070048
49 assert credentials.valid
50 assert not credentials.expired
51
Jon Wayne Parrott7af9f662017-05-08 09:40:56 -070052 # Set the credentials expiration to now. Because of the clock skew
53 # accomodation, these credentials should report as expired.
54 credentials.expiry = datetime.datetime.utcnow()
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070055
56 assert not credentials.valid
57 assert credentials.expired
58
59
60def test_before_request():
61 credentials = CredentialsImpl()
Bu Sun Kim9eec0912019-10-21 17:04:21 -070062 request = "token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070063 headers = {}
64
65 # First call should call refresh, setting the token.
Bu Sun Kim9eec0912019-10-21 17:04:21 -070066 credentials.before_request(request, "http://example.com", "GET", headers)
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070067 assert credentials.valid
Bu Sun Kim9eec0912019-10-21 17:04:21 -070068 assert credentials.token == "token"
69 assert headers["authorization"] == "Bearer token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070070
Bu Sun Kim9eec0912019-10-21 17:04:21 -070071 request = "token2"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070072 headers = {}
73
74 # Second call shouldn't call refresh.
Bu Sun Kim9eec0912019-10-21 17:04:21 -070075 credentials.before_request(request, "http://example.com", "GET", headers)
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070076 assert credentials.valid
Bu Sun Kim9eec0912019-10-21 17:04:21 -070077 assert credentials.token == "token"
78 assert headers["authorization"] == "Bearer token"
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -070079
80
Tres Seaverb096a3d2017-10-30 16:12:37 -040081def test_anonymous_credentials_ctor():
82 anon = credentials.AnonymousCredentials()
83 assert anon.token is None
84 assert anon.expiry is None
85 assert not anon.expired
86 assert anon.valid
87
88
89def test_anonymous_credentials_refresh():
90 anon = credentials.AnonymousCredentials()
91 request = object()
92 with pytest.raises(ValueError):
93 anon.refresh(request)
94
95
96def test_anonymous_credentials_apply_default():
97 anon = credentials.AnonymousCredentials()
98 headers = {}
99 anon.apply(headers)
100 assert headers == {}
101 with pytest.raises(ValueError):
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700102 anon.apply(headers, token="TOKEN")
Tres Seaverb096a3d2017-10-30 16:12:37 -0400103
104
105def test_anonymous_credentials_before_request():
106 anon = credentials.AnonymousCredentials()
107 request = object()
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700108 method = "GET"
109 url = "https://example.com/api/endpoint"
Tres Seaverb096a3d2017-10-30 16:12:37 -0400110 headers = {}
111 anon.before_request(request, method, url, headers)
112 assert headers == {}
113
114
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700115class ReadOnlyScopedCredentialsImpl(credentials.ReadOnlyScoped, CredentialsImpl):
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700116 @property
117 def requires_scopes(self):
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700118 return super(ReadOnlyScopedCredentialsImpl, self).requires_scopes
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700119
120
Tres Seaver42468322017-09-11 15:36:53 -0400121def test_readonly_scoped_credentials_constructor():
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700122 credentials = ReadOnlyScopedCredentialsImpl()
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700123 assert credentials._scopes is None
124
125
Tres Seaver42468322017-09-11 15:36:53 -0400126def test_readonly_scoped_credentials_scopes():
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700127 credentials = ReadOnlyScopedCredentialsImpl()
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700128 credentials._scopes = ["one", "two"]
129 assert credentials.scopes == ["one", "two"]
130 assert credentials.has_scopes(["one"])
131 assert credentials.has_scopes(["two"])
132 assert credentials.has_scopes(["one", "two"])
133 assert not credentials.has_scopes(["three"])
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700134
135
Tres Seaver42468322017-09-11 15:36:53 -0400136def test_readonly_scoped_credentials_requires_scopes():
Jon Wayne Parrott4460a962017-09-12 10:01:23 -0700137 credentials = ReadOnlyScopedCredentialsImpl()
Jon Wayne Parrott71ce2a02016-10-14 14:08:10 -0700138 assert not credentials.requires_scopes
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700139
140
141class RequiresScopedCredentialsImpl(credentials.Scoped, CredentialsImpl):
142 def __init__(self, scopes=None):
143 super(RequiresScopedCredentialsImpl, self).__init__()
144 self._scopes = scopes
145
146 @property
147 def requires_scopes(self):
148 return not self.scopes
149
150 def with_scopes(self, scopes):
151 return RequiresScopedCredentialsImpl(scopes=scopes)
152
153
154def test_create_scoped_if_required_scoped():
155 unscoped_credentials = RequiresScopedCredentialsImpl()
156 scoped_credentials = credentials.with_scopes_if_required(
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700157 unscoped_credentials, ["one", "two"]
158 )
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700159
160 assert scoped_credentials is not unscoped_credentials
161 assert not scoped_credentials.requires_scopes
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700162 assert scoped_credentials.has_scopes(["one", "two"])
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700163
164
165def test_create_scoped_if_required_not_scopes():
166 unscoped_credentials = CredentialsImpl()
167 scoped_credentials = credentials.with_scopes_if_required(
Bu Sun Kim9eec0912019-10-21 17:04:21 -0700168 unscoped_credentials, ["one", "two"]
169 )
Jon Wayne Parrottf89a3cf2016-10-31 10:52:57 -0700170
171 assert scoped_credentials is unscoped_credentials