diff options
author | eniotna.t <eniotna.t@gmail.com> | 2014-08-29 15:19:28 +0200 |
---|---|---|
committer | eniotna.t <eniotna.t@gmail.com> | 2014-08-29 15:19:28 +0200 |
commit | a3d1279dc88fb6e2ca5eeb3c1e3aa1a7a0f7054b (patch) | |
tree | d97643123b2a6c84ff3cbca25e04ec0826964cad /XMonad | |
parent | da55f3778c9ac27a23f5566f300f74337f3fadaa (diff) | |
download | XMonadContrib-a3d1279dc88fb6e2ca5eeb3c1e3aa1a7a0f7054b.tar.gz XMonadContrib-a3d1279dc88fb6e2ca5eeb3c1e3aa1a7a0f7054b.tar.xz XMonadContrib-a3d1279dc88fb6e2ca5eeb3c1e3aa1a7a0f7054b.zip |
add-new-xmonad-prompt-pass
Ignore-this: 11e85dfe3d24cef88d8d89f4e7b1ec0b
This module provides 3 <XMonad.Prompt> to ease passwords manipulation (generate, read, remove):
- one to lookup passwords in the password-storage.
- one to generate a password for a given password label that the user inputs.
- one to delete a stored password for a given password label that the user inputs.
All those prompts benefit from the completion system provided by the module <XMonad.Prompt>.
The password store is setuped through an environment variable PASSWORD_STORE_DIR.
If this is set, use the content of the variable.
Otherwise, the password store is located on user's home @$HOME\/.password-store@.
Source:
- The password storage implementation is <http://git.zx2c4.com/password-store the password-store cli>.
- Inspired from <http://babushk.in/posts/combining-xmonad-and-pass.html>
darcs-hash:20140829131928-ab0f9-201583ab1cebfed0b77492c080b8a70f7b389eeb.gz
Diffstat (limited to '')
-rw-r--r-- | XMonad/Prompt/Pass.hs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/XMonad/Prompt/Pass.hs b/XMonad/Prompt/Pass.hs new file mode 100644 index 0000000..db4ce2d --- /dev/null +++ b/XMonad/Prompt/Pass.hs @@ -0,0 +1,142 @@ +----------------------------------------------------------------------------- +-- | +-- Module : XMonad.Prompt.Pass +-- Copyright : (c) 2014 Igor Babuschkin, Antoine R. Dumont +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : Antoine R. Dumont <eniotna.t@gmail.com> +-- Stability : unstable +-- Portability : unportable +-- +-- This module provides 3 <XMonad.Prompt> to ease passwords manipulation (generate, read, remove): +-- +-- - one to lookup passwords in the password-storage. +-- +-- - one to generate a password for a given password label that the user inputs. +-- +-- - one to delete a stored password for a given password label that the user inputs. +-- +-- All those prompts benefit from the completion system provided by the module <XMonad.Prompt>. +-- +-- The password store is setuped through an environment variable PASSWORD_STORE_DIR. +-- If this is set, use the content of the variable. +-- Otherwise, the password store is located on user's home @$HOME\/.password-store@. +-- +-- +-- Source: +-- +-- - The password storage implementation is <http://git.zx2c4.com/password-store the password-store cli>. +-- +-- - Inspired from <http://babushk.in/posts/combining-xmonad-and-pass.html> +-- +----------------------------------------------------------------------------- + +module XMonad.Prompt.Pass ( + -- * Usages + -- $usages + passPrompt + , passGeneratePrompt + , passRemovePrompt + ) where + +import Control.Monad (liftM) +import XMonad.Core +import XMonad.Prompt ( XPrompt + , showXPrompt + , commandToComplete + , nextCompletion + , getNextCompletion + , XPConfig + , mkXPrompt + , mkComplFunFromList) +import System.Directory (getDirectoryContents, getHomeDirectory) +import System.FilePath (takeBaseName, combine) +import System.Posix.Env (getEnv) + +-- $usages +-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: +-- +-- > import XMonad.Prompt.Pass +-- +-- Then add a keybinding for 'passPrompt', 'passGeneratePrompt' or 'passRemovePrompt': +-- +-- > , ((modMask x , xK_p) , passPrompt xpconfig) +-- > , ((modMask x .|. controlMask, xK_p) , passGeneratePrompt xpconfig) +-- > , ((modMask x .|. controlMask .|. shiftMask, xK_p), passRemovePrompt xpconfig) +-- +-- For detailed instructions on: +-- +-- - editing your key bindings, see "XMonad.Doc.Extending#Editing_key_bindings". +-- +-- - how to setup the password storage, see <http://git.zx2c4.com/password-store/about/> +-- + +type PromptLabel = String + +data Pass = Pass PromptLabel + +instance XPrompt Pass where + showXPrompt (Pass prompt) = prompt ++ ": " + commandToComplete _ c = c + nextCompletion _ = getNextCompletion + +-- | Default password store folder in $HOME/.password-store +-- +passwordStoreFolderDefault :: String -> String +passwordStoreFolderDefault home = combine home ".password-store" + +-- | Compute the password store's location. +-- Use the PASSWORD_STORE_DIR environment variable to set the password store. +-- If empty, return the password store located in user's home. +-- +passwordStoreFolder :: IO String +passwordStoreFolder = + getEnv "PASSWORD_STORE_DIR" >>= computePasswordStoreDir + where computePasswordStoreDir Nothing = liftM passwordStoreFolderDefault getHomeDirectory + computePasswordStoreDir (Just storeDir) = return storeDir + +-- | A pass prompt factory +-- +mkPassPrompt :: PromptLabel -> (String -> X ()) -> XPConfig -> X () +mkPassPrompt promptLabel passwordFunction xpconfig = do + passwords <- io (passwordStoreFolder >>= getPasswords) + mkXPrompt (Pass promptLabel) xpconfig (mkComplFunFromList passwords) passwordFunction + +-- | A prompt to retrieve a password from a given entry. +-- +passPrompt :: XPConfig -> X () +passPrompt = mkPassPrompt "Select password" selectPassword + +-- | A prompt to generate a password for a given entry. +-- This can be used to override an already stored entry. +-- (Beware that no confirmation is asked) +-- +passGeneratePrompt :: XPConfig -> X () +passGeneratePrompt = mkPassPrompt "Generate password" generatePassword + +-- | A prompt to remove a password for a given entry. +-- (Beware that no confirmation is asked) +-- +passRemovePrompt :: XPConfig -> X () +passRemovePrompt = mkPassPrompt "Remove password" removePassword + +-- | Select a password. +-- +selectPassword :: String -> X () +selectPassword passLabel = spawn $ "pass --clip " ++ passLabel + +-- | Generate a 30 characters password for a given entry. +-- If the entry already exists, it is updated with a new password. +-- +generatePassword :: String -> X () +generatePassword passLabel = spawn $ "pass generate --force " ++ passLabel ++ " 30" + +-- | Remove a password stored for a given entry. +-- +removePassword :: String -> X () +removePassword passLabel = spawn $ "pass rm --force " ++ passLabel + +-- | Retrieve the list of passwords from the password storage 'passwordStoreDir +-- +getPasswords :: String -> IO [String] +getPasswords passwordStoreDir = liftM (map takeBaseName) $ getDirectoryContents passwordStoreDir |