test_credentials.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # Copyright 2016 Google LLC
  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. import datetime
  15. import pytest
  16. from google.auth import _helpers
  17. from google.auth import credentials
  18. class CredentialsImpl(credentials.Credentials):
  19. def refresh(self, request):
  20. self.token = request
  21. def with_quota_project(self, quota_project_id):
  22. raise NotImplementedError()
  23. def test_credentials_constructor():
  24. credentials = CredentialsImpl()
  25. assert not credentials.token
  26. assert not credentials.expiry
  27. assert not credentials.expired
  28. assert not credentials.valid
  29. def test_expired_and_valid():
  30. credentials = CredentialsImpl()
  31. credentials.token = "token"
  32. assert credentials.valid
  33. assert not credentials.expired
  34. # Set the expiration to one second more than now plus the clock skew
  35. # accomodation. These credentials should be valid.
  36. credentials.expiry = (
  37. datetime.datetime.utcnow() + _helpers.CLOCK_SKEW + datetime.timedelta(seconds=1)
  38. )
  39. assert credentials.valid
  40. assert not credentials.expired
  41. # Set the credentials expiration to now. Because of the clock skew
  42. # accomodation, these credentials should report as expired.
  43. credentials.expiry = datetime.datetime.utcnow()
  44. assert not credentials.valid
  45. assert credentials.expired
  46. def test_before_request():
  47. credentials = CredentialsImpl()
  48. request = "token"
  49. headers = {}
  50. # First call should call refresh, setting the token.
  51. credentials.before_request(request, "http://example.com", "GET", headers)
  52. assert credentials.valid
  53. assert credentials.token == "token"
  54. assert headers["authorization"] == "Bearer token"
  55. request = "token2"
  56. headers = {}
  57. # Second call shouldn't call refresh.
  58. credentials.before_request(request, "http://example.com", "GET", headers)
  59. assert credentials.valid
  60. assert credentials.token == "token"
  61. assert headers["authorization"] == "Bearer token"
  62. def test_anonymous_credentials_ctor():
  63. anon = credentials.AnonymousCredentials()
  64. assert anon.token is None
  65. assert anon.expiry is None
  66. assert not anon.expired
  67. assert anon.valid
  68. def test_anonymous_credentials_refresh():
  69. anon = credentials.AnonymousCredentials()
  70. request = object()
  71. with pytest.raises(ValueError):
  72. anon.refresh(request)
  73. def test_anonymous_credentials_apply_default():
  74. anon = credentials.AnonymousCredentials()
  75. headers = {}
  76. anon.apply(headers)
  77. assert headers == {}
  78. with pytest.raises(ValueError):
  79. anon.apply(headers, token="TOKEN")
  80. def test_anonymous_credentials_before_request():
  81. anon = credentials.AnonymousCredentials()
  82. request = object()
  83. method = "GET"
  84. url = "https://example.com/api/endpoint"
  85. headers = {}
  86. anon.before_request(request, method, url, headers)
  87. assert headers == {}
  88. class ReadOnlyScopedCredentialsImpl(credentials.ReadOnlyScoped, CredentialsImpl):
  89. @property
  90. def requires_scopes(self):
  91. return super(ReadOnlyScopedCredentialsImpl, self).requires_scopes
  92. def test_readonly_scoped_credentials_constructor():
  93. credentials = ReadOnlyScopedCredentialsImpl()
  94. assert credentials._scopes is None
  95. def test_readonly_scoped_credentials_scopes():
  96. credentials = ReadOnlyScopedCredentialsImpl()
  97. credentials._scopes = ["one", "two"]
  98. assert credentials.scopes == ["one", "two"]
  99. assert credentials.has_scopes(["one"])
  100. assert credentials.has_scopes(["two"])
  101. assert credentials.has_scopes(["one", "two"])
  102. assert not credentials.has_scopes(["three"])
  103. def test_readonly_scoped_credentials_requires_scopes():
  104. credentials = ReadOnlyScopedCredentialsImpl()
  105. assert not credentials.requires_scopes
  106. class RequiresScopedCredentialsImpl(credentials.Scoped, CredentialsImpl):
  107. def __init__(self, scopes=None, default_scopes=None):
  108. super(RequiresScopedCredentialsImpl, self).__init__()
  109. self._scopes = scopes
  110. self._default_scopes = default_scopes
  111. @property
  112. def requires_scopes(self):
  113. return not self.scopes
  114. def with_scopes(self, scopes, default_scopes=None):
  115. return RequiresScopedCredentialsImpl(
  116. scopes=scopes, default_scopes=default_scopes
  117. )
  118. def test_create_scoped_if_required_scoped():
  119. unscoped_credentials = RequiresScopedCredentialsImpl()
  120. scoped_credentials = credentials.with_scopes_if_required(
  121. unscoped_credentials, ["one", "two"]
  122. )
  123. assert scoped_credentials is not unscoped_credentials
  124. assert not scoped_credentials.requires_scopes
  125. assert scoped_credentials.has_scopes(["one", "two"])
  126. def test_create_scoped_if_required_not_scopes():
  127. unscoped_credentials = CredentialsImpl()
  128. scoped_credentials = credentials.with_scopes_if_required(
  129. unscoped_credentials, ["one", "two"]
  130. )
  131. assert scoped_credentials is unscoped_credentials