Start of bitwarden.el
This commit is contained in:
parent
a3f6539920
commit
778befee9b
@ -4,8 +4,8 @@
|
|||||||
First of all, thank you for being interested in contributing! You rock!
|
First of all, thank you for being interested in contributing! You rock!
|
||||||
|
|
||||||
In this document, you will find some guidelines for contributing to
|
In this document, you will find some guidelines for contributing to
|
||||||
~TEMPLATE-NAME.el~. These are more guidelines than rules, so don’t try
|
~bitwarden.el~. These are more guidelines than rules, so don’t try too
|
||||||
too hard to follow them.
|
hard to follow them.
|
||||||
|
|
||||||
* Table of Contents :TOC_5_gh:
|
* Table of Contents :TOC_5_gh:
|
||||||
- [[#how-can-i-contribute][How Can I Contribute?]]
|
- [[#how-can-i-contribute][How Can I Contribute?]]
|
||||||
|
72
README.org
72
README.org
@ -1,34 +1,42 @@
|
|||||||
#+title: TEMPLATE-NAME
|
#+title: bitwarden.el
|
||||||
#+author: Lucien Cartier-Tilet
|
#+author: Lucien Cartier-Tilet
|
||||||
#+email: lucien@phundrak.com
|
#+email: lucien@phundrak.com
|
||||||
|
|
||||||
* Introduction
|
* Introduction
|
||||||
Describe briefly what the package is, what it does, and who it is for.
|
Bitwarden.el is a Bitwarden porcelain for Emacs. It aims to be a
|
||||||
|
complete text-based interface for the [[https://github.com/bitwarden/cli][Bitwarden CLI]].
|
||||||
|
|
||||||
|
Most of its public function are transient functions from the
|
||||||
|
transient library to provide the user an easy-to-use interface with
|
||||||
|
most of its options exposed.
|
||||||
|
|
||||||
|
|
||||||
* Table of Contents :TOC_2_gh:
|
* Table of Contents :TOC_2_gh:
|
||||||
- [[#introduction][Introduction]]
|
- [[#introduction][Introduction]]
|
||||||
- [[#installation][Installation]]
|
- [[#installation][Installation]]
|
||||||
|
- [[#notes][Notes]]
|
||||||
|
- [[#login][Login]]
|
||||||
- [[#customizing][Customizing]]
|
- [[#customizing][Customizing]]
|
||||||
- [[#contributing][Contributing]]
|
- [[#contributing][Contributing]]
|
||||||
- [[#license][License]]
|
- [[#license][License]]
|
||||||
|
|
||||||
* Installation
|
* Installation
|
||||||
A couple of options are available for installing ~TEMPLATE-NAME~.
|
A couple of options are available for installing bitwarden.el.
|
||||||
|
|
||||||
The first one is to clone the repository in your ~load-path~ and add the
|
The first one is to clone the repository in your ~load-path~ and add the
|
||||||
following to your ~.emacs~ or your ~init.el~:
|
following to your ~.emacs~ or your ~init.el~:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(require 'TEMPLATE-NAME)
|
(require 'bitwarden.el)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
In my case, I prefer using ~use-package~ with ~straight~:
|
In my case, I prefer using ~use-package~ with ~straight~:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package TEMPLATE-NAME
|
(use-package bitwarden
|
||||||
:ensure t
|
:ensure t
|
||||||
:defer t
|
:defer t
|
||||||
:straight (TEMPLATE-NAME :type git
|
:straight (bitwarden :type git
|
||||||
:host nil
|
:host nil
|
||||||
:repo "https://labs.phundrak.com/phundrak/TEMPLATE-NAME"))
|
:repo "https://labs.phundrak.com/phundrak/bitwarden.el"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
I personally also added ~:build t~ in the straight recipe to ensure
|
I personally also added ~:build t~ in the straight recipe to ensure
|
||||||
@ -42,14 +50,56 @@ a PR to add some more installation instructions!
|
|||||||
There is currently no plans of making this package available on MELPA
|
There is currently no plans of making this package available on MELPA
|
||||||
or non-gnu elpa.
|
or non-gnu elpa.
|
||||||
|
|
||||||
|
* Notes
|
||||||
|
** Login
|
||||||
|
Loging in with the ~--apikey~ option is not supported due to its
|
||||||
|
interactive nature.
|
||||||
|
|
||||||
|
Bitwarden allows three different sources for your password:
|
||||||
|
- a plain password as an argument following the username
|
||||||
|
- an environment variable containing the password
|
||||||
|
- a file containing the password
|
||||||
|
Bitwarden.el allows a fourth option: the authinfo file on computer. To
|
||||||
|
use this option, simply add the following line in your ~.authinfo~ or
|
||||||
|
~.authinfo.gpg~ file:
|
||||||
|
#+begin_src text
|
||||||
|
machine bitwarden.example.com login yourusername password yourpassword
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Of course, you will have to replace ~bitwarden.example.com~ with the
|
||||||
|
actual server, ~yourusername~ with your actual username, and
|
||||||
|
~yourpassword~ with your actual password. If you do not set your
|
||||||
|
username or your password in bitwarden.el, the package will look for
|
||||||
|
them in your auth source file on login. Bitwarden.el retrieves the
|
||||||
|
server name from the command
|
||||||
|
#+begin_src bash
|
||||||
|
$ bw config server
|
||||||
|
#+end_src
|
||||||
|
and it strips the result from any ~http://~ or ~https://~ prefix. For
|
||||||
|
instance, if the command returns ~https://example.com/bitwarden~,
|
||||||
|
bitwarden.el will look for ~example.com/bitwarden~ in your authinfo
|
||||||
|
file.
|
||||||
|
|
||||||
* Customizing
|
* Customizing
|
||||||
Indicate the various customization options available, e.g. variables
|
Bitwarden.el has a couple of customizable variables you can find in
|
||||||
and faces. For each one of them, give a brief description and their
|
the ~bitwarden~ group when executing ~M-x customize-group~. Here is a
|
||||||
default value.
|
quick description of these variables:
|
||||||
|
- ~bitwarden-cli-executable~ :: Your Bitwarden CLI executable. Set this
|
||||||
|
variable if Emacs doesn’t find ~bw~ in your ~$PATH~ or if ~bw~ does not
|
||||||
|
refer to your Bitwarden CLI.
|
||||||
|
|
||||||
|
Default value: ~bw~
|
||||||
|
- ~bitwarden-default-cli-arguments~ :: A list of the default arguments
|
||||||
|
to pass to Bitwarden CLI. By default, only the package only passes
|
||||||
|
~--nointeraction~ in order to inhibit any attempt from the CLI to
|
||||||
|
launch anything interactive --- it should be taken care of by the
|
||||||
|
package itself.
|
||||||
|
|
||||||
|
Default value: ~'("--nointeraction")~
|
||||||
|
|
||||||
* Contributing
|
* Contributing
|
||||||
See [[file:CONTRIBUTING.org]].
|
See [[file:CONTRIBUTING.org]].
|
||||||
|
|
||||||
* License
|
* License
|
||||||
~TEMPLATE-NAME.el~ is available under the GNU GPL-3.0 license. You can
|
~bitwarden.el~ is available under the GNU GPL-3.0 license. You can
|
||||||
find the full text in [[file:LICENSE.md][LICENSE.md]].
|
find the full text in [[file:LICENSE.md][LICENSE.md]].
|
||||||
|
305
bitwarden.el
Normal file
305
bitwarden.el
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
;;; bitwarden.el --- Interact with Bitwarden from Emacs -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Author: Lucien Cartier-Tilet <lucien@phundrak.com>
|
||||||
|
;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com>
|
||||||
|
;; Version: 0.1.0
|
||||||
|
;; Package-Requires: ((emacs "27.1") (transient "0.3.7"))
|
||||||
|
;; Homepage: https://labs.phundrak.com/phundrak/bitwarden.el
|
||||||
|
;; Keywords:
|
||||||
|
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; # Introduction
|
||||||
|
|
||||||
|
;; bitwarden.el is a Bitwarden porcelain for Emacs. It aims to be a
|
||||||
|
;; complete text-based interface for the Bitwarden CLI
|
||||||
|
;; (https://github.com/bitwarden/cli).
|
||||||
|
;;
|
||||||
|
;; Most of its public function are transient functions from the
|
||||||
|
;; transient library to provide the user an easy-to-use interface with
|
||||||
|
;; most of its options exposed.
|
||||||
|
;;
|
||||||
|
;; # Notes
|
||||||
|
;; ## Login
|
||||||
|
;;
|
||||||
|
;; Loging in with the --apikey option is not supported due to its
|
||||||
|
;; interactive nature.
|
||||||
|
;;
|
||||||
|
;; Bitwarden allows three different sources for your password:
|
||||||
|
;; - a plain password as an argument following the username
|
||||||
|
;; - an environment variable containing the password
|
||||||
|
;; - a file containing the password
|
||||||
|
;; Bitwarden.el allows a fourth option: the authinfo file on computer.
|
||||||
|
;; To use this option, simply add the following line in your .authinfo
|
||||||
|
;; or .authinfo.gpg file:
|
||||||
|
;;
|
||||||
|
;; machine bitwarden.example.com login yourusername password yourpassword
|
||||||
|
;;
|
||||||
|
;; Of course, you will have to replace `bitwarden.example.com` with
|
||||||
|
;; the actual server, `yourusername` with your actual username, and
|
||||||
|
;; `yourpassword` with your actual password. If you do not set your
|
||||||
|
;; username or your password in bitwarden.el, the package will look
|
||||||
|
;; for them in your auth source file on login. Bitwarden.el retrieves
|
||||||
|
;; the server name from the command
|
||||||
|
;;
|
||||||
|
;; bw config server
|
||||||
|
;;
|
||||||
|
;; and it strips the result from any http:// or https:// prefix. For
|
||||||
|
;; instance, if the command returns "https://example.com/bitwarden",
|
||||||
|
;; bitwarden.el will look for "example.com/bitwarden" in your authinfo
|
||||||
|
;; file.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Requires
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'eshell)
|
||||||
|
(require 'auth-source)
|
||||||
|
(require 'transient)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Constants
|
||||||
|
(defconst bitwarden-version "0.1.0")
|
||||||
|
|
||||||
|
(defconst bitwarden-login-methods '(("Authentificator" . "0") ("Email" . "1") ("YubiKey" . "3"))
|
||||||
|
"Bitwarden login methods.")
|
||||||
|
|
||||||
|
|
||||||
|
;;; Group and Custom Variables
|
||||||
|
(defgroup bitwarden ()
|
||||||
|
"Interact with Bitwarden from Emacs."
|
||||||
|
:group 'applications
|
||||||
|
:prefix "bitwarden-"
|
||||||
|
:link '(url-link :tag "Gitea" "https://labs.phundrak.com/phundrak/bitwarden.el"))
|
||||||
|
|
||||||
|
(defcustom bitwarden-cli-executable "bw"
|
||||||
|
"Path to the Bitwarden CLI executable."
|
||||||
|
:type 'string
|
||||||
|
:group 'bitwarden
|
||||||
|
:safe #'stringp
|
||||||
|
:version "0.1.0")
|
||||||
|
|
||||||
|
(defcustom bitwarden-default-cli-arguments '("--nointeraction")
|
||||||
|
"Default arguments for the Bitwarden CLI."
|
||||||
|
:group 'bitwarden
|
||||||
|
:type '(repeat string)
|
||||||
|
:version "0.1.0")
|
||||||
|
|
||||||
|
(defvar bitwarden--shell-status)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Internal Functions
|
||||||
|
|
||||||
|
(defun bitwarden--run-cli (&rest args)
|
||||||
|
"Run the Bitwarden cli with ARGS.
|
||||||
|
The default arguments specified by
|
||||||
|
`bitwarden-default-cli-arguments' immediately follow the cli’s
|
||||||
|
name defined in `bitwarden-cli-executable'.
|
||||||
|
|
||||||
|
The output status of the command is stored in RESULT, which
|
||||||
|
should be a variable’s symbol."
|
||||||
|
(eshell-command-result
|
||||||
|
(mapconcat #'identity
|
||||||
|
(flatten-tree `(,bitwarden-cli-executable ,bitwarden-default-cli-arguments ,args))
|
||||||
|
" ")
|
||||||
|
'bitwarden--shell-status))
|
||||||
|
|
||||||
|
(defun bitwarden-hello ()
|
||||||
|
"Dummy function."
|
||||||
|
(interactive)
|
||||||
|
(message "hello"))
|
||||||
|
|
||||||
|
;;; Transient Infixes
|
||||||
|
(eval-when-compile
|
||||||
|
(defmacro bitwarden--define-infix (key name description type version
|
||||||
|
default &rest reader)
|
||||||
|
"Define infix and its corresponding variable at once.
|
||||||
|
The variable is named bitwarden-NAME is of type TYPE, has a
|
||||||
|
DESCRIPTION and a specified VERSION.
|
||||||
|
The KEY and READER are for the infix declaration.
|
||||||
|
|
||||||
|
This macro is largely copied from Tecosaur’s screenshot.el"
|
||||||
|
(let ((var-name (concat "bitwarden-" name)))
|
||||||
|
`(progn
|
||||||
|
(defcustom ,(intern var-name) ,default
|
||||||
|
,description
|
||||||
|
:type ,type
|
||||||
|
:group 'bitwarden
|
||||||
|
:version ,version)
|
||||||
|
(transient-define-infix ,(intern (concat "bitwarden--set-" name)) ()
|
||||||
|
"Set Bitwarden options."
|
||||||
|
:class 'transient-lisp-variable
|
||||||
|
:variable ',(intern var-name)
|
||||||
|
:key ,key
|
||||||
|
:description ,description
|
||||||
|
:argument ,(concat "--" name)
|
||||||
|
:reader (lambda (&rest _) ,@reader)))))
|
||||||
|
|
||||||
|
;; Config
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-s" "server" "On-premises hosted installation URL"
|
||||||
|
'string "0.1.0"
|
||||||
|
(let ((output-str (bitwarden--run-cli "config" "server")))
|
||||||
|
(if (eq 0 bitwarden--shell-status)
|
||||||
|
(string-trim output-str "https?://")
|
||||||
|
""))
|
||||||
|
(read-string "Server URL: "))
|
||||||
|
|
||||||
|
;; Login
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-u" "username" "Email of the user."
|
||||||
|
'string "0.1.0"
|
||||||
|
""
|
||||||
|
(read-string "Email address: "))
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-p" "password" "Password of the user"
|
||||||
|
'string "0.1.0"
|
||||||
|
""
|
||||||
|
(read-string "Password: "))
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-s" "sso" "Log in with Single-Sign On"
|
||||||
|
'boolean "0.1.0" nil
|
||||||
|
(not bitwarden-sso))
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-e" "passwordenv" "Environment variable storing your password"
|
||||||
|
'string "0.1.0"
|
||||||
|
""
|
||||||
|
(read-string "Environment variable: "))
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-f" "passwordfile"
|
||||||
|
"Path to a file containing your password as its first line"
|
||||||
|
'string "0.1.0" ""
|
||||||
|
(read-file-name "Password file: "))
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-c" "code"
|
||||||
|
"Two-step login code"
|
||||||
|
'string "0.1.0" ""
|
||||||
|
(read-string "Two-step code: "))
|
||||||
|
|
||||||
|
(bitwarden--define-infix
|
||||||
|
"-m" "method"
|
||||||
|
"Two-step login method"
|
||||||
|
'string "0.1.0" "0"
|
||||||
|
(cdr (assoc (completing-read "Two-step login method: "
|
||||||
|
bitwarden-login-methods)
|
||||||
|
bitwarden-login-methods))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Transient Actions
|
||||||
|
(eval-when-compile
|
||||||
|
(defmacro bitwarden--def-action (name description transient &rest body)
|
||||||
|
"Create a function called from TRANSIENT.
|
||||||
|
DESCRIPTION is the docstring of the function named
|
||||||
|
bitwarden--NAME, and it gets BODY as its body."
|
||||||
|
`(defun ,(intern (concat "bitwarden--action-" name)) (&optional _args)
|
||||||
|
,(concat description "
|
||||||
|
This function is meant to be called by a transient.")
|
||||||
|
(interactive
|
||||||
|
(list (transient-args ,transient)))
|
||||||
|
,@body))
|
||||||
|
|
||||||
|
;; Config
|
||||||
|
|
||||||
|
(bitwarden--def-action
|
||||||
|
"set-server"
|
||||||
|
"Set the Bitwarden server."
|
||||||
|
'bitwarden--server
|
||||||
|
(message "%s" (format "%S" _args)))
|
||||||
|
|
||||||
|
;; Login
|
||||||
|
|
||||||
|
(bitwarden--def-action
|
||||||
|
"login"
|
||||||
|
"Log in Bitwarden."
|
||||||
|
'bitwarden--login
|
||||||
|
(if bitwarden-sso
|
||||||
|
(bitwarden--run-cli "login" "--raw" "--sso")
|
||||||
|
(bitwarden--run-cli "login" "--raw"
|
||||||
|
;; bitwarden-username
|
||||||
|
(format "\"%s\""
|
||||||
|
(if (string= "" bitwarden-username))
|
||||||
|
(plist-get (car (auth-source-search
|
||||||
|
:max 1
|
||||||
|
:host bitwarden-server))
|
||||||
|
:user)
|
||||||
|
bitwarden-username)
|
||||||
|
(format "\"%s\""
|
||||||
|
(cond
|
||||||
|
((not (string= "" bitwarden-password))
|
||||||
|
bitwarden-password)
|
||||||
|
((! (string= "" bitwarden-passwordenv))
|
||||||
|
bitwarden-passwordenv)
|
||||||
|
((! (string= "" bitwarden-passwordfile))
|
||||||
|
bitwarden-passwordfile)
|
||||||
|
(t (funcall
|
||||||
|
(plist-get
|
||||||
|
(car (auth-source-search :max 1
|
||||||
|
:host bitwarden-server))
|
||||||
|
:secret))))))))
|
||||||
|
|
||||||
|
(bitwarden--def-action
|
||||||
|
"logout"
|
||||||
|
"Log out of Bitwarden."
|
||||||
|
'bitwarden--login
|
||||||
|
(shell-command (concat bitwarden-cli-executable " logout"))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Transient Prefixes
|
||||||
|
(transient-define-prefix bitwarden-config ()
|
||||||
|
["Options"
|
||||||
|
(bitwarden--set-server)]
|
||||||
|
["Actions"
|
||||||
|
("g" "Get current server" bitwarden-hello)
|
||||||
|
("s" "Set current server" bitwarden-hello)])
|
||||||
|
|
||||||
|
(transient-define-prefix bitwarden-login ()
|
||||||
|
["Options"
|
||||||
|
(bitwarden--set-username)
|
||||||
|
(bitwarden--set-password)
|
||||||
|
(bitwarden--set-passwordenv)
|
||||||
|
(bitwarden--set-passwordfile)
|
||||||
|
(bitwarden--set-method)
|
||||||
|
(bitwarden--set-code)]
|
||||||
|
["Actions"
|
||||||
|
("l" "Login" bitwarden-login)
|
||||||
|
("L" "Logout" bitwarden-logout)])
|
||||||
|
|
||||||
|
(transient-define-prefix bitwarden-transient ()
|
||||||
|
["Actions"
|
||||||
|
("c" "Config" bitwarden--config)
|
||||||
|
("l" "Login" bitwarden--login)
|
||||||
|
("L" "Lock" bitwarden-hello)
|
||||||
|
("s" "sync" bitwarden-hello)])
|
||||||
|
|
||||||
|
;; (defun bitwarden ()
|
||||||
|
;; (interactive)
|
||||||
|
;; (call-interactively #'bitwarden-transient))
|
||||||
|
|
||||||
|
(provide 'bitwarden)
|
||||||
|
|
||||||
|
;;; bitwarden.el ends here
|
Loading…
Reference in New Issue
Block a user