1###################################################################### 2# 3# File: b2sdk/application_key.py 4# 5# Copyright 2021 Backblaze Inc. All Rights Reserved. 6# 7# License https://www.backblaze.com/using_b2_code.html 8# 9###################################################################### 10 11from typing import List, Optional 12 13 14class BaseApplicationKey: 15 """Common methods for ApplicationKey and FullApplicationKey.""" 16 17 def __init__( 18 self, 19 key_name: str, 20 application_key_id: str, 21 capabilities: List[str], 22 account_id: str, 23 expiration_timestamp_millis: Optional[int] = None, 24 bucket_id: Optional[str] = None, 25 name_prefix: Optional[str] = None, 26 options: Optional[List[str]] = None, 27 ): 28 """ 29 :param key_name: name of the key, assigned by user 30 :param application_key_id: key id, used to authenticate 31 :param capabilities: list of capabilities assigned to this key 32 :param account_id: account's id 33 :param expiration_timestamp_millis: expiration time of the key 34 :param bucket_id: if restricted to a bucket, this is the bucket's id 35 :param name_prefix: if restricted to some files, this is their prefix 36 :param options: reserved for future use 37 """ 38 self.key_name = key_name 39 self.id_ = application_key_id 40 self.capabilities = capabilities 41 self.account_id = account_id 42 self.expiration_timestamp_millis = expiration_timestamp_millis 43 self.bucket_id = bucket_id 44 self.name_prefix = name_prefix 45 self.options = options 46 47 @classmethod 48 def parse_response_dict(cls, response: dict): 49 mandatory_args = { 50 'key_name': response['keyName'], 51 'application_key_id': response['applicationKeyId'], 52 'capabilities': response['capabilities'], 53 'account_id': response['accountId'], 54 } 55 56 optional_args = { 57 'expiration_timestamp_millis': response.get('expirationTimestamp'), 58 'bucket_id': response.get('bucketId'), 59 'name_prefix': response.get('namePrefix'), 60 'options': response.get('options'), 61 } 62 return { 63 **mandatory_args, 64 **{key: value 65 for key, value in optional_args.items() if value is not None}, 66 } 67 68 def as_dict(self): 69 """Represent the key as a dict, like the one returned by B2 cloud""" 70 mandatory_keys = { 71 'keyName': self.key_name, 72 'applicationKeyId': self.id_, 73 'capabilities': self.capabilities, 74 'accountId': self.account_id, 75 } 76 optional_keys = { 77 'expirationTimestamp': self.expiration_timestamp_millis, 78 'bucketId': self.bucket_id, 79 'namePrefix': self.name_prefix, 80 'options': self.options, 81 } 82 return { 83 **mandatory_keys, 84 **{key: value 85 for key, value in optional_keys.items() if value is not None}, 86 } 87 88 89class ApplicationKey(BaseApplicationKey): 90 """Dataclass for storing info about an application key returned by delete-key or list-keys.""" 91 92 @classmethod 93 def from_api_response(cls, response: dict) -> 'ApplicationKey': 94 """Create an ApplicationKey object from a delete-key or list-key response (a parsed json object).""" 95 return cls(**cls.parse_response_dict(response)) 96 97 98class FullApplicationKey(BaseApplicationKey): 99 """Dataclass for storing info about an application key, including the actual key, as returned by create-key.""" 100 101 def __init__( 102 self, 103 key_name: str, 104 application_key_id: str, 105 application_key: str, 106 capabilities: List[str], 107 account_id: str, 108 expiration_timestamp_millis: Optional[int] = None, 109 bucket_id: Optional[str] = None, 110 name_prefix: Optional[str] = None, 111 options: Optional[List[str]] = None, 112 ): 113 """ 114 :param key_name: name of the key, assigned by user 115 :param application_key_id: key id, used to authenticate 116 :param application_key: the actual secret key 117 :param capabilities: list of capabilities assigned to this key 118 :param account_id: account's id 119 :param expiration_timestamp_millis: expiration time of the key 120 :param bucket_id: if restricted to a bucket, this is the bucket's id 121 :param name_prefix: if restricted to some files, this is their prefix 122 :param options: reserved for future use 123 """ 124 self.application_key = application_key 125 super().__init__( 126 key_name=key_name, 127 application_key_id=application_key_id, 128 capabilities=capabilities, 129 account_id=account_id, 130 expiration_timestamp_millis=expiration_timestamp_millis, 131 bucket_id=bucket_id, 132 name_prefix=name_prefix, 133 options=options, 134 ) 135 136 @classmethod 137 def from_create_response(cls, response: dict) -> 'FullApplicationKey': 138 """Create a FullApplicationKey object from a create-key response (a parsed json object).""" 139 return cls(**cls.parse_response_dict(response)) 140 141 @classmethod 142 def parse_response_dict(cls, response: dict): 143 result = super().parse_response_dict(response) 144 result['application_key'] = response['applicationKey'] 145 return result 146 147 def as_dict(self): 148 """Represent the key as a dict, like the one returned by B2 cloud""" 149 return { 150 **super().as_dict(), 151 'applicationKey': self.application_key, 152 } 153