def test_remove(): """ Tests the remove() method of PupDB. """ database = PupDB(TEST_DB_PATH) for i in range(10): database.set(i, i) # Removing key 0 from the database. database.remove(0) for i in range(10): if i == 0: assert database.get(i) is None else: assert database.get(i) is not None # Check the behavaiour for a non-existent key. with pytest.raises(KeyError): database.remove(1000)
class Crypt(Logger): def __init__(self, name=None, fn=None, use_secret=CRYPT_USE_SECRET, path_secret=PATH_CRYPT_SECRET, encrypt_values=False, encryptor_func=None, decryptor_func=None): # defaults if not name and fn: name = os.path.basename(fn).replace('.', '_') self.name, self.fn = name, fn # use secret? for salting if use_secret and path_secret: if not os.path.exists(path_secret): self.secret = get_random_binary_id() from comrad.backend.keymaker import make_key_discreet self.log('shhh! creating secret:', make_key_discreet(self.secret)) with open(path_secret, 'wb') as of: of.write(self.secret) else: with open(path_secret, 'rb') as f: self.secret = f.read() else: self.secret = b'' self.encrypt_values = encrypt_values if self.secret and encrypt_values and (not encryptor_func or not decryptor_func): from comrad.backend.keymaker import ComradSymmetricKeyWithPassphrase self.key = ComradSymmetricKeyWithPassphrase(passphrase=self.secret) encryptor_func = self.key.encrypt decryptor_func = self.key.decrypt self.encryptor_func = encryptor_func self.decryptor_func = decryptor_func # self.store = FilesystemStore(self.fn) # self.store = RedisStore(redis.StrictRedis()) # self.db = Vedis(self.fn) # self.db = WalrusLite(self.fn) # import hirlite # self.db = hirlite.Rlite(path=self.fn) from pupdb.core import PupDB self.db = PupDB(self.fn) def log(self, *x, **y): if LOG_GET_SET: super().log(*x) def hash(self, binary_data): # return binary_data return b64enc_s(hasher(b64dec(binary_data), self.secret)) def force_binary(self, k_b): if k_b is None: return None if type(k_b) == str: k_b = k_b.encode() if type(k_b) != bytes: k_b = k_b.decode() return k_b def package_key(self, k, prefix=''): return b64enc_s(prefix) + b64enc_s(k) def package_val(self, v, encrypt=None): if encrypt is None: encrypt = self.encrypt_values v_b = self.force_binary(v) if encrypt: try: v_b = self.encryptor_func(v_b) except ThemisError as e: self.log('!! ENCRYPTION ERROR:', e) v = b64enc_s(v) return v def unpackage_val(self, v, encrypt=None): v_b = b64dec(v) if encrypt is None: encrypt = self.encrypt_values if encrypt: try: v_b = self.decryptor_func(v_b) except ThemisError as e: self.log('!! DECRYPTION ERROR:', e) return v_b def has(self, k, prefix=''): got = self.get(k, prefix=prefix) # self.log('has got',got) return bool(got) def set(self, k, v, prefix='', override=False, encrypt=True): if self.has(k, prefix=prefix) and not override: self.log( f"I'm afraid I can't let you do that, overwrite someone's data!\n\nat {prefix}{k} = {v}" ) return False #(False,None,None) k_b = self.package_key(k, prefix=prefix) k_b_hash = self.hash(k_b) v_b = self.package_val(v, encrypt=(self.encrypt_values and encrypt)) if not override: self.log(f'''Crypt.set(\n\t{k_b}\n\n\t{k_b_hash}\n\n\t{v_b}\n)''') #self.store.put(k_b_hash,v_b) #with self.db.transaction(): # self.db[k_b_hash]=v_b # return self.db.command('set',k_b_hash,v_b) return self.db.set(k_b_hash, v_b) # return True def exists(self, k, prefix=''): return self.has(k, prefix=prefix) def key2hash(self, k, prefix=''): return self.hash(self.package_key(prefix + k)) def delete(self, k, prefix=''): k_b = self.package_key(k, prefix=prefix) k_b_hash = self.hash(k_b) # v = self.db.command('del',k_b_hash) v = self.db.remove(k_b_hash) self.log('<--', v) return v def get(self, k, prefix=''): k_b = self.package_key(k, prefix=prefix) k_b_hash = self.hash(k_b) # v=self.db.get(k_b_hash) self.log('getting k', k, 'with prefix', prefix) self.log('getting k_b', k_b) self.log('getting k_b_hash', k_b_hash) # v = self.db.command('get',k_b_hash) v = self.db.get(k_b_hash) self.log('<--', v) v_b = self.unpackage_val(v) return v_b