1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE DuplicateRecordFields #-}
4 module Gargantext.API.GraphQL.UserInfo where
7 import Data.Maybe (fromMaybe)
8 import Data.Morpheus.Types
16 import Data.Text (Text)
17 import qualified Data.Text as T
18 import Gargantext.API.Prelude (GargM, GargError)
19 import Gargantext.Core.Mail.Types (HasMail)
20 import Gargantext.Database.Admin.Types.Hyperdata
25 import Gargantext.Database.Admin.Types.Hyperdata.Contact
43 import Gargantext.Database.Prelude (HasConnectionPool, HasConfig)
44 import Gargantext.Database.Query.Table.Node.UpdateOpaleye (updateHyperdata)
45 import Gargantext.Database.Query.Table.User (getUsersWithHyperdata, getUsersWithNodeHyperdata, updateUserEmail)
46 import Gargantext.Database.Schema.User (UserLight(..))
47 import Gargantext.Database.Schema.Node (node_id, node_hyperdata, NodePoly (Node, _node_id))
48 import Gargantext.Prelude
49 import GHC.Generics (Generic)
50 import Gargantext.API.GraphQL.Utils (AuthStatus(Invalid, Valid), authUser)
51 import Gargantext.API.Admin.Types (HasSettings)
53 data UserInfo = UserInfo
57 , ui_title :: Maybe Text
58 , ui_source :: Maybe Text
59 , ui_cwFirstName :: Maybe Text
60 , ui_cwLastName :: Maybe Text
61 , ui_cwCity :: Maybe Text
62 , ui_cwCountry :: Maybe Text
63 , ui_cwOrganization :: [Text]
64 , ui_cwLabTeamDepts :: [Text]
65 , ui_cwOffice :: Maybe Text
66 , ui_cwRole :: Maybe Text
67 , ui_cwTouchPhone :: Maybe Text
68 , ui_cwTouchMail :: Maybe Text -- TODO: Remove. userLight_email should be used instead
69 , ui_cwDescription :: Maybe Text
71 deriving (Generic, Show)
72 instance GQLType UserInfo where
73 description = const $ Just "provides user info"
75 -- | Arguments to the "user info" query.
79 } deriving (Generic, GQLType)
81 -- | Arguments to the "user info" mutation,
86 , ui_username :: Maybe Text
87 , ui_email :: Maybe Text
88 , ui_title :: Maybe Text
89 , ui_source :: Maybe Text
90 , ui_cwFirstName :: Maybe Text
91 , ui_cwLastName :: Maybe Text
92 , ui_cwCity :: Maybe Text
93 , ui_cwCountry :: Maybe Text
94 , ui_cwOrganization :: Maybe [Text]
95 , ui_cwLabTeamDepts :: Maybe [Text]
96 , ui_cwOffice :: Maybe Text
97 , ui_cwRole :: Maybe Text
98 , ui_cwTouchPhone :: Maybe Text
99 , ui_cwTouchMail :: Maybe Text
100 , ui_cwDescription :: Maybe Text
101 } deriving (Generic, GQLType)
103 type GqlM e env = Resolver QUERY e (GargM env GargError)
104 type GqlM' e env err = ResolverM e (GargM env err) Int
106 -- | Function to resolve user from a query.
108 :: (HasConnectionPool env, HasConfig env, HasMail env)
109 => UserInfoArgs -> GqlM e env [UserInfo]
110 resolveUserInfos UserInfoArgs { user_id } = dbUsers user_id
112 -- | Mutation for user info
114 :: (HasConnectionPool env, HasConfig env, HasMail env, HasSettings env)
115 -- => UserInfoMArgs -> ResolverM e (GargM env err) Int
116 => UserInfoMArgs -> GqlM' e env err
117 updateUserInfo (UserInfoMArgs { ui_id, .. }) = do
118 -- lift $ printDebug "[updateUserInfo] ui_id" ui_id
119 users <- lift (getUsersWithNodeHyperdata ui_id)
121 [] -> panic $ "[updateUserInfo] User with id " <> (T.pack $ show ui_id) <> " doesn't exist."
122 ((UserLight { .. }, node_u):_) -> do
123 testAuthUser <- lift $ authUser (nId node_u) token
125 Invalid -> panic "[updateUserInfo] failed to validate user"
127 let u_hyperdata = node_u ^. node_hyperdata
128 -- lift $ printDebug "[updateUserInfo] u" u
129 let u_hyperdata' = uh ui_titleL ui_title $
130 uh ui_sourceL ui_source $
131 uh ui_cwFirstNameL ui_cwFirstName $
132 uh ui_cwLastNameL ui_cwLastName $
133 uh ui_cwCityL ui_cwCity $
134 uh ui_cwCountryL ui_cwCountry $
135 uh' ui_cwLabTeamDeptsL ui_cwLabTeamDepts $
136 uh' ui_cwOrganizationL ui_cwOrganization $
137 uh ui_cwOfficeL ui_cwOffice $
138 uh ui_cwRoleL ui_cwRole $
139 uh ui_cwTouchMailL ui_cwTouchMail $
140 uh ui_cwTouchPhoneL ui_cwTouchPhone $
141 uh ui_cwDescriptionL ui_cwDescription
143 -- NOTE: We have 1 username and 2 emails: userLight_email and ui_cwTouchMail
144 -- The userLight_email is more important: it is used for login and sending mail.
145 -- Therefore we update ui_cwTouchMail and userLight_email.
146 -- ui_cwTouchMail is to be removed in the future.
147 let u' = UserLight { userLight_email = fromMaybe userLight_email $ view ui_cwTouchMailL u_hyperdata'
149 -- lift $ printDebug "[updateUserInfo] with firstName" u_hyperdata'
150 _ <- lift $ updateHyperdata (node_u ^. node_id) u_hyperdata'
151 _ <- lift $ updateUserEmail u'
152 --let _newUser = toUser (u, u_hyperdata')
155 uh _ Nothing u_hyperdata = u_hyperdata
156 uh lens' (Just val) u_hyperdata = u_hyperdata & lens' .~ Just val
157 uh' _ Nothing u_hyperdata = u_hyperdata
158 uh' lens' (Just val) u_hyperdata = u_hyperdata & lens' .~ val
159 nId Node {_node_id} = _node_id
161 -- | Inner function to fetch the user from DB.
163 :: (HasConnectionPool env, HasConfig env, HasMail env)
164 => Int -> GqlM e env [UserInfo]
166 -- lift $ printDebug "[dbUsers]" user_id
167 -- user <- getUsersWithId user_id
168 -- hyperdata <- getUserHyperdata user_id
169 -- lift (map toUser <$> zip user hyperdata)
170 lift (map toUser <$> (getUsersWithHyperdata user_id))
172 toUser :: (UserLight, HyperdataUser) -> UserInfo
173 toUser (UserLight { .. }, u_hyperdata) =
174 UserInfo { ui_id = userLight_id
175 , ui_username = userLight_username
176 , ui_email = userLight_email
177 , ui_title = u_hyperdata ^. ui_titleL
178 , ui_source = u_hyperdata ^. ui_sourceL
179 , ui_cwFirstName = u_hyperdata ^. ui_cwFirstNameL
180 , ui_cwLastName = u_hyperdata ^. ui_cwLastNameL
181 , ui_cwCity = u_hyperdata ^. ui_cwCityL
182 , ui_cwCountry = u_hyperdata ^. ui_cwCountryL
183 , ui_cwLabTeamDepts = u_hyperdata ^. ui_cwLabTeamDeptsL
184 , ui_cwOrganization = u_hyperdata ^. ui_cwOrganizationL
185 , ui_cwOffice = u_hyperdata ^. ui_cwOfficeL
186 , ui_cwRole = u_hyperdata ^. ui_cwRoleL
187 --, ui_cwTouchMail = u_hyperdata ^. ui_cwTouchMailL
188 , ui_cwTouchMail = Just userLight_email
189 , ui_cwTouchPhone = u_hyperdata ^. ui_cwTouchPhoneL
190 , ui_cwDescription = u_hyperdata ^. ui_cwDescriptionL }
192 sharedL :: Traversal' HyperdataUser HyperdataContact
193 sharedL = hu_shared . _Just
194 ui_titleL :: Traversal' HyperdataUser (Maybe Text)
195 ui_titleL = sharedL . hc_title
196 ui_sourceL :: Traversal' HyperdataUser (Maybe Text)
197 ui_sourceL = sharedL . hc_source
198 contactWhoL :: Traversal' HyperdataUser ContactWho
199 contactWhoL = sharedL . hc_who . _Just
200 ui_cwFirstNameL :: Traversal' HyperdataUser (Maybe Text)
201 ui_cwFirstNameL = contactWhoL . cw_firstName
202 ui_cwLastNameL :: Traversal' HyperdataUser (Maybe Text)
203 ui_cwLastNameL = contactWhoL . cw_lastName
204 contactWhereL :: Traversal' HyperdataUser ContactWhere
205 contactWhereL = sharedL . hc_where . (ix 0)
206 ui_cwCityL :: Traversal' HyperdataUser (Maybe Text)
207 ui_cwCityL = contactWhereL . cw_city
208 ui_cwCountryL :: Traversal' HyperdataUser (Maybe Text)
209 ui_cwCountryL = contactWhereL . cw_country
210 ui_cwLabTeamDeptsL :: Traversal' HyperdataUser [Text]
211 ui_cwLabTeamDeptsL = hu_shared . _Just . (hc_where . (ix 0) . cw_labTeamDepts)
212 ui_cwOrganizationL :: Traversal' HyperdataUser [Text]
213 ui_cwOrganizationL = hu_shared . _Just . (hc_where . (ix 0) . cw_organization)
214 ui_cwOfficeL :: Traversal' HyperdataUser (Maybe Text)
215 ui_cwOfficeL = contactWhereL . cw_office
216 ui_cwRoleL :: Traversal' HyperdataUser (Maybe Text)
217 ui_cwRoleL = contactWhereL . cw_role
218 ui_cwTouchMailL :: Traversal' HyperdataUser (Maybe Text)
219 ui_cwTouchMailL = hu_shared . _Just . (hc_where . (ix 0) . cw_touch . _Just . ct_mail)
220 --ui_cwTouchMailL = contactWhereL . cw_touch . _Just . ct_mail
221 ui_cwTouchPhoneL :: Traversal' HyperdataUser (Maybe Text)
222 ui_cwTouchPhoneL = hu_shared . _Just . (hc_where . (ix 0) . cw_touch . _Just . ct_phone)
223 --ui_cwTouchPhoneL = contactWhereL . cw_touch . _Just . ct_phone
224 ui_cwDescriptionL :: Traversal' HyperdataUser (Maybe Text)
225 ui_cwDescriptionL = contactWhoL . cw_description