Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/auth/iam.py: 53%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

34 statements  

1# Copyright 2017 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 

15"""Tools for using the Google `Cloud Identity and Access Management (IAM) 

16API`_'s auth-related functionality. 

17 

18.. _Cloud Identity and Access Management (IAM) API: 

19 https://cloud.google.com/iam/docs/ 

20""" 

21 

22import base64 

23import http.client as http_client 

24import json 

25 

26from google.auth import _helpers 

27from google.auth import crypt 

28from google.auth import exceptions 

29 

30 

31_IAM_SCOPE = ["https://www.googleapis.com/auth/iam"] 

32 

33_IAM_ENDPOINT = ( 

34 "https://iamcredentials.googleapis.com/v1/projects/-" 

35 + "/serviceAccounts/{}:generateAccessToken" 

36) 

37 

38_IAM_SIGN_ENDPOINT = ( 

39 "https://iamcredentials.googleapis.com/v1/projects/-" 

40 + "/serviceAccounts/{}:signBlob" 

41) 

42 

43_IAM_IDTOKEN_ENDPOINT = ( 

44 "https://iamcredentials.googleapis.com/v1/" 

45 + "projects/-/serviceAccounts/{}:generateIdToken" 

46) 

47 

48 

49class Signer(crypt.Signer): 

50 """Signs messages using the IAM `signBlob API`_. 

51 

52 This is useful when you need to sign bytes but do not have access to the 

53 credential's private key file. 

54 

55 .. _signBlob API: 

56 https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts 

57 /signBlob 

58 """ 

59 

60 def __init__(self, request, credentials, service_account_email): 

61 """ 

62 Args: 

63 request (google.auth.transport.Request): The object used to make 

64 HTTP requests. 

65 credentials (google.auth.credentials.Credentials): The credentials 

66 that will be used to authenticate the request to the IAM API. 

67 The credentials must have of one the following scopes: 

68 

69 - https://www.googleapis.com/auth/iam 

70 - https://www.googleapis.com/auth/cloud-platform 

71 service_account_email (str): The service account email identifying 

72 which service account to use to sign bytes. Often, this can 

73 be the same as the service account email in the given 

74 credentials. 

75 """ 

76 self._request = request 

77 self._credentials = credentials 

78 self._service_account_email = service_account_email 

79 

80 def _make_signing_request(self, message): 

81 """Makes a request to the API signBlob API.""" 

82 message = _helpers.to_bytes(message) 

83 

84 method = "POST" 

85 url = _IAM_SIGN_ENDPOINT.format(self._service_account_email) 

86 headers = {"Content-Type": "application/json"} 

87 body = json.dumps( 

88 {"payload": base64.b64encode(message).decode("utf-8")} 

89 ).encode("utf-8") 

90 

91 self._credentials.before_request(self._request, method, url, headers) 

92 response = self._request(url=url, method=method, body=body, headers=headers) 

93 

94 if response.status != http_client.OK: 

95 raise exceptions.TransportError( 

96 "Error calling the IAM signBlob API: {}".format(response.data) 

97 ) 

98 

99 return json.loads(response.data.decode("utf-8")) 

100 

101 @property 

102 def key_id(self): 

103 """Optional[str]: The key ID used to identify this private key. 

104 

105 .. warning:: 

106 This is always ``None``. The key ID used by IAM can not 

107 be reliably determined ahead of time. 

108 """ 

109 return None 

110 

111 @_helpers.copy_docstring(crypt.Signer) 

112 def sign(self, message): 

113 response = self._make_signing_request(message) 

114 return base64.b64decode(response["signedBlob"])