passman/src/Password.hs

105 lines
2.9 KiB
Haskell
Raw Normal View History

2018-12-06 22:03:38 -05:00
{-|
Module: Password
Description: a simple password manager
Copyright: (C) 2018 Jonathan Lamothe
License: LGPLv3 (or later)
Maintainer: jlamothe1980@gmail.com
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
<https://www.gnu.org/licenses/>.
-}
2018-12-12 17:04:23 -05:00
{-# LANGUAGE TemplateHaskell #-}
2018-12-09 15:34:29 -05:00
module Password (
-- * Data Types
2018-12-12 17:04:23 -05:00
PWPolicy (..),
-- ** Lenses
-- $lenses
2018-12-12 17:38:10 -05:00
pwLength, pwUpper, pwLower, pwDigits, pwSpecial,
-- ** Default Instances
2018-12-12 18:41:34 -05:00
newPWPolicy,
-- * Functions
2018-12-13 13:23:56 -05:00
validatePWPolicy, applyPWPolicy
2018-12-09 15:34:29 -05:00
) where
2018-12-12 18:41:34 -05:00
import Control.Lens (makeLenses, (^.))
2018-12-13 13:23:56 -05:00
import Data.Char (isUpper, isLower, isDigit, isAlphaNum)
2018-12-12 18:41:34 -05:00
import Data.Maybe (fromMaybe)
2018-12-12 17:04:23 -05:00
2018-12-09 15:34:29 -05:00
-- | defines a password policy
data PWPolicy = PWPolicy
{ _pwLength :: Int
-- ^ password length
, _pwUpper :: Int
-- ^ the minimum number of upper case characters
, _pwLower :: Int
-- ^ the minimum number of lower case characters
, _pwDigits :: Int
-- ^ the minimum number of digits
, _pwSpecial :: Maybe Int
-- ^ the minimum number of non-alphanumeric characters (not allowed
-- if @"Nothing"@)
} deriving (Eq, Show)
2018-12-12 17:04:23 -05:00
-- $lenses The following functions are automatically generated by
-- @makeLenses@. See the
-- [lens](http://hackage.haskell.org/package/lens) package for further
-- details.
makeLenses ''PWPolicy
2018-12-12 17:38:10 -05:00
-- | default password policy
newPWPolicy :: PWPolicy
newPWPolicy = PWPolicy 16 0 0 0 (Just 0)
2018-12-12 18:41:34 -05:00
-- | validates a password policy
validatePWPolicy
:: PWPolicy
-- ^ the policy being validated
2018-12-13 11:15:26 -05:00
-> Bool
-- ^ indicates whether or not the policy is valid
2018-12-17 00:04:43 -05:00
validatePWPolicy x = and
2018-12-13 11:48:37 -05:00
[ needed <= x^.pwLength
, x^.pwLength >= 0
, x^.pwUpper >= 0
, x^.pwLower >= 0
, x^.pwDigits >= 0
, fromMaybe 0 (x^.pwSpecial) >= 0
] where
needed = x^.pwUpper + x^.pwLower + x^.pwDigits + special
special = fromMaybe 0 $ x^.pwSpecial
2018-12-12 18:41:34 -05:00
2018-12-13 13:23:56 -05:00
-- | checks whether or not a password meets a given password policy
applyPWPolicy
:: String
-- ^ the password
-> PWPolicy
-- ^ the policy
-> Bool
-- ^ @"True"@ if the password meets the policy, @"False"@ otherwise
2018-12-17 00:04:43 -05:00
applyPWPolicy pw policy = and
2018-12-13 13:23:56 -05:00
[ length pw <= policy^.pwLength
, length (filter isUpper pw) >= policy^.pwUpper
, length (filter isLower pw) >= policy^.pwLower
, length (filter isDigit pw) >= policy^.pwDigits
, length (filter (not . isAlphaNum) pw) >=
fromMaybe (succ $ policy^.pwLength) (policy^.pwSpecial)
, validatePWPolicy policy
]
2018-12-09 15:34:29 -05:00
--jl