mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 08:38:32 +02:00
- initial pass through to rework encryption into separate module - little more cleanup - rename function, fix some linting issues - more cleaning - fix password bug in encryption - fix linting issue - more cleanup - move prompt into prompt.py - more cleanup - update the upgrade process for new encryption classes - general cleanup - turn into enum instead of strings - store status code so tests don't fail - standardize the load and store methods in journals - get rid of old PlainJournal class - typing cleanup - more cleanup - format - fix linting issue - Fix obscure Windows line ending issue with decode See https://bugs.python.org/issue40863 - fix for python 3.11 - add more typing - don't use class variables because that's not what we want - fix more type hints - jrnlv1 encryption doesn't support encryption anymore (it's deprecated) - keep logic for password attemps inside the class that uses it - take out old line of code - add some more logging - update logging statements - clean up logging statements - run linters - fix typo - Fix for new test from develop branch There was a new test added for re-encrypting a journal. This updates the refactor to match the old (previously untested) behavior of jrnl. Co-authored-by: Micah Jerome Ellison <micah.jerome.ellison@gmail.com>
81 lines
2.4 KiB
Python
81 lines
2.4 KiB
Python
# Copyright © 2012-2022 jrnl contributors
|
|
# License: https://www.gnu.org/licenses/gpl-3.0.html
|
|
import logging
|
|
|
|
from jrnl.encryption.BaseEncryption import BaseEncryption
|
|
from jrnl.exception import JrnlException
|
|
from jrnl.keyring import get_keyring_password
|
|
from jrnl.messages import Message
|
|
from jrnl.messages import MsgStyle
|
|
from jrnl.messages import MsgText
|
|
from jrnl.prompt import create_password
|
|
from jrnl.prompt import prompt_password
|
|
|
|
|
|
class BasePasswordEncryption(BaseEncryption):
|
|
def __init__(self, *args, **kwargs) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
logging.debug("start")
|
|
self._attempts: int = 0
|
|
self._max_attempts: int = 3
|
|
self._password: str = ""
|
|
self._check_keyring: bool = True
|
|
|
|
@property
|
|
def check_keyring(self) -> bool:
|
|
return self._check_keyring
|
|
|
|
@check_keyring.setter
|
|
def check_keyring(self, value: bool) -> None:
|
|
self._check_keyring = value
|
|
|
|
@property
|
|
def password(self) -> str | None:
|
|
return self._password
|
|
|
|
@password.setter
|
|
def password(self, value: str) -> None:
|
|
self._password = value
|
|
|
|
def clear(self):
|
|
self.password = None
|
|
self.check_keyring = False
|
|
|
|
def encrypt(self, text: str) -> bytes:
|
|
logging.debug("encrypting")
|
|
if not self.password:
|
|
if self.check_keyring and (
|
|
keyring_pw := get_keyring_password(self._journal_name)
|
|
):
|
|
self.password = keyring_pw
|
|
|
|
if not self.password:
|
|
self.password = create_password(self._journal_name)
|
|
|
|
return self._encrypt(text)
|
|
|
|
def decrypt(self, text: bytes) -> str:
|
|
logging.debug("decrypting")
|
|
if not self.password:
|
|
if self.check_keyring and (
|
|
keyring_pw := get_keyring_password(self._journal_name)
|
|
):
|
|
self.password = keyring_pw
|
|
|
|
if not self.password:
|
|
self._prompt_password()
|
|
|
|
while (result := self._decrypt(text)) is None:
|
|
self._prompt_password()
|
|
|
|
return result
|
|
|
|
def _prompt_password(self) -> None:
|
|
if self._attempts >= self._max_attempts:
|
|
raise JrnlException(
|
|
Message(MsgText.PasswordMaxTriesExceeded, MsgStyle.ERROR)
|
|
)
|
|
|
|
first_try = self._attempts == 0
|
|
self.password = prompt_password(first_try=first_try)
|
|
self._attempts += 1
|