summaryrefslogtreecommitdiff
path: root/contrib/oisafe2pstore
diff options
context:
space:
mode:
authorMohamed Zenadi <zeapo@users.noreply.github.com>2016-07-30 19:23:58 +0100
committerGitHub <noreply@github.com>2016-07-30 19:23:58 +0100
commit113725e3ab94fa72824b81595fb3a8d64a636e6e (patch)
tree2978b830c330773eac904f3dda8b68c17e9464ba /contrib/oisafe2pstore
parent8be387c5a72dddd80d9ecfd93e41da0d8f22381f (diff)
parent99934d35b99fc2188c962a53cf7bc0f8b83fe58f (diff)
Merge pull request #201 from crosser/oisafe2pstore
oisafe2pstore.hs: script to migrate from OI Safe
Diffstat (limited to 'contrib/oisafe2pstore')
-rw-r--r--contrib/oisafe2pstore/oisafe2pstore.hs85
1 files changed, 85 insertions, 0 deletions
diff --git a/contrib/oisafe2pstore/oisafe2pstore.hs b/contrib/oisafe2pstore/oisafe2pstore.hs
new file mode 100644
index 00000000..0417fc0a
--- /dev/null
+++ b/contrib/oisafe2pstore/oisafe2pstore.hs
@@ -0,0 +1,85 @@
+{-
+ oisafe2psore - Quick and dirty script to convert OI Safe export CSV
+ into the password-store tree format.
+
+ Copyright 2016 Eugene Crosser
+
+ License: BSD, Apache or GPLv3 - chose whatever suits you.
+
+ You will need to adjust paths to the GnuPG program and the CSV
+ file produced by OI Safe. Also fill in the PGP key I.D.
+ Description becomes the file name. '*' in the Description is
+ converted to '+', '/' - to '-'. If this is not sufficient,
+ adjust the function `sanitize`.
+-}
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+--import Data.Text hiding (head, tail, reverse, length, map)
+import Control.Monad
+import Text.CSV
+import System.Directory
+import System.Process
+import System.Exit
+
+--gpg = "/usr/local/bin/gpg2"
+gpg = "/usr/bin/gpg2"
+
+keyid = "01234567" -- !!!Fill in the real I.D. here!!!
+
+data Entry = Entry { fCategory :: String
+ , fDescription :: String
+ , fWebsite :: String
+ , fUsername :: String
+ , fPassword :: String
+ , fNotes :: String
+ };
+
+instance Show Entry where
+ show e = fPassword e
+ ++ nonempty "User" (fUsername e)
+ ++ nonempty "Website" (fWebsite e)
+ ++ nonempty "Notes" (fNotes e)
+ where
+ nonempty :: String -> String -> String
+ nonempty l v = if length v > 0 then "\n" ++ l ++ ": " ++ v else ""
+
+pathOf e = (sanitize (fCategory e), sanitize (fDescription e))
+
+sanitize = map substsafe
+ where
+ substsafe '/' = '-'
+ substsafe '*' = '+'
+ substsafe x = x
+
+record2entry :: Record -> Maybe Entry
+record2entry [fCat,fDesc,fWeb,fUser,fPass,fNote,_] =
+ Just (Entry { fCategory = fCat
+ , fDescription = fDesc
+ , fWebsite = fWeb
+ , fUsername = fUser
+ , fPassword = fPass
+ , fNotes = fNote
+ })
+record2entry _ = Nothing
+
+main = parseCSVFromFile "oisafe.csv"
+ >>= either (error . show) ((mapM_ makeEntry) . tail)
+
+makeEntry :: Record -> IO ()
+makeEntry = buildFile . record2entry
+
+buildFile :: Maybe Entry -> IO ()
+buildFile Nothing = return ()
+buildFile (Just e) = do
+ let
+ (sub, file) = pathOf e
+ dir = "password-store/" ++ sub
+ path = dir ++ "/" ++ file ++ ".gpg"
+ cont = show e
+ (rc, stdout, stderr) <- readProcessWithExitCode gpg ["-ae", "-r", keyid] cont
+ when (rc /= ExitSuccess) $ error $ "gpg rc " ++ (show rc) ++ " message " ++ stderr
+ createDirectoryIfMissing True dir
+ writeFile path stdout