summaryrefslogtreecommitdiff
path: root/provider/posts/pwutil.md
diff options
context:
space:
mode:
Diffstat (limited to 'provider/posts/pwutil.md')
-rw-r--r--provider/posts/pwutil.md122
1 files changed, 122 insertions, 0 deletions
diff --git a/provider/posts/pwutil.md b/provider/posts/pwutil.md
new file mode 100644
index 0000000..a4b3757
--- /dev/null
+++ b/provider/posts/pwutil.md
@@ -0,0 +1,122 @@
1---
2title: A Tool to Manage a Set of YAML Objects Representing Account Information — pwutil
3published: 2015-04-07
4---
5
6A long time ago I wrote a bunch of scripts (first in bash, then zsh, and later perl) to manage a, sometimes encrypted, file containing account information I get asked to create and remember on a daily basis—accounts for shopping websites spring to mind.
7
8[pwutil](git://git.yggdrasil.li/pwutil) is the newest iteration in this line of bunches of scripts.
9
10## Features
11
12 * Support for embedding common operation in any kind of record keeping
13
14 Thus support for almost any encryption known to man (with absolutely no online security), version control, and synchronisation
15 * [Human read- and writeable](https://en.wikipedia.org/wiki/YAML) backstore
16 * Machine parseable output
17 * [Command Line Interface](https://en.wikipedia.org/wiki/Command-line_interface)-only
18 * New accounts can be partially generated by user defined functions with out of the box support for [pwgen](http://sourceforge.net/projects/pwgen/) and SSH
19
20## Usage
21
22~~~
23pwget [<searchTerm> …]
24Looks up and returns all accounts which contain any <searchTerm> anywhere in their representation — case insensitive.
25
26pwadd [[--gen-<generator> [<generatorArgument> …] …] --] <identifier> [<attributeKey> <attributeValue> …]
27Adds an account to the store — does not overwrite.
28~~~
29
30## Documentation
31
32I shall document the project in a partial and file-wise fashion—amendments available on request.
33
34### Structure
35
36~~~ {#DirTree}
37pwutil
38├── default.nix
39├── PWAdd.hs
40├── PWGet.hs
41├── PWUtil
42│   ├── Extra
43│   │   ├── PWGen.hs
44│   │   └── SSHCmd.hs
45│   ├── Types.hs
46│   └── Util.hs
47├── pwutil.hs
48├── PWUtil.hs
49└── pwutil.nix
50~~~
51
52### `pwutil.nix`
53is a [nix](https://nixos.org/nix) expression allowing easy installation using the nix package manager.
54A `~/.nixpkgs/config.nix` allowing one to do so might look thus:
55
56~~~ {.numberLines}
57{
58 packageOverrides = pkgs: {
59 pwutil = pkgs.callPackage /path/to/pwutil.nix {};
60 };
61}
62~~~
63
64The derivation takes some arguments (write those in `{}` above):
65
66`main ? null`
67 ~ Overwrite `pwutil.hs` with a file path
68
69`with<Package> ? false`
70 ~ `<Package>` is one of Pwgen, or Ssh a the current time.
71 If `true` wraps executables to have `$PATH` include `<Package>`.
72
73### `Types.hs`
74
75Introducing `PW` (much as [xmonad](https://xmonad.org) did with `X`) is an easy way to keep track of the `PWConfig` without resorting to function arguments.
76`BackStore` is our (new and improved) way of encapsulating store access in a totally customisable way—`plain`, which is essential `readFile` and `writeFile` as provided by `ByteString`, is provided for convenience in `Util.hs`.
77`PWConfig` most importantly contains a definition of generators (called by passing `--gen-…` to `pwadd`).
78
79~~~ {#Types.hs .haskell .numberLines}
80module PWUtil.Types (
81 PW(..),
82 BackStore(..),
83 PWConfig(..),
84 Generator(..)
85 ) where
86
87import Control.Monad.State
88import qualified Data.Map as M
89import Data.Yaml
90import Data.ByteString
91
92type PW = StateT PWConfig IO
93
94data BackStore = BackStore
95 { readContents :: PW ByteString
96 , writeContents :: ByteString -> PW ()
97 }
98
99data PWConfig = PWConfig
100 { generators :: M.Map String Generator
101 , backstore :: BackStore
102 }
103
104type Generator = [String] -> PW Value
105~~~
106
107
108### `pwutil.hs`
109
110is, in a [xmonad](http://xmonad.org) kind of way, the configuration file—the shipped default is reproduced below as a template for custom configs.
111
112~~~ {#pwutil.hs .haskell .numberLines}
113import PWUtil
114
115import System.FilePath ((</>))
116import System.Directory (getHomeDirectory)
117
118main :: IO ()
119main = do
120 h <- getHomeDirectory
121 runPW (emptyConfig { backstore = plain (h </> "accounts.yaml") }) pwutil
122~~~