Decrypt ragnar.db.enc to ragnar.db. Keeps encrypted copy as backup.
(self)
| 773 | raise |
| 774 | |
| 775 | def decrypt_database(self): |
| 776 | """Decrypt ragnar.db.enc to ragnar.db. Keeps encrypted copy as backup.""" |
| 777 | if not self._fernet_key: |
| 778 | raise RuntimeError("No Fernet key available for decryption") |
| 779 | |
| 780 | if not os.path.exists(self.encrypted_db_path): |
| 781 | logger.warning("No encrypted database to decrypt") |
| 782 | return |
| 783 | |
| 784 | with self._lock: |
| 785 | try: |
| 786 | f = Fernet(self._fernet_key) |
| 787 | with open(self.encrypted_db_path, 'rb') as enc_file: |
| 788 | encrypted = enc_file.read() |
| 789 | |
| 790 | plaintext = f.decrypt(encrypted) |
| 791 | |
| 792 | # Remove empty placeholder DB and its WAL/SHM files before writing |
| 793 | if os.path.exists(self.main_db_path): |
| 794 | os.remove(self.main_db_path) |
| 795 | for suffix in ['-wal', '-shm']: |
| 796 | p = self.main_db_path + suffix |
| 797 | if os.path.exists(p): |
| 798 | os.remove(p) |
| 799 | |
| 800 | with open(self.main_db_path, 'wb') as db_file: |
| 801 | db_file.write(plaintext) |
| 802 | |
| 803 | logger.info("Database decrypted successfully") |
| 804 | except InvalidToken: |
| 805 | logger.error("Database decryption failed - invalid key") |
| 806 | raise |
| 807 | except Exception as e: |
| 808 | logger.error(f"Database decryption failed: {e}") |
| 809 | raise |
| 810 | |
| 811 | def shutdown_encrypt(self): |
| 812 | """Called on application shutdown to encrypt the database.""" |