{-|
Module      : Gargantext.Core.Types.Individu
Description : Short description
Copyright   : (c) CNRS, 2017-Present
License     : AGPL + CECILL v3
Maintainer  : team@gargantext.org
Stability   : experimental
Portability : POSIX

Individu defintions
-}



module Gargantext.Core.Types.Individu
  where

import Data.Aeson
import Control.Monad.IO.Class (MonadIO)
import GHC.Generics (Generic)
import Data.Swagger
import Data.Text (Text, pack, reverse)
import Gargantext.Database.Admin.Types.Node (NodeId, UserId)
import Gargantext.Prelude hiding (reverse)
import qualified Gargantext.Prelude.Crypto.Auth as Auth

-- FIXME UserName used twice
data User = UserDBId UserId | UserName Text | RootId NodeId | UserPublic
  deriving (User -> User -> Bool
(User -> User -> Bool) -> (User -> User -> Bool) -> Eq User
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: User -> User -> Bool
$c/= :: User -> User -> Bool
== :: User -> User -> Bool
$c== :: User -> User -> Bool
Eq)

type Username = Text

type HashPassword    = Auth.PasswordHash Auth.Argon2
newtype GargPassword = GargPassword Text
  deriving ((forall x. GargPassword -> Rep GargPassword x)
-> (forall x. Rep GargPassword x -> GargPassword)
-> Generic GargPassword
forall x. Rep GargPassword x -> GargPassword
forall x. GargPassword -> Rep GargPassword x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GargPassword x -> GargPassword
$cfrom :: forall x. GargPassword -> Rep GargPassword x
Generic)

instance Show GargPassword where
  show :: GargPassword -> String
show (GargPassword Text
_) = String
"*GargPassword*"

instance ToJSON GargPassword
instance FromJSON GargPassword

instance ToSchema GargPassword
type Email          = Text
type UsernameMaster = Username
type UsernameSimple = Username

data NewUser a = NewUser { NewUser a -> Text
_nu_username :: Username
                         , NewUser a -> Text
_nu_email    :: Email
                         , NewUser a -> a
_nu_password :: a
                         }
  deriving (Int -> NewUser a -> ShowS
[NewUser a] -> ShowS
NewUser a -> String
(Int -> NewUser a -> ShowS)
-> (NewUser a -> String)
-> ([NewUser a] -> ShowS)
-> Show (NewUser a)
forall a. Show a => Int -> NewUser a -> ShowS
forall a. Show a => [NewUser a] -> ShowS
forall a. Show a => NewUser a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NewUser a] -> ShowS
$cshowList :: forall a. Show a => [NewUser a] -> ShowS
show :: NewUser a -> String
$cshow :: forall a. Show a => NewUser a -> String
showsPrec :: Int -> NewUser a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> NewUser a -> ShowS
Show)

arbitraryUsername :: [Username]
arbitraryUsername :: [Text]
arbitraryUsername = {- ["gargantua"] <> -} [Text]
users
  where
    users :: [Text]
users = (Text -> Int -> Text) -> [Text] -> [Int] -> [Text]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Text
a Int
b -> Text
a Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
pack (String -> Text) -> (Int -> String) -> Int -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show) Int
b) 
                    (Text -> [Text]
forall a. a -> [a]
repeat Text
"user") ([Int
1..Int
20]::[Int])

arbitraryPassword :: [GargPassword]
arbitraryPassword :: [GargPassword]
arbitraryPassword = (Text -> GargPassword) -> [Text] -> [GargPassword]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (\Text
u -> Text -> GargPassword
GargPassword (Text -> Text
reverse Text
u)) [Text]
arbitraryUsername

-----------------------------------------------------------
toUserHash :: MonadIO m
         =>    NewUser GargPassword
         -> m (NewUser HashPassword)
toUserHash :: NewUser GargPassword -> m (NewUser HashPassword)
toUserHash (NewUser Text
u Text
m (GargPassword Text
p)) = do
  HashPassword
h <- Text -> m HashPassword
forall (m :: * -> *). MonadIO m => Text -> m HashPassword
Auth.createPasswordHash Text
p
  NewUser HashPassword -> m (NewUser HashPassword)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NewUser HashPassword -> m (NewUser HashPassword))
-> NewUser HashPassword -> m (NewUser HashPassword)
forall a b. (a -> b) -> a -> b
$ Text -> Text -> HashPassword -> NewUser HashPassword
forall a. Text -> Text -> a -> NewUser a
NewUser Text
u Text
m HashPassword
h

-- TODO remove
arbitraryUsersHash :: MonadIO m
                  => m [NewUser HashPassword]
arbitraryUsersHash :: m [NewUser HashPassword]
arbitraryUsersHash = (NewUser GargPassword -> m (NewUser HashPassword))
-> [NewUser GargPassword] -> m [NewUser HashPassword]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM NewUser GargPassword -> m (NewUser HashPassword)
forall (m :: * -> *).
MonadIO m =>
NewUser GargPassword -> m (NewUser HashPassword)
toUserHash [NewUser GargPassword]
arbitraryNewUsers

arbitraryNewUsers :: [NewUser GargPassword]
arbitraryNewUsers :: [NewUser GargPassword]
arbitraryNewUsers = (Text -> NewUser GargPassword) -> [Text] -> [NewUser GargPassword]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (\Text
u -> Text -> Text -> GargPassword -> NewUser GargPassword
forall a. Text -> Text -> a -> NewUser a
NewUser Text
u (Text
u Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"@gargantext.org") (Text -> GargPassword
GargPassword (Text -> GargPassword) -> Text -> GargPassword
forall a b. (a -> b) -> a -> b
$ Text -> Text
reverse Text
u))
                     [Text]
arbitraryUsername