~anjan/public-inbox

added onepassword.py v1 APPLIED

Kim Visscher
Kim Visscher: 1
 added onepassword.py

 2 files changed, 161 insertions(+), 0 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~anjan/public-inbox/patches/24737/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] added onepassword.py Export this patch

Kim Visscher
---
 README.md      |   5 ++
 onepassword.py | 156 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)
 create mode 100755 onepassword.py

diff --git a/README.md b/README.md
index d6bf01b..d8b3427 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,11 @@ Please use [git send-email](https://git-send-email.io/) and send a patch to my [

# Summary of scripts

## onepassword.py
- Author: Kim Visscher <kim@visscher.codes>
- License: MIT
- Description: A mobile friendly interface for [1Password](https://1password.com/)

## Workout
- Author: Anjandev Momi <anjan@momi.ca>
- License: MIT
diff --git a/onepassword.py b/onepassword.py
new file mode 100755
index 0000000..9ab99cd
--- /dev/null
+++ b/onepassword.py
@@ -0,0 +1,156 @@
#!/usr/bin/env python3

# This script makes some pretty naive assumptions.
# It assumes that you have setup your 1Password account atleast once, by issuing: op signin <sign_in_address> <email_address> <secret_key>
# Furthermore it assumes a very happy flow of things, and deliberately doesn't do a lot of try-except error handling to improve performance.
#
# To find 1Password's latest CLI release, consult: https://app-updates.agilebits.com/product_history/CLI
# To install 1Password execute the following command:
# wget https://cache.agilebits.com/dist/1P/op/pkg/LATEST/op_linux_arm64_LATEST.zip && \
# unzip op_linux_arm64_LATEST.zip && \
# sudo mv op /usr/local/bin/op && \
# rm op.sig && \
# rm op_linux_arm64_LATEST.zip
#
# To install pexpect execute the following command:
# sudo pip install pexpect

import subprocess
import json
import operator
import os
import sys
import pexpect
import re

SUCCESS = 0
FAILURE = 1

# TODO: change this into a color that suites your dmenu.
COLOR = "#bcecff"

UUID_REGEX_PATTERN = re.compile("^.*\((.*)\)$")


def notify(message):
    if not os.environ.get("SSH_CLIENT") and not os.environ.get("SSH_TTY"):
        subprocess.run(["notify-send", message])


def notify_and_die(message):
    notify(message)

    print(message, file=sys.stderr)
    sys.exit(FAILURE)


dmenu_result = subprocess.run(
    [
        "ash",
        "-c",
        f"sxmo_dmenu_with_kb.sh -c -p \"pwd:\" -nf '{COLOR}' -nb '{COLOR}' <&-",
    ],
    capture_output=True,
)
password = bytes.decode(dmenu_result.stdout, "utf-8").strip()

signin_process = None
try:
    signin_process = pexpect.spawn("op signin")
    signin_process.expect("Enter the password for .* at .*\.1password\.com: ")
    signin_process.sendline(password)
    signin_process.expect(pexpect.EOF, timeout=5)
    signin_process.close()
except:
    notify_and_die("unable to sign in...")

if signin_process.exitstatus != SUCCESS:
    notify_and_die("wrong password...")

signin_token = (
    bytes.decode(signin_process.before, "utf-8").split("\r\n")[1].split(" ")[1].strip()
)

list_vaults_process = subprocess.run(
    ["ash", "-c", f"{signin_token} op list vaults"], capture_output=True
)
vaults = json.loads(list_vaults_process.stdout)

vaults = sorted(vaults, key=operator.itemgetter("name"))
dmenu_input = "\n".join([f"{vault['name']} ({vault['uuid']})" for vault in vaults])

dmenu_result = subprocess.run(
    [
        "sxmo_dmenu_with_kb.sh",
        "-c",
        "-l",
        "10",
    ],
    capture_output=True,
    input=bytes(dmenu_input, "utf-8"),
)
selected_vault_id = UUID_REGEX_PATTERN.match(
    bytes.decode(dmenu_result.stdout, "utf-8").strip()
).group(1)

list_items_process = subprocess.run(
    ["ash", "-c", f"{signin_token} op list items"], capture_output=True
)
items = json.loads(list_items_process.stdout)

items = [
    {
        "uuid": item["uuid"],
        "title": item["overview"]["title"],
        "username": item["overview"]["ainfo"],
    }
    for item in items
    if item["trashed"] == "N" and item["vaultUuid"] == selected_vault_id
]
items = sorted(items, key=operator.itemgetter("title"))

dmenu_input = "\n".join(
    [
        f"{item['title']} ({item['username'] if item['username'] else '-'}) ({item['uuid']})"
        for item in items
    ]
)

dmenu_result = subprocess.run(
    [
        "sxmo_dmenu_with_kb.sh",
        "-c",
        "-l",
        "10",
    ],
    capture_output=True,
    input=bytes(dmenu_input, "utf-8"),
)

selected_item_id = UUID_REGEX_PATTERN.match(
    bytes.decode(dmenu_result.stdout, "utf-8").strip()
).group(1)

get_item_process = subprocess.run(
    ["ash", "-c", f"{signin_token} op get item {selected_item_id}"],
    capture_output=True,
)
item = json.loads(get_item_process.stdout)

password = list(
    filter(lambda field: field["designation"] == "password", item["details"]["fields"])
)[0]["value"]

if os.environ.get("SSH_CLIENT") or os.environ.get("SSH_TTY"):
    print(password)
else:
    subprocess.run(
        ["xclip", "-i", "/dev/null"],
    )
    subprocess.run(
        ["xclip", "-i"],
        input=bytes(password, "utf-8"),
    )
    notify("copied to clipboard!")

sys.exit(SUCCESS)
--
2.20.1
Thanks! Applied.

To git.sr.ht:~anjan/sxmo-userscripts
   7deb5a2..d067649  master -> master
-- 
w:] www.momi.ca
pgp:] https://momi.ca/publickey.txt