diff --git a/src/Password.hs b/src/Password.hs index b251722..7f09e4f 100644 --- a/src/Password.hs +++ b/src/Password.hs @@ -36,7 +36,12 @@ module Password ( -- ** Default Instances newPWDatabase, newPWData, newPWPolicy, newPWSalt, -- ** Validations - validatePWDatabase, validatePWData, validatePWPolicy + validatePWDatabase, validatePWData, validatePWPolicy, + -- * Functions + -- ** Password Generator + pwGenerate, + -- ** Password Checkers + pwCountUpper, pwCountLower, pwCountDigits, pwCountSpecial ) where import Control.Lens (makeLenses, (^.)) @@ -148,4 +153,47 @@ validatePWPolicy x = and needed = x^.pwUpper + x^.pwLower + x^.pwDigits + special special = fromMaybe 0 $ x^.pwSpecial +-- | generates a password +pwGenerate + :: String + -- ^ the master password + -> PWData + -- ^ the password parameters + -> Maybe String + -- ^ the resulting password, if possible; @"Nothing"@ if the data is + -- invalid +pwGenerate = undefined + +-- | counts lower case characters in a password +pwCountLower + :: String + -- ^ the password + -> Int + -- ^ the count +pwCountLower = undefined + +-- | counts digits in a password +pwCountDigits + :: String + -- ^ the password + -> Int + -- ^ the count +pwCountDigits = undefined + +-- | counts special characters in a password +pwCountSpecial + :: String + -- ^ the password + -> Int + -- ^ the count +pwCountSpecial = undefined + +-- | counts upper case characters in a password +pwCountUpper + :: String + -- ^ the password + -> Int + -- ^ the count +pwCountUpper = undefined + --jl diff --git a/test/Spec.hs b/test/Spec.hs index 19fbb28..a75142b 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -30,6 +30,7 @@ import qualified Spec.NewPWData as NewPWData import qualified Spec.NewPWDatabase as NewPWDatabase import qualified Spec.NewPWPolicy as NewPWPolicy import qualified Spec.NewPWSalt as NewPWSalt +import qualified Spec.PWGenerate as PWGenerate import qualified Spec.ValidatePWData as ValidatePWData import qualified Spec.ValidatePWDatabase as ValidatePWDatabase import qualified Spec.ValidatePWPolicy as ValidatePWPolicy @@ -44,9 +45,10 @@ tests = TestList , NewPWData.tests , NewPWPolicy.tests , NewPWSalt.tests - , ValidatePWPolicy.tests - , ValidatePWData.tests , ValidatePWDatabase.tests + , ValidatePWData.tests + , ValidatePWPolicy.tests + --, PWGenerate.tests ] --jl diff --git a/test/Spec/PWGenerate.hs b/test/Spec/PWGenerate.hs new file mode 100644 index 0000000..90e0096 --- /dev/null +++ b/test/Spec/PWGenerate.hs @@ -0,0 +1,99 @@ +{- + +passman +Copyright (C) 2018 Jonathan Lamothe + + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this program. If not, see +. + +-} + +module Spec.PWGenerate (tests) where + +import Control.Lens (set, (^.)) +import Data.Maybe (fromJust) +import System.Random (mkStdGen) +import Test.HUnit + (Test (..) + , assertBool + , assertEqual + , assertFailure + , (~?=) + ) + +import Password + +tests = TestLabel "pwGenerate" $ TestList + [ defaultData + , invalidPolicy + , constraints + , noSpecial + , differentMaster + ] + +defaultData = TestLabel "default data" $ TestCase $ + case pwGenerate "foo" validData of + Nothing -> assertFailure "no password generated" + Just x -> assertEqual "incorrect password length" + (validData^.pwPolicy.pwLength) (length x) + +invalidPolicy = TestLabel "invalid policy" $ + pwGenerate "foo" invalidPolicy' ~?= Nothing + +constraints = TestLabel "strict constraints" $ TestCase $ + case pwGenerate "foo" constraints' of + Nothing -> assertFailure "no password generated" + Just x -> do + assertEqual "incorrect password length" + (constraints'^.pwPolicy.pwLength) (length x) + assertEqual "incorrect number of upper case" + (constraints'^.pwPolicy.pwUpper) (pwCountUpper x) + assertEqual "incorrect number of lower case" + (constraints'^.pwPolicy.pwLower) (pwCountLower x) + assertEqual "incorrect number of digita" + (constraints'^.pwPolicy.pwDigits) (pwCountDigits x) + assertEqual "incorrect number of special characters" + (fromJust $ constraints'^.pwPolicy.pwSpecial) (pwCountSpecial x) + +noSpecial = TestLabel "no special chars" $ TestCase $ + case pwGenerate "foo" noSpecial' of + Nothing -> assertFailure "no password generated" + Just x -> do + assertEqual "incorrect password length" + (noSpecial'^.pwPolicy.pwLength) (length x) + assertEqual "special characters found" 0 $ pwCountSpecial x + +differentMaster = TestLabel "different master passwords" $ TestCase $ + assertBool "passwords match" $ + fromJust (pwGenerate "foo" validData) /= + fromJust (pwGenerate "bar" validData) + +(validData, _) = newPWData g + +invalidPolicy' = set (pwPolicy.pwLength) (-1) validData + +constraints' = set (pwPolicy.pwUpper) 4 $ + set (pwPolicy.pwLower) 4 $ + set (pwPolicy.pwDigits) 4 $ + set (pwPolicy.pwSpecial) (Just 4) + validData + +noSpecial' = set (pwPolicy.pwLength) 256 $ + set (pwPolicy.pwSpecial) Nothing + validData + +g = mkStdGen 1 + +--jl