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
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import gnupg
|
|
||||||
import questionary
|
import questionary
|
||||||
import pyperclip
|
|
||||||
import argparse
|
import argparse
|
||||||
import typer
|
import typer
|
||||||
|
import pyotp
|
||||||
|
|
||||||
from typing_extensions import Annotated
|
from typing_extensions import Annotated
|
||||||
from sys import exit
|
from sys import exit
|
||||||
from os import environ
|
from os import environ
|
||||||
@@ -13,24 +13,14 @@ from subprocess import run, DEVNULL
|
|||||||
|
|
||||||
home = environ.get('HOME')
|
home = environ.get('HOME')
|
||||||
|
|
||||||
gpg = gnupg.GPG(gnupghome=f"{home}/.gnupg", use_agent=True)
|
|
||||||
|
|
||||||
def check_lock() -> bool:
|
def check_lock() -> bool:
|
||||||
check = run(['bw', 'unlock', '--check'], stdout=DEVNULL, stderr=DEVNULL)
|
check = run(['bw', 'unlock', '--check'], stdout=DEVNULL, stderr=DEVNULL)
|
||||||
if check.returncode != 0:
|
if check.returncode != 0:
|
||||||
return False
|
return False
|
||||||
else: return True
|
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():
|
def new_session():
|
||||||
with open(f"{home}/.secret/bw-master.txt.gpg", 'rb') as f:
|
password = questionary.password("Master password").ask()
|
||||||
password = str(gpg.decrypt_file(f)).strip()
|
|
||||||
|
|
||||||
unlock_command = run(['bw', 'unlock', password, '--raw'], capture_output=True, text=True)
|
unlock_command = run(['bw', 'unlock', password, '--raw'], capture_output=True, text=True)
|
||||||
environ["BW_SESSION"] = str(unlock_command.stdout)
|
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")] = ""):
|
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()
|
new_session()
|
||||||
|
|
||||||
list_items_cmd = run(['bw', 'list', 'items'], capture_output=True)
|
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))
|
choices.append(questionary.Choice(f"{item['name']} ({item['login']['username']})", item_index))
|
||||||
|
|
||||||
chosen_index = questionary.select("Select item", choices, use_shortcuts=True).ask()
|
chosen_index = questionary.select("Select item", choices, use_shortcuts=True).ask()
|
||||||
elif (filtered_list) == 1:
|
elif len(filtered_list) == 1:
|
||||||
chosen_index = 0
|
chosen_index = 0
|
||||||
else: chosen_index = None
|
else: chosen_index = None
|
||||||
|
|
||||||
if chosen_index is not 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']:
|
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:
|
else:
|
||||||
print("No item found")
|
print("No item found")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user