Update entry manager for generic entries

This commit is contained in:
thePR0M3TH3AN
2025-07-02 22:28:56 -04:00
parent 2c0baa9591
commit 7fff164da7
2 changed files with 60 additions and 14 deletions

View File

@@ -28,6 +28,7 @@ from pathlib import Path
from termcolor import colored from termcolor import colored
from password_manager.migrations import LATEST_VERSION from password_manager.migrations import LATEST_VERSION
from password_manager.entry_types import EntryType
from password_manager.vault import Vault from password_manager.vault import Vault
from utils.file_lock import exclusive_lock from utils.file_lock import exclusive_lock
@@ -65,7 +66,7 @@ class EntryManager:
return {"schema_version": LATEST_VERSION, "entries": {}} return {"schema_version": LATEST_VERSION, "entries": {}}
else: else:
logger.info( logger.info(
f"Index file '{self.index_file}' not found. Initializing new password database." f"Index file '{self.index_file}' not found. Initializing new entries database."
) )
return {"schema_version": LATEST_VERSION, "entries": {}} return {"schema_version": LATEST_VERSION, "entries": {}}
@@ -79,7 +80,7 @@ class EntryManager:
def get_next_index(self) -> int: def get_next_index(self) -> int:
""" """
Retrieves the next available index for a new password entry. Retrieves the next available index for a new entry.
:return: The next index number as an integer. :return: The next index number as an integer.
""" """
@@ -104,15 +105,17 @@ class EntryManager:
username: Optional[str] = None, username: Optional[str] = None,
url: Optional[str] = None, url: Optional[str] = None,
blacklisted: bool = False, blacklisted: bool = False,
notes: str = "",
) -> int: ) -> int:
""" """
Adds a new password entry to the encrypted JSON index file. Adds a new entry to the encrypted JSON index file.
:param website_name: The name of the website. :param website_name: The name of the website.
:param length: The desired length of the password. :param length: The desired length of the password.
:param username: (Optional) The username associated with the website. :param username: (Optional) The username associated with the website.
:param url: (Optional) The URL of the website. :param url: (Optional) The URL of the website.
:param blacklisted: (Optional) Whether the password is blacklisted. Defaults to False. :param blacklisted: (Optional) Whether the password is blacklisted. Defaults to False.
:param notes: (Optional) Extra notes to attach to the entry.
:return: The assigned index of the new entry. :return: The assigned index of the new entry.
""" """
try: try:
@@ -126,6 +129,8 @@ class EntryManager:
"username": username if username else "", "username": username if username else "",
"url": url if url else "", "url": url if url else "",
"blacklisted": blacklisted, "blacklisted": blacklisted,
"type": EntryType.PASSWORD.value,
"notes": notes,
} }
logger.debug(f"Added entry at index {index}: {data['entries'][str(index)]}") logger.debug(f"Added entry at index {index}: {data['entries'][str(index)]}")
@@ -144,6 +149,39 @@ class EntryManager:
print(colored(f"Error: Failed to add entry: {e}", "red")) print(colored(f"Error: Failed to add entry: {e}", "red"))
sys.exit(1) sys.exit(1)
def add_totp(self, notes: str = "") -> int:
"""Placeholder for adding a TOTP entry."""
index = self.get_next_index()
data = self.vault.load_index()
data.setdefault("entries", {})
data["entries"][str(index)] = {"type": EntryType.TOTP.value, "notes": notes}
self._save_index(data)
self.update_checksum()
self.backup_index_file()
raise NotImplementedError("TOTP entry support not implemented yet")
def add_ssh_key(self, notes: str = "") -> int:
"""Placeholder for adding an SSH key entry."""
index = self.get_next_index()
data = self.vault.load_index()
data.setdefault("entries", {})
data["entries"][str(index)] = {"type": EntryType.SSH.value, "notes": notes}
self._save_index(data)
self.update_checksum()
self.backup_index_file()
raise NotImplementedError("SSH key entry support not implemented yet")
def add_seed(self, notes: str = "") -> int:
"""Placeholder for adding a seed entry."""
index = self.get_next_index()
data = self.vault.load_index()
data.setdefault("entries", {})
data["entries"][str(index)] = {"type": EntryType.SEED.value, "notes": notes}
self._save_index(data)
self.update_checksum()
self.backup_index_file()
raise NotImplementedError("Seed entry support not implemented yet")
def get_encrypted_index(self) -> Optional[bytes]: def get_encrypted_index(self) -> Optional[bytes]:
""" """
Retrieves the encrypted password index file's contents. Retrieves the encrypted password index file's contents.
@@ -161,9 +199,9 @@ class EntryManager:
def retrieve_entry(self, index: int) -> Optional[Dict[str, Any]]: def retrieve_entry(self, index: int) -> Optional[Dict[str, Any]]:
""" """
Retrieves a password entry based on the provided index. Retrieves an entry based on the provided index.
:param index: The index number of the password entry. :param index: The index number of the entry.
:return: A dictionary containing the entry details or None if not found. :return: A dictionary containing the entry details or None if not found.
""" """
try: try:
@@ -193,14 +231,16 @@ class EntryManager:
username: Optional[str] = None, username: Optional[str] = None,
url: Optional[str] = None, url: Optional[str] = None,
blacklisted: Optional[bool] = None, blacklisted: Optional[bool] = None,
notes: Optional[str] = None,
) -> None: ) -> None:
""" """
Modifies an existing password entry based on the provided index and new values. Modifies an existing entry based on the provided index and new values.
:param index: The index number of the password entry to modify. :param index: The index number of the entry to modify.
:param username: (Optional) The new username. :param username: (Optional) The new username.
:param url: (Optional) The new URL. :param url: (Optional) The new URL.
:param blacklisted: (Optional) The new blacklist status. :param blacklisted: (Optional) The new blacklist status.
:param notes: (Optional) New notes to attach to the entry.
""" """
try: try:
data = self.vault.load_index() data = self.vault.load_index()
@@ -232,6 +272,10 @@ class EntryManager:
f"Updated blacklist status to '{blacklisted}' for index {index}." f"Updated blacklist status to '{blacklisted}' for index {index}."
) )
if notes is not None:
entry["notes"] = notes
logger.debug(f"Updated notes for index {index}.")
data["entries"][str(index)] = entry data["entries"][str(index)] = entry
logger.debug(f"Modified entry at index {index}: {entry}") logger.debug(f"Modified entry at index {index}: {entry}")
@@ -252,7 +296,7 @@ class EntryManager:
def list_entries(self) -> List[Tuple[int, str, Optional[str], Optional[str], bool]]: def list_entries(self) -> List[Tuple[int, str, Optional[str], Optional[str], bool]]:
""" """
Lists all password entries in the index. Lists all entries in the index.
:return: A list of tuples containing entry details: (index, website, username, url, blacklisted) :return: A list of tuples containing entry details: (index, website, username, url, blacklisted)
""" """
@@ -261,8 +305,8 @@ class EntryManager:
entries_data = data.get("entries", {}) entries_data = data.get("entries", {})
if not entries_data: if not entries_data:
logger.info("No password entries found.") logger.info("No entries found.")
print(colored("No password entries found.", "yellow")) print(colored("No entries found.", "yellow"))
return [] return []
entries = [] entries = []
@@ -295,9 +339,9 @@ class EntryManager:
def delete_entry(self, index: int) -> None: def delete_entry(self, index: int) -> None:
""" """
Deletes a password entry based on the provided index. Deletes an entry based on the provided index.
:param index: The index number of the password entry to delete. :param index: The index number of the entry to delete.
""" """
try: try:
data = self.vault.load_index() data = self.vault.load_index()
@@ -424,7 +468,7 @@ class EntryManager:
def list_all_entries(self) -> None: def list_all_entries(self) -> None:
""" """
Displays all password entries in a formatted manner. Displays all entries in a formatted manner.
""" """
try: try:
entries = self.list_entries() entries = self.list_entries()
@@ -432,7 +476,7 @@ class EntryManager:
print(colored("No entries to display.", "yellow")) print(colored("No entries to display.", "yellow"))
return return
print(colored("\n[+] Listing All Password Entries:\n", "green")) print(colored("\n[+] Listing All Entries:\n", "green"))
for entry in entries: for entry in entries:
index, website, username, url, blacklisted = entry index, website, username, url, blacklisted = entry
print(colored(f"Index: {index}", "cyan")) print(colored(f"Index: {index}", "cyan"))

View File

@@ -23,6 +23,8 @@ def test_add_and_retrieve_entry():
"username": "user", "username": "user",
"url": "", "url": "",
"blacklisted": False, "blacklisted": False,
"type": "password",
"notes": "",
} }
data = enc_mgr.load_json_data(entry_mgr.index_file) data = enc_mgr.load_json_data(entry_mgr.index_file)