{-| Module : Gargantext.Database.user Description : User Database management tools Copyright : (c) CNRS, 2017-Present License : AGPL + CECILL v3 Maintainer : team@gargantext.org Stability : experimental Portability : POSIX Functions to deal with users, database side. -} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE Arrows #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} module Gargantext.Database.Schema.User where import Control.Arrow (returnA) import Control.Lens.TH (makeLensesWith, abbreviatedFields) import Data.Eq(Eq(..)) import Data.List (find) import Data.Maybe (Maybe) import Data.Profunctor.Product.TH (makeAdaptorAndInstance) import Data.Text (Text) import Data.Time (UTCTime) import GHC.Show(Show(..)) import Gargantext.Core.Types.Individu (Username) import Gargantext.Database.Utils import Gargantext.Prelude import Opaleye ------------------------------------------------------------------------ type UserId = Int data UserLight = UserLight { userLight_id :: Int , userLight_username :: Text , userLight_email :: Text } deriving (Show) toUserLight :: User -> UserLight toUserLight (User id _ _ _ u _ _ e _ _ _ ) = UserLight id u e data UserPoly id pass llogin suser uname fname lname mail staff active djoined = User { user_id :: id , user_password :: pass , user_lastLogin :: llogin , user_isSuperUser :: suser , user_username :: uname , user_firstName :: fname , user_lastName :: lname , user_email :: mail , user_isStaff :: staff , user_isActive :: active , user_dateJoined :: djoined } deriving (Show) type UserWrite = UserPoly (Maybe (Column PGInt4)) (Column PGText) (Maybe (Column PGTimestamptz)) (Column PGBool) (Column PGText) (Column PGText) (Column PGText) (Column PGText) (Column PGBool) (Column PGBool) (Maybe (Column PGTimestamptz)) type UserRead = UserPoly (Column PGInt4) (Column PGText) (Column PGTimestamptz) (Column PGBool) (Column PGText) (Column PGText) (Column PGText) (Column PGText) (Column PGBool) (Column PGBool) (Column PGTimestamptz) type User = UserPoly Int Text (Maybe UTCTime) Bool Text Text Text Text Bool Bool UTCTime $(makeAdaptorAndInstance "pUser" ''UserPoly) $(makeLensesWith abbreviatedFields ''UserPoly) userTable :: Table UserWrite UserRead userTable = Table "auth_user" (pUser User { user_id = optional "id" , user_password = required "password" , user_lastLogin = optional "last_login" , user_isSuperUser = required "is_superuser" , user_username = required "username" , user_firstName = required "first_name" , user_lastName = required "last_name" , user_email = required "email" , user_isStaff = required "is_staff" , user_isActive = required "is_active" , user_dateJoined = optional "date_joined" } ) -- TODO: on conflict, nice message insertUsers :: [UserWrite] -> Cmd Int64 insertUsers us = mkCmd $ \c -> runInsertMany c userTable us gargantuaUser :: UserWrite gargantuaUser = User (Nothing) (pgStrictText "password") (Nothing) (pgBool True) (pgStrictText "gargantua") (pgStrictText "first_name") (pgStrictText "last_name") (pgStrictText "e@mail") (pgBool True) (pgBool True) (Nothing) simpleUser :: UserWrite simpleUser = User (Nothing) (pgStrictText "password") (Nothing) (pgBool False) (pgStrictText "user1") (pgStrictText "first_name") (pgStrictText "last_name") (pgStrictText "e@mail") (pgBool False) (pgBool True) (Nothing) ------------------------------------------------------------------ queryUserTable :: Query UserRead queryUserTable = queryTable userTable selectUsersLight :: Query UserRead selectUsersLight = proc () -> do row@(User i _p _ll _is _un _fn _ln _m _iff _ive _dj) <- queryUserTable -< () restrict -< i .== 1 --returnA -< User i p ll is un fn ln m iff ive dj returnA -< row ------------------------------------------------------------------ -- | Select User with some parameters -- Not optimized version userWith :: (Eq a1, Foldable t) => (a -> a1) -> a1 -> t a -> Maybe a userWith f t xs = find (\x -> f x == t) xs -- | Select User with Username userWithUsername :: Text -> [User] -> Maybe User userWithUsername t xs = userWith user_username t xs userWithId :: Int -> [User] -> Maybe User userWithId t xs = userWith user_id t xs userLightWithUsername :: Text -> [UserLight] -> Maybe UserLight userLightWithUsername t xs = userWith userLight_username t xs userLightWithId :: Int -> [UserLight] -> Maybe UserLight userLightWithId t xs = userWith userLight_id t xs instance QueryRunnerColumnDefault PGTimestamptz (Maybe UTCTime) where queryRunnerColumnDefault = fieldQueryRunnerColumn users :: Cmd err [User] users = runOpaQuery queryUserTable usersLight :: Cmd err [UserLight] usersLight = map toUserLight <$> users getUser :: Username -> Cmd err (Maybe UserLight) getUser u = userLightWithUsername u <$> usersLight