Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/auth/crypt/base.py: 69%

32 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:40 +0000

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 

15"""Base classes for cryptographic signers and verifiers.""" 

16 

17import abc 

18import io 

19import json 

20 

21from google.auth import exceptions 

22 

23_JSON_FILE_PRIVATE_KEY = "private_key" 

24_JSON_FILE_PRIVATE_KEY_ID = "private_key_id" 

25 

26 

27class Verifier(metaclass=abc.ABCMeta): 

28 """Abstract base class for crytographic signature verifiers.""" 

29 

30 @abc.abstractmethod 

31 def verify(self, message, signature): 

32 """Verifies a message against a cryptographic signature. 

33 

34 Args: 

35 message (Union[str, bytes]): The message to verify. 

36 signature (Union[str, bytes]): The cryptography signature to check. 

37 

38 Returns: 

39 bool: True if message was signed by the private key associated 

40 with the public key that this object was constructed with. 

41 """ 

42 # pylint: disable=missing-raises-doc,redundant-returns-doc 

43 # (pylint doesn't recognize that this is abstract) 

44 raise NotImplementedError("Verify must be implemented") 

45 

46 

47class Signer(metaclass=abc.ABCMeta): 

48 """Abstract base class for cryptographic signers.""" 

49 

50 @abc.abstractproperty 

51 def key_id(self): 

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

53 raise NotImplementedError("Key id must be implemented") 

54 

55 @abc.abstractmethod 

56 def sign(self, message): 

57 """Signs a message. 

58 

59 Args: 

60 message (Union[str, bytes]): The message to be signed. 

61 

62 Returns: 

63 bytes: The signature of the message. 

64 """ 

65 # pylint: disable=missing-raises-doc,redundant-returns-doc 

66 # (pylint doesn't recognize that this is abstract) 

67 raise NotImplementedError("Sign must be implemented") 

68 

69 

70class FromServiceAccountMixin(metaclass=abc.ABCMeta): 

71 """Mix-in to enable factory constructors for a Signer.""" 

72 

73 @abc.abstractmethod 

74 def from_string(cls, key, key_id=None): 

75 """Construct an Signer instance from a private key string. 

76 

77 Args: 

78 key (str): Private key as a string. 

79 key_id (str): An optional key id used to identify the private key. 

80 

81 Returns: 

82 google.auth.crypt.Signer: The constructed signer. 

83 

84 Raises: 

85 ValueError: If the key cannot be parsed. 

86 """ 

87 raise NotImplementedError("from_string must be implemented") 

88 

89 @classmethod 

90 def from_service_account_info(cls, info): 

91 """Creates a Signer instance instance from a dictionary containing 

92 service account info in Google format. 

93 

94 Args: 

95 info (Mapping[str, str]): The service account info in Google 

96 format. 

97 

98 Returns: 

99 google.auth.crypt.Signer: The constructed signer. 

100 

101 Raises: 

102 ValueError: If the info is not in the expected format. 

103 """ 

104 if _JSON_FILE_PRIVATE_KEY not in info: 

105 raise exceptions.MalformedError( 

106 "The private_key field was not found in the service account " "info." 

107 ) 

108 

109 return cls.from_string( 

110 info[_JSON_FILE_PRIVATE_KEY], info.get(_JSON_FILE_PRIVATE_KEY_ID) 

111 ) 

112 

113 @classmethod 

114 def from_service_account_file(cls, filename): 

115 """Creates a Signer instance from a service account .json file 

116 in Google format. 

117 

118 Args: 

119 filename (str): The path to the service account .json file. 

120 

121 Returns: 

122 google.auth.crypt.Signer: The constructed signer. 

123 """ 

124 with io.open(filename, "r", encoding="utf-8") as json_file: 

125 data = json.load(json_file) 

126 

127 return cls.from_service_account_info(data)