Onionr/src/safedb/__init__.py

52 lines
1.5 KiB
Python

from typing import Union
from enum import Enum, auto
import dbm
from .securestring import generate_key_file, protect_string, unprotect_string
class SafeDB:
"""Wrapper around dbm to optionally encrypt db values."""
def get(self, key: Union[str, bytes, bytearray]) -> bytes:
if self.protected:
return self.db_conn[key]
return unprotect_string(self.db_conn[key])
def put(
self, key: [str, bytes, bytearray], value: [bytes, bytearray]):
if self.protected:
self.db_conn[key] = protect_string(value)
else:
self.db_conn[key] = value
def close(self):
self.db_conn.close()
def __init__(self, db_path: str, protected=True):
self.db_path = db_path
self.db_conn = dbm.open(db_path, "c")
try:
existing_protected_mode = self.db_conn['enc']
if protected and existing_protected_mode != b'1':
raise ValueError(
"Cannot open unencrypted database with protected=True")
elif not protected and existing_protected_mode != b'0':
raise ValueError(
"Cannot open encrypted database in protected=False")
except KeyError:
if protected:
self.db_conn['enc'] = b'1'
else:
self.db_conn['enc'] = b'0'
try:
generate_key_file()
except FileExistsError:
pass
self.protected = protected