credentials.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # Copyright 2024 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. """Interfaces for asynchronous credentials."""
  15. from google.auth import _helpers
  16. from google.auth import exceptions
  17. from google.auth._credentials_base import _BaseCredentials
  18. class Credentials(_BaseCredentials):
  19. """Base class for all asynchronous credentials.
  20. All credentials have a :attr:`token` that is used for authentication and
  21. may also optionally set an :attr:`expiry` to indicate when the token will
  22. no longer be valid.
  23. Most credentials will be :attr:`invalid` until :meth:`refresh` is called.
  24. Credentials can do this automatically before the first HTTP request in
  25. :meth:`before_request`.
  26. Although the token and expiration will change as the credentials are
  27. :meth:`refreshed <refresh>` and used, credentials should be considered
  28. immutable. Various credentials will accept configuration such as private
  29. keys, scopes, and other options. These options are not changeable after
  30. construction. Some classes will provide mechanisms to copy the credentials
  31. with modifications such as :meth:`ScopedCredentials.with_scopes`.
  32. """
  33. def __init__(self):
  34. super(Credentials, self).__init__()
  35. async def apply(self, headers, token=None):
  36. """Apply the token to the authentication header.
  37. Args:
  38. headers (Mapping): The HTTP request headers.
  39. token (Optional[str]): If specified, overrides the current access
  40. token.
  41. """
  42. self._apply(headers, token=token)
  43. async def refresh(self, request):
  44. """Refreshes the access token.
  45. Args:
  46. request (google.auth.aio.transport.Request): The object used to make
  47. HTTP requests.
  48. Raises:
  49. google.auth.exceptions.RefreshError: If the credentials could
  50. not be refreshed.
  51. """
  52. raise NotImplementedError("Refresh must be implemented")
  53. async def before_request(self, request, method, url, headers):
  54. """Performs credential-specific before request logic.
  55. Refreshes the credentials if necessary, then calls :meth:`apply` to
  56. apply the token to the authentication header.
  57. Args:
  58. request (google.auth.aio.transport.Request): The object used to make
  59. HTTP requests.
  60. method (str): The request's HTTP method or the RPC method being
  61. invoked.
  62. url (str): The request's URI or the RPC service's URI.
  63. headers (Mapping): The request's headers.
  64. """
  65. await self.apply(headers)
  66. class StaticCredentials(Credentials):
  67. """Asynchronous Credentials representing an immutable access token.
  68. The credentials are considered immutable except the tokens which can be
  69. configured in the constructor ::
  70. credentials = StaticCredentials(token="token123")
  71. StaticCredentials does not support :meth `refresh` and assumes that the configured
  72. token is valid and not expired. StaticCredentials will never attempt to
  73. refresh the token.
  74. """
  75. def __init__(self, token):
  76. """
  77. Args:
  78. token (str): The access token.
  79. """
  80. super(StaticCredentials, self).__init__()
  81. self.token = token
  82. @_helpers.copy_docstring(Credentials)
  83. async def refresh(self, request):
  84. raise exceptions.InvalidOperation("Static credentials cannot be refreshed.")
  85. # Note: before_request should never try to refresh access tokens.
  86. # StaticCredentials intentionally does not support it.
  87. @_helpers.copy_docstring(Credentials)
  88. async def before_request(self, request, method, url, headers):
  89. await self.apply(headers)
  90. class AnonymousCredentials(Credentials):
  91. """Asynchronous Credentials that do not provide any authentication information.
  92. These are useful in the case of services that support anonymous access or
  93. local service emulators that do not use credentials.
  94. """
  95. async def refresh(self, request):
  96. """Raises :class:``InvalidOperation``, anonymous credentials cannot be
  97. refreshed."""
  98. raise exceptions.InvalidOperation("Anonymous credentials cannot be refreshed.")
  99. async def apply(self, headers, token=None):
  100. """Anonymous credentials do nothing to the request.
  101. The optional ``token`` argument is not supported.
  102. Raises:
  103. google.auth.exceptions.InvalidValue: If a token was specified.
  104. """
  105. if token is not None:
  106. raise exceptions.InvalidValue("Anonymous credentials don't support tokens.")
  107. async def before_request(self, request, method, url, headers):
  108. """Anonymous credentials do nothing to the request."""
  109. pass