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

36 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 07:30 +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 

21import six 

22 

23from google.auth import exceptions 

24 

25_JSON_FILE_PRIVATE_KEY = "private_key" 

26_JSON_FILE_PRIVATE_KEY_ID = "private_key_id" 

27 

28 

29@six.add_metaclass(abc.ABCMeta) 

30class Verifier(object): 

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

32 

33 @abc.abstractmethod 

34 def verify(self, message, signature): 

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

36 

37 Args: 

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

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

40 

41 Returns: 

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

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

44 """ 

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

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

47 raise NotImplementedError("Verify must be implemented") 

48 

49 

50@six.add_metaclass(abc.ABCMeta) 

51class Signer(object): 

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

53 

54 @abc.abstractproperty 

55 def key_id(self): 

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

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

58 

59 @abc.abstractmethod 

60 def sign(self, message): 

61 """Signs a message. 

62 

63 Args: 

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

65 

66 Returns: 

67 bytes: The signature of the message. 

68 """ 

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

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

71 raise NotImplementedError("Sign must be implemented") 

72 

73 

74@six.add_metaclass(abc.ABCMeta) 

75class FromServiceAccountMixin(object): 

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

77 

78 @abc.abstractmethod 

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

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

81 

82 Args: 

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

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

85 

86 Returns: 

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

88 

89 Raises: 

90 ValueError: If the key cannot be parsed. 

91 """ 

92 raise NotImplementedError("from_string must be implemented") 

93 

94 @classmethod 

95 def from_service_account_info(cls, info): 

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

97 service account info in Google format. 

98 

99 Args: 

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

101 format. 

102 

103 Returns: 

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

105 

106 Raises: 

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

108 """ 

109 if _JSON_FILE_PRIVATE_KEY not in info: 

110 raise exceptions.MalformedError( 

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

112 ) 

113 

114 return cls.from_string( 

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

116 ) 

117 

118 @classmethod 

119 def from_service_account_file(cls, filename): 

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

121 in Google format. 

122 

123 Args: 

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

125 

126 Returns: 

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

128 """ 

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

130 data = json.load(json_file) 

131 

132 return cls.from_service_account_info(data)