packages feed

pwstore-cli-0.1: tests/test.hs

{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import qualified Data.ByteString.Char8 as B
import Data.List (isPrefixOf)
import qualified Crypto.PasswordStore as P
import System.Process (readProcess)
import Test.HUnit
import Test.Hspec
import Test.Hspec.HUnit

-- | Runs the pwstore command with the given arguments and standard
-- input.
runPwstore :: [String] -> String -> IO String
runPwstore = readProcess "dist/build/pwstore/pwstore"

-- | A valid hunter2 hash.
hunter2hash :: String
hunter2hash = "sha256|12|YmBsCrO7FQIcrbMt23jnOA==|E8FZPaJnwa/dakuXOnz1A9OL2qj3nlzwDE02olsXMy0="

specs :: IO Specs
specs = describe "pwstore-cli"
  [ it "verifies hash with good password" $
    do actual <- runPwstore ["verify", hunter2hash] "hunter2"
       "good password\n" @=? actual

  , it "does not verify hash with bad password" $
    do actual <- runPwstore ["verify", hunter2hash] "badpass"
       "bad password\n" @=? actual

  , it "generates hash with given salt" $
    do actual <- runPwstore ["generate", "--salt=72cd18b5ebfe6e96"] "hunter2"
       "sha256|12|NzJjZDE4YjVlYmZlNmU5Ng==|M17VU2ciK8VaKyyDfVeGHS5eiLAuiStg/Y647B+Y4aE=\n" @=? actual

  , it "generates hash without given salt" $
    do hash' <- runPwstore ["generate"] "hunter2"
       let hash = init hash'    -- Remove trailing \n
       assertBool "" $ P.verifyPassword "hunter2" (B.pack hash)

  , it "generates hash with given strength" $
    do hash' <- runPwstore ["generate", "--strength=15"] "hunter2"
       let hash = init hash'    -- Remove trailing \n
       assertBool "" $ P.verifyPassword "hunter2" (B.pack hash)
       assertBool "" $ "sha256|15|" `isPrefixOf` hash

  , it "strengthens hashes" $
    do actual <- runPwstore ["strengthen", "-s15", hunter2hash] ""
       "sha256|15|YmBsCrO7FQIcrbMt23jnOA==|6ugvNWDF6KznLSsNC6AGXEObUalzx60UKauaivGkPkU=\n" @=? actual

  , it "does not weaken hashes" $
    do actual <- runPwstore ["strengthen", "-s11", hunter2hash] ""
       hunter2hash ++ "\n" @=? actual
  ]

main :: IO ()
main = hspecX specs