2 Module : Gargantext.Prelude.Crypto.Pass.User
4 Copyright : (c) CNRS, 2017-Present
5 License : Public Domain
6 Maintainer : team@gargantext.org
7 Stability : experimental
10 1) quick password generator for first invitations
11 2) Easy password manager for User (easy to memorize) (needs list of words)
16 module Gargantext.Prelude.Crypto.Pass.User
20 -- | 1) Quick password generator imports
21 import Data.Text (Text)
22 import Data.String (String)
24 import Control.Monad.Random
25 import Data.List hiding (sum)
27 -- | 2) Easy password manager imports
28 import Gargantext.Prelude
29 import Gargantext.Prelude.Utils (shuffle)
32 -- | 1) Quick password generator
33 -- | Inspired by Rosetta code
34 -- https://www.rosettacode.org/wiki/Password_generator#Haskell
35 gargPass :: MonadRandom m => m Text
36 gargPass = cs <$> gargPass' chars 33
38 chars = zipWith (\\) charSets visualySimilar
40 charSets = [ ['a'..'z']
43 , "!\"#$%&'()*+,-./:;<=>?@[]^_{|}~"
46 visualySimilar = ["l","IOSZ","012","!|.,'\""]
48 gargPass' :: MonadRandom m => [String] -> Int -> m String
49 gargPass' charSets n = do
50 parts <- getPartition n
51 chars <- zipWithM replicateM parts (uniform <$> charSets)
52 shuffle' (concat chars)
54 getPartition n' = adjust <$> replicateM (k-1) (getRandomR (1, n' `div` k))
56 adjust p = (n - sum p) : p
58 shuffle' :: (Eq a, MonadRandom m) => [a] -> m [a]
62 xs <- shuffle (delete x lst)
67 -- | 2) Easy password manager
68 -- TODO add this as parameter to gargantext.ini
69 gargPassUserEasy :: (Num a, Enum a, Integral a) => a -> [b] -> IO [b]
70 gargPassUserEasy n = gargPassUserEasy' (100 * fromIntegral n) n
72 gargPassUserEasy' :: (Num a, Enum a) => Int -> a -> [b] -> IO [b]
73 gargPassUserEasy' threshold size wlist
74 | length wlist > threshold = generatePassword size wlist
75 | otherwise = panic "List to short"
77 generatePassword :: (Num a, Enum a) => a -> [b] -> IO [b]
78 generatePassword size wlist = shuffle wlist
79 >>= \wlist' -> mapM (\_ -> getRandomElement wlist') [1..size]
81 getRandomIndex :: Foldable t => t a -> IO Int
82 getRandomIndex list = randomRIO (0, (length list - 1))
84 getRandomElement :: [b] -> IO b
85 getRandomElement list = do
86 index <- (getRandomIndex list)