Initial commit
This commit is contained in:
28
pyproject.toml
Normal file
28
pyproject.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[build-system]
|
||||
requires = ["hatchling >= 1.26"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "bw-get"
|
||||
version = "0.0.1"
|
||||
authors = [
|
||||
{name="Fabian van Koppen", email="f@bianvk.nl"}
|
||||
]
|
||||
description = "Wrapper script voor de Bitwarden CLI"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
dependencies = [
|
||||
"questionary",
|
||||
"pyotp",
|
||||
"pyperclip",
|
||||
"typer",
|
||||
"python-gnupg",
|
||||
"typing"
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
bw-get = "bw_get.cli:app"
|
||||
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
questionary
|
||||
pyotp
|
||||
pyperclip
|
||||
typer
|
||||
3
src/bw_get/__init__.py
Normal file
3
src/bw_get/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
if __name__ == "__main__":
|
||||
from bw_get.cli import app
|
||||
app()
|
||||
82
src/bw_get/bw_get.py
Executable file
82
src/bw_get/bw_get.py
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import json
|
||||
import gnupg
|
||||
import questionary
|
||||
import pyperclip
|
||||
import argparse
|
||||
import typer
|
||||
from typing_extensions import Annotated
|
||||
from sys import exit
|
||||
from os import environ
|
||||
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()
|
||||
|
||||
unlock_command = run(['bw', 'unlock', password, '--raw'], capture_output=True, text=True)
|
||||
environ["BW_SESSION"] = str(unlock_command.stdout)
|
||||
if check_lock() is False:
|
||||
print("Something went wrong unlocking the vault")
|
||||
exit(1)
|
||||
|
||||
|
||||
def get_password(search_string: Annotated[str, typer.Argument(help="The term to search for in Vaultwarden")] = ""):
|
||||
|
||||
decrypt_session()
|
||||
if check_lock() is False:
|
||||
new_session()
|
||||
|
||||
list_items_cmd = run(['bw', 'list', 'items'], capture_output=True)
|
||||
|
||||
items = json.loads(list_items_cmd.stdout)
|
||||
|
||||
# Filtering the list based on the search string
|
||||
filtered_list = [
|
||||
d for d in items if any(
|
||||
search_string in str(value) for key, value in d.items()
|
||||
if key != 'login' # Exclude the 'login' key entirely
|
||||
) or (
|
||||
'login' in d and (
|
||||
search_string in str(d['login'].get('username', '')) or
|
||||
search_string in str(d['login'].get('password', ''))
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
choices = []
|
||||
|
||||
if len(filtered_list) > 1:
|
||||
for item_index, item in enumerate(filtered_list):
|
||||
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:
|
||||
chosen_index = 0
|
||||
else: chosen_index = None
|
||||
|
||||
if chosen_index is not None:
|
||||
pyperclip.copy(filtered_list[chosen_index]['login']['password'])
|
||||
if filtered_list[chosen_index]['login']['totp']:
|
||||
print("Todo, fix OTP")
|
||||
else:
|
||||
print("No item found")
|
||||
exit(1)
|
||||
9
src/bw_get/cli.py
Normal file
9
src/bw_get/cli.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import typer
|
||||
|
||||
from .bw_get import get_password
|
||||
|
||||
app = typer.Typer()
|
||||
app.command()(get_password)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
Reference in New Issue
Block a user