First release version
- Added TOTP support - Removed GPG requirement - Display more information about item
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import json
|
||||
import gnupg
|
||||
import questionary
|
||||
import pyperclip
|
||||
import argparse
|
||||
import typer
|
||||
import pyotp
|
||||
|
||||
from typing_extensions import Annotated
|
||||
from sys import exit
|
||||
from os import environ
|
||||
@@ -13,24 +13,14 @@ from subprocess import run, DEVNULL
|
||||
|
||||
home = environ.get('HOME')
|
||||
|
||||
gpg = gnupg.GPG(gnupghome=f"{home}/.gnupg", use_agent=True)
|
||||
|
||||
def check_lock() -> bool:
|
||||
check = run(['bw', 'unlock', '--check'], stdout=DEVNULL, stderr=DEVNULL)
|
||||
if check.returncode != 0:
|
||||
return False
|
||||
else: return True
|
||||
|
||||
def decrypt_session() -> str:
|
||||
with open(f"{home}/.secret/bw-session.txt.gpg", 'rb') as f:
|
||||
master_pw = str(gpg.decrypt_file(f)).strip()
|
||||
|
||||
environ["BW_SESSION"] = f"{master_pw}"
|
||||
f.close()
|
||||
|
||||
def new_session():
|
||||
with open(f"{home}/.secret/bw-master.txt.gpg", 'rb') as f:
|
||||
password = str(gpg.decrypt_file(f)).strip()
|
||||
password = questionary.password("Master password").ask()
|
||||
|
||||
unlock_command = run(['bw', 'unlock', password, '--raw'], capture_output=True, text=True)
|
||||
environ["BW_SESSION"] = str(unlock_command.stdout)
|
||||
@@ -41,8 +31,7 @@ def new_session():
|
||||
|
||||
def get_password(search_string: Annotated[str, typer.Argument(help="The term to search for in Vaultwarden")] = ""):
|
||||
|
||||
decrypt_session()
|
||||
if check_lock() is False:
|
||||
if check_lock is False:
|
||||
new_session()
|
||||
|
||||
list_items_cmd = run(['bw', 'list', 'items'], capture_output=True)
|
||||
@@ -69,14 +58,30 @@ def get_password(search_string: Annotated[str, typer.Argument(help="The term to
|
||||
choices.append(questionary.Choice(f"{item['name']} ({item['login']['username']})", item_index))
|
||||
|
||||
chosen_index = questionary.select("Select item", choices, use_shortcuts=True).ask()
|
||||
elif (filtered_list) == 1:
|
||||
elif len(filtered_list) == 1:
|
||||
chosen_index = 0
|
||||
else: chosen_index = None
|
||||
|
||||
if chosen_index is not None:
|
||||
pyperclip.copy(filtered_list[chosen_index]['login']['password'])
|
||||
|
||||
print(f"name\t\t: {filtered_list[chosen_index]['name']}")
|
||||
print(f"id\t\t: {filtered_list[chosen_index]['id']}")
|
||||
# Loop over URIs
|
||||
print(f"username\t: {filtered_list[chosen_index]['login']['username']}")
|
||||
print(f"password\t: \033[34m\033[44m{filtered_list[chosen_index]['login']['password']}\033[0m")
|
||||
if filtered_list[chosen_index]['login']['totp']:
|
||||
print("Todo, fix OTP")
|
||||
totp = pyotp.parse_uri(filtered_list[chosen_index]['login']['totp'])
|
||||
print(f"TOTP\t\t: {totp.now()}")
|
||||
|
||||
try:
|
||||
import pyperclip
|
||||
except ImportError:
|
||||
print("\nHint: install pyperclip to automatically copy the password to the clipboard.")
|
||||
else:
|
||||
pyperclip.copy(filtered_list[chosen_index]['login']['password'])
|
||||
print("\nPassword has been copied to the clipboard.")
|
||||
|
||||
|
||||
else:
|
||||
print("No item found")
|
||||
exit(1)
|
||||
|
||||
Reference in New Issue
Block a user