Exemple #1
0
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)
Exemple #2
0
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