Encrypt ragnar.db to ragnar.db.enc and remove the plaintext copy.
(self)
| 729 | # ========================================================================= |
| 730 | |
| 731 | def encrypt_database(self): |
| 732 | """Encrypt ragnar.db to ragnar.db.enc and remove the plaintext copy.""" |
| 733 | if not self._fernet_key: |
| 734 | raise RuntimeError("No Fernet key available for encryption") |
| 735 | |
| 736 | if not os.path.exists(self.main_db_path): |
| 737 | logger.warning("No database to encrypt") |
| 738 | return |
| 739 | |
| 740 | with self._lock: |
| 741 | try: |
| 742 | f = Fernet(self._fernet_key) |
| 743 | with open(self.main_db_path, 'rb') as db_file: |
| 744 | plaintext = db_file.read() |
| 745 | |
| 746 | encrypted = f.encrypt(plaintext) |
| 747 | |
| 748 | # Write encrypted file atomically (write to temp, then rename) |
| 749 | temp_path = self.encrypted_db_path + '.tmp' |
| 750 | with open(temp_path, 'wb') as enc_file: |
| 751 | enc_file.write(encrypted) |
| 752 | |
| 753 | # Replace the encrypted file |
| 754 | if os.path.exists(self.encrypted_db_path): |
| 755 | os.remove(self.encrypted_db_path) |
| 756 | os.rename(temp_path, self.encrypted_db_path) |
| 757 | |
| 758 | # Remove plaintext database |
| 759 | os.remove(self.main_db_path) |
| 760 | # Also remove WAL and SHM files if they exist |
| 761 | for suffix in ['-wal', '-shm']: |
| 762 | wal_path = self.main_db_path + suffix |
| 763 | if os.path.exists(wal_path): |
| 764 | os.remove(wal_path) |
| 765 | |
| 766 | logger.info("Database encrypted successfully") |
| 767 | except Exception as e: |
| 768 | # Clean up temp file on failure |
| 769 | temp_path = self.encrypted_db_path + '.tmp' |
| 770 | if os.path.exists(temp_path): |
| 771 | os.remove(temp_path) |
| 772 | logger.error(f"Database encryption failed: {e}") |
| 773 | raise |
| 774 | |
| 775 | def decrypt_database(self): |
| 776 | """Decrypt ragnar.db.enc to ragnar.db. Keeps encrypted copy as backup.""" |