all repos — dotfiles @ c2895b6fb3cfb1b791bf03a71deb1794687052ca

my *nix dotfiles

nix/bin/pw.nix (view raw)

  1{ pkgs, theme, ... }:
  2
  3let
  4  name = "pw";
  5  pamixer = "${pkgs.pamixer}/bin/pamixer";
  6  lemonbar = "${pkgs.lemonbar-xft}/bin/lemonbar";
  7in
  8pkgs.writeShellScriptBin name
  9  ''
 10    #!/usr/bin/env bash
 11    # pw - a mnml password manager
 12    command -v gpg >/dev/null 2>&1 && gpg=gpg
 13    command -v gpg2 >/dev/null 2>&1 && gpg=gpg2
 14    # check if xclip or pbcopy exist
 15    # command -v xclip >/dev/null 2>&1 && copy="xclip -rmlastnl -selection clipboard"
 16    # command -v pbcopy >/dev/null 2>&1 && copy="pbcopy | tr -d '\n'"
 17    # export PW_DIR to your own path
 18    [[ -z "$PW_DIR" ]] && PW_DIR="$HOME/.pw"
 19    init() {
 20        if [[ ! -e "$PW_DIR" ]]; then
 21            mkdir -p "$PW_DIR"
 22            printf "pw: password directory initialized at %s\n" "$PW_DIR"
 23        else
 24            printf "PW_DIR is %s\n" "$PW_DIR"
 25            die "$PW_DIR exists"
 26        fi
 27    }
 28    add() {
 29        # $1: path to file
 30        # $2 [optional]: password text
 31        [[ -z "$PW_KEY" ]] && die "\$PW_KEY not set"
 32        if [[ "$#" -eq 2 ]]; then
 33            pass="$2"
 34        else
 35            # uses default length of 25 chars, unless PW_LEN is set
 36            pass="$(pwgen "${PW_LEN:-25}" 1 -s)"
 37            printf "pw: generated password for %s\n" "$1"
 38        fi
 39        if [[ ! -f "$PW_DIR/$1.gpg" ]]; then
 40            printf "%s" "$pass" | "$gpg" -aer "$PW_KEY" -o "$PW_DIR/$1.gpg"
 41            printf "pw: %s/%s.gpg created\n" "$PW_DIR" "$1"
 42        else
 43            die "the file $PW_DIR/$1.gpg exists"
 44        fi
 45        (
 46            cd $PW_DIR
 47            git add .
 48            git commit -m "$(date)"
 49            remote="$(git remote show)"
 50            branch="$(git branch --show-current)"
 51            git pull -r "$remote" "$branch"
 52            git push "$remote" "$branch"
 53        )
 54    }
 55    list() {
 56        (cd "$PW_DIR"; find *.gpg | awk -F '.gpg' '{ print $1 }' )
 57    }
 58    del() {
 59        checkf "$PW_DIR/$1.gpg"
 60        read -rn 1 -p "pw: are you sure you want to delete $1? [y/n]: "
 61        printf "\n"
 62        [[ "$REPLY" == [yY] ]] && {
 63            rm -f "$PW_DIR/$1.gpg"
 64            printf "pw: deleted %s" "$1"
 65        }
 66    }
 67    show() {
 68        checkf "$PW_DIR/$1.gpg"
 69        "$gpg" --decrypt --quiet --use-agent "$PW_DIR/$1.gpg"
 70    }
 71    # TODO: rework having to checkf twice
 72    copy() {
 73        checkf "$PW_DIR/$1.gpg"
 74        if [[ "$OSTYPE" =~ darwin* ]]; then
 75            show "$1" | head -1 | pbcopy | tr -d '\n'
 76        else
 77            show "$1" | head -1 | xclip -rmlastnl -selection clipboard
 78        fi
 79        printf "pw: copied %s to clipboard\n" "$1"
 80    }
 81    usage() {
 82        usage="
 83    pw - mnml password manager
 84    usage: pw [options] [NAME]
 85    All options except -i and -h require a NAME argument.
 86    options:
 87      -i            Initializes password directory at \$HOME/.pw or at \$PW_DIR, if it exists.
 88      -a            Add a password.
 89      -g            Generate a password.
 90      -s            Print password to STDOUT.
 91      -l            List out all passwords.
 92      -c            Copy existing password to clipboard.
 93      -d            Delete password.
 94      -h            Display this help message and exit.
 95    Requires PW_KEY to be set. Optionally, set PW_DIR for custom directory location.
 96    Set PW_LEN to an integer of your choice, to override the default password length of 25.
 97    "
 98        printf "%s" "$usage"
 99        exit 1
100    }
101    checkf() {
102        [[ ! -f "$1" ]] &&
103            die "$1 does not exist"
104    }
105    die() {
106        printf "error: %s\n" "$1" >&2
107        exit 1
108    }
109    main() {
110        [[ -z "$1" ]] && {
111            usage
112        }
113        while getopts "ila:g:s:c:d:h" options
114        do
115            # shellcheck disable=SC2221,SC2222
116            case "$options" in
117                i) init ;;
118                l) list ;;
119                g) add "$OPTARG" ;;
120                a)
121                   read -rsp "enter password: " pass
122                   printf "\n"
123                   add "$OPTARG" "$pass"
124                   ;;
125                s) show "$OPTARG" ;;
126                c) copy "$OPTARG" ;;
127                d) del "$OPTARG" ;;
128                *|h) usage ;;
129            esac
130        done
131        shift $(( OPTIND -1 ))
132    }
133    main "$@"
134  ''