diff --git a/app/main.py b/app/main.py index b61ffae..c416078 100644 --- a/app/main.py +++ b/app/main.py @@ -49,20 +49,26 @@ def save( numbers=numbers, ) - password = pass_gen.generate_password(sqlite_repo, options) + try: + password = pass_gen.generate_password(sqlite_repo, options) - typer.echo(typer.style(f"🔐 {password}", fg=typer.colors.GREEN, bold=True)) + typer.echo(typer.style(f"🔐 {password}", fg=typer.colors.GREEN, bold=True)) - if file is not None: - utils.save_to_file(file, password) - return typer.echo(f"The password has been saved to: {file} 🗄") + if file is not None: + utils.save_to_file(file, password) + return typer.echo(f"The password has been saved to: {file} 🗄") - utils.copy_to_clipboard(password) - return typer.echo("The password has been copied to your clipboard 😉\nPaste it using cmd + v") + utils.copy_to_clipboard(password) + return typer.echo( + "The password has been copied to your clipboard 😉\nPaste it using cmd + v" + ) + except ValueError as error: + typer.echo(f"error: {error}", err=True) @app.command() def read() -> None: sqlite_repo = sqlite.get_instance() - stored_passwords = sqlite_repo.list_all() - typer.echo([f"{p.service}: {p.password.get_secret_value()}" for p in stored_passwords]) + stored_passwords = pass_gen.list_all_saved_passwords(sqlite_repo) + for p in stored_passwords: + typer.echo(f"{p.service}: {p.password.get_secret_value()}") diff --git a/app/repositories/fake.py b/app/repositories/fake.py index 998dc1e..600c6d6 100644 --- a/app/repositories/fake.py +++ b/app/repositories/fake.py @@ -15,6 +15,9 @@ class FakeRepository: Password(id=1, service="second", password=SecretStr("iK2ZWeqh")), ] + def exists(self, service: str) -> bool: + return False + @classmethod def get_instance(cls) -> FakeRepository: return FakeRepository() diff --git a/app/repositories/sqlite.py b/app/repositories/sqlite.py index b02f3fd..d215e45 100644 --- a/app/repositories/sqlite.py +++ b/app/repositories/sqlite.py @@ -21,9 +21,17 @@ class PasswordRepository: def list_all(self) -> list[Password]: return [ Password(id=row[0], service=row[1], password=row[2]) - for row in self.db.execute("SELECT * FROM " "passwords").fetchall() + for row in self.db.execute("SELECT * FROM passwords").fetchall() ] + def exists(self, service: str) -> bool: + row = self.db.execute( + "SELECT EXISTS(SELECT 1 FROM passwords WHERE service=:service)", + {"service": service}, + ).fetchone() + + return bool(row[0]) + def get_instance() -> PasswordRepository: db = sqlite.DB() diff --git a/app/repositories/type.py b/app/repositories/type.py index 9cb8c04..428b92c 100644 --- a/app/repositories/type.py +++ b/app/repositories/type.py @@ -9,3 +9,6 @@ class Repository(Protocol): def list_all(self) -> list[Password]: ... + + def exists(self, service: str) -> bool: + ... diff --git a/app/usecases/pass_gen.py b/app/usecases/pass_gen.py index c1ef114..6d23385 100644 --- a/app/usecases/pass_gen.py +++ b/app/usecases/pass_gen.py @@ -17,6 +17,9 @@ class PassGenOptions(BaseModel): def generate_password(repo: Repository, options: PassGenOptions) -> str: + if repo.exists(options.service): + raise ValueError("password for this service has already been set") + characters = _build_characters(symbols=options.symbols, numbers=options.numbers) random_generator = _new_random_generator(options.seed) password = "".join(random_generator.sample(characters, options.length))