Skip to content

Latest commit

 

History

History
169 lines (132 loc) · 4.56 KB

1pass.org

File metadata and controls

169 lines (132 loc) · 4.56 KB

1Password CLI (op) integration for Elvish

This module provides wrappers to use the 1Password op CLI tool with Elvish.

This file is written in literate programming style, to make it easy to explain. See 1pass.elv for the generated file.

Table of Contents

Usage

Install the elvish-modules package using epm (you can put these statements in your rc.elv file as well, to automatically install the package upon startup if needed):

use epm
epm:install &silent-if-installed github.com/zzamboni/elvish-modules

In your rc.elv, load this module:

use github.com/zzamboni/elvish-modules/1pass

Implementation

Load some base modules.

use str
use re
use path

Configuration

The account to use, defaults to my.

var account = my

The command to use, defaults to the op command.

var op = (external op)

The field name where the passwords are usually stored - don’t modify this unless you know what you are doing.

var password-field = "password"

Authentication and token manipulation

Get the current session token. Returns $nil if not set.

fn session-token {|&account=$account|
  if (has-env OP_SESSION_$account) {
    get-env OP_SESSION_$account
  } else {
    put $nil
  }
}

Set the token environment variable

fn set-token {|&account=$account token|
  set-env OP_SESSION_$account $token
}

Refresh the current login token, reauthenticating if needed. Reauthentication can be forced by using the &no-refresh option.

Note that this assumes you have logged in at least once with the full op signin syntax, to specify the account and your email address, as described in the op documentation.

fn signin {|&account=$account &no-refresh=$false|
  var refresh-opts = [ --session (session-token) ]
  if $no-refresh {
    set refresh-opts = []
  }
  set-token &account=$account ($op signin --raw $@refresh-opts </dev/tty)
}

Getting item information

Base function to get item information. This function returns the raw string output from the command.

fn get-item-raw {|item &options=[] &fields=[]|
  signin
  if (not-eq $fields []) {
    set options = [ $@options --fields (str:join , $fields) ]
  } else {
    set options = [ $@options ]
  }
  $op item get $@options $item | slurp
}

The main function is the same, but it parses the return value from JSON into an Elvish map.

fn get-item {|item &options=[] &fields=[]|
  if (!= (count $fields) 1) {
    set options = [ $@options --format json ]
  }
  var item-str = (get-item-raw &options=$options &fields=$fields $item)
  if (== (count $fields) 1) {
    put $item-str
  } else {
    echo $item-str | from-json
  }
}

One of the most common use cases is to get the password stored in an item, so we have a special function for this.

fn get-password {|item|
  get-item &fields=[$password-field] $item
}

Reading op shell plugin aliases

This function reads $1pass:op_plugins_file (default ~/.config/op/plugins.sh) and parses the alias definitions, defining them as Elvish functions.

var op_plugins_file = ~/.config/op/plugins.sh
fn read-aliases {
  if (path:is-regular $op_plugins_file) {
    cat $op_plugins_file | each {|l|
      var m = [(re:find '^alias (\w+)="(.*?)"' $l)]
      if (not-eq $m []) {
        var name = $m[0][groups][1][text]
        var cmd = [(edit:wordify $m[0][groups][2][text])]
        var fndef = (print 'edit:add-var '$name'~ {|@_args| ' $@cmd '$@_args }' | slurp)
        eval $fndef
      }
      if (re:find '^export' $l) {
        var _ key val = (re:split &max=3 '[ =]' $l)
        set-env $key $val
      }
    }
  }
}