Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Christian Merten
haskell-gargantext
Commits
5d61a290
Verified
Commit
5d61a290
authored
Aug 22, 2024
by
Przemyslaw Kaminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[worker] async worker implemented for ForgotPassword
parent
dd22584b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
107 additions
and
59 deletions
+107
-59
gargantext.cabal
gargantext.cabal
+1
-0
Auth.hs
src/Gargantext/API/Admin/Auth.hs
+11
-7
Types.hs
src/Gargantext/API/Admin/Auth/Types.hs
+3
-3
Worker.hs
src/Gargantext/Core/Worker.hs
+34
-20
Jobs.hs
src/Gargantext/Core/Worker/Jobs.hs
+14
-26
Types.hs
src/Gargantext/Core/Worker/Jobs/Types.hs
+37
-0
Root.hs
src/Gargantext/Database/Query/Tree/Root.hs
+1
-1
Worker.hs
test/Test/Core/Worker.hs
+6
-2
No files found.
gargantext.cabal
View file @
5d61a290
...
@@ -232,6 +232,7 @@ library
...
@@ -232,6 +232,7 @@ library
Gargantext.Core.Viz.Types
Gargantext.Core.Viz.Types
Gargantext.Core.Worker
Gargantext.Core.Worker
Gargantext.Core.Worker.Jobs
Gargantext.Core.Worker.Jobs
Gargantext.Core.Worker.Jobs.Types
Gargantext.Core.Worker.TOML
Gargantext.Core.Worker.TOML
Gargantext.Database.Action.Flow
Gargantext.Database.Action.Flow
Gargantext.Database.Action.Flow.Types
Gargantext.Database.Action.Flow.Types
...
...
src/Gargantext/API/Admin/Auth.hs
View file @
5d61a290
...
@@ -40,11 +40,12 @@ module Gargantext.API.Admin.Auth
...
@@ -40,11 +40,12 @@ module Gargantext.API.Admin.Auth
,
withNamedAccess
,
withNamedAccess
,
ForgotPasswordAsyncParams
,
ForgotPasswordAsyncParams
,
forgotUserPassword
)
)
where
where
import
Control.Lens
(
view
,
(
#
))
import
Control.Lens
(
view
,
(
#
))
import
Data.Text
qualified
as
Text
import
Data.Text.Lazy.Encoding
qualified
as
LE
import
Data.Text.Lazy.Encoding
qualified
as
LE
import
Data.UUID
(
UUID
,
fromText
,
toText
)
import
Data.UUID
(
UUID
,
fromText
,
toText
)
import
Data.UUID.V4
(
nextRandom
)
import
Data.UUID.V4
(
nextRandom
)
...
@@ -58,6 +59,8 @@ import Gargantext.API.Prelude (authenticationError, HasServerError, GargServerC,
...
@@ -58,6 +59,8 @@ import Gargantext.API.Prelude (authenticationError, HasServerError, GargServerC,
import
Gargantext.Core.Mail
(
MailModel
(
..
),
mail
)
import
Gargantext.Core.Mail
(
MailModel
(
..
),
mail
)
import
Gargantext.Core.Mail.Types
(
mailSettings
)
import
Gargantext.Core.Mail.Types
(
mailSettings
)
import
Gargantext.Core.Types.Individu
(
User
(
..
),
Username
,
GargPassword
(
..
))
import
Gargantext.Core.Types.Individu
(
User
(
..
),
Username
,
GargPassword
(
..
))
import
Gargantext.Core.Worker.Jobs
qualified
as
Jobs
import
Gargantext.Core.Worker.Jobs.Types
qualified
as
Jobs
import
Gargantext.Database.Action.Flow.Types
(
FlowCmdM
)
import
Gargantext.Database.Action.Flow.Types
(
FlowCmdM
)
import
Gargantext.Database.Action.User.New
(
guessUserName
)
import
Gargantext.Database.Action.User.New
(
guessUserName
)
import
Gargantext.Database.Admin.Types.Node
(
NodeId
(
..
))
import
Gargantext.Database.Admin.Types.Node
(
NodeId
(
..
))
...
@@ -238,13 +241,14 @@ forgotPassword = Named.ForgotPasswordAPI
...
@@ -238,13 +241,14 @@ forgotPassword = Named.ForgotPasswordAPI
,
forgotPasswordGetEp
=
forgotPasswordGet
,
forgotPasswordGetEp
=
forgotPasswordGet
}
}
forgotPasswordPost
::
(
CmdCommon
env
)
forgotPasswordPost
::
(
CmdCommon
env
,
HasSettings
env
)
=>
ForgotPasswordRequest
->
Cmd'
env
err
ForgotPasswordResponse
=>
ForgotPasswordRequest
->
Cmd'
env
err
ForgotPasswordResponse
forgotPasswordPost
(
ForgotPasswordRequest
email
)
=
do
forgotPasswordPost
(
ForgotPasswordRequest
email
)
=
do
us
<-
getUsersWithEmail
(
Text
.
toLower
email
)
Jobs
.
sendJob
$
Jobs
.
ForgotPassword
{
Jobs
.
_fp_email
=
email
}
case
us
of
-- us <- getUsersWithEmail (Text.toLower email)
[
u
]
->
forgotUserPassword
u
-- case us of
_
->
pure
()
-- [u] -> forgotUserPassword u
-- _ -> pure ()
-- NOTE Sending anything else here could leak information about
-- NOTE Sending anything else here could leak information about
-- users' emails
-- users' emails
...
@@ -329,7 +333,7 @@ forgotPasswordAsync :: Named.ForgotPasswordAsyncAPI (AsServerT (GargM Env Backen
...
@@ -329,7 +333,7 @@ forgotPasswordAsync :: Named.ForgotPasswordAsyncAPI (AsServerT (GargM Env Backen
forgotPasswordAsync
=
Named
.
ForgotPasswordAsyncAPI
$
AsyncJobs
$
forgotPasswordAsync
=
Named
.
ForgotPasswordAsyncAPI
$
AsyncJobs
$
serveJobsAPI
ForgotPasswordJob
$
\
jHandle
p
->
forgotPasswordAsync'
p
jHandle
serveJobsAPI
ForgotPasswordJob
$
\
jHandle
p
->
forgotPasswordAsync'
p
jHandle
forgotPasswordAsync'
::
(
FlowCmdM
env
err
m
,
MonadJobStatus
m
)
forgotPasswordAsync'
::
(
FlowCmdM
env
err
m
,
MonadJobStatus
m
,
HasSettings
env
)
=>
ForgotPasswordAsyncParams
=>
ForgotPasswordAsyncParams
->
JobHandle
m
->
JobHandle
m
->
m
()
->
m
()
...
...
src/Gargantext/API/Admin/Auth/Types.hs
View file @
5d61a290
...
@@ -118,17 +118,17 @@ type Email = Text
...
@@ -118,17 +118,17 @@ type Email = Text
type
Password
=
Text
type
Password
=
Text
data
ForgotPasswordRequest
=
ForgotPasswordRequest
{
_fpReq_email
::
Email
}
data
ForgotPasswordRequest
=
ForgotPasswordRequest
{
_fpReq_email
::
Email
}
deriving
(
Generic
)
deriving
(
Generic
)
instance
ToSchema
ForgotPasswordRequest
where
instance
ToSchema
ForgotPasswordRequest
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_fpReq_"
)
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_fpReq_"
)
data
ForgotPasswordResponse
=
ForgotPasswordResponse
{
_fpRes_status
::
Text
}
data
ForgotPasswordResponse
=
ForgotPasswordResponse
{
_fpRes_status
::
Text
}
deriving
(
Generic
)
deriving
(
Generic
)
instance
ToSchema
ForgotPasswordResponse
where
instance
ToSchema
ForgotPasswordResponse
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_fpRes_"
)
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_fpRes_"
)
data
ForgotPasswordGet
=
ForgotPasswordGet
{
_fpGet_password
::
Password
}
data
ForgotPasswordGet
=
ForgotPasswordGet
{
_fpGet_password
::
Password
}
deriving
(
Generic
)
deriving
(
Generic
)
instance
ToSchema
ForgotPasswordGet
where
instance
ToSchema
ForgotPasswordGet
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_fpGet_"
)
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_fpGet_"
)
...
...
src/Gargantext/Core/Worker.hs
View file @
5d61a290
...
@@ -19,38 +19,52 @@ import Async.Worker qualified as Worker
...
@@ -19,38 +19,52 @@ import Async.Worker qualified as Worker
import
Async.Worker.Types
qualified
as
Worker
import
Async.Worker.Types
qualified
as
Worker
import
Async.Worker.Types
(
HasWorkerBroker
)
import
Async.Worker.Types
(
HasWorkerBroker
)
import
Data.Text
qualified
as
T
import
Data.Text
qualified
as
T
import
Database.Redis
qualified
as
Redis
import
Gargantext.API.Admin.Auth
(
forgotUserPassword
)
import
Gargantext.API.Admin.Types
(
HasSettings
)
import
Gargantext.Core.Worker.Jobs
import
Gargantext.Core.Worker.Jobs
import
Gargantext.Core.Worker.TOML
(
WorkerDefinition
(
..
))
import
Gargantext.Core.Worker.Jobs.Types
(
Job
(
..
))
import
Gargantext.Core.Worker.TOML
(
WorkerDefinition
(
..
),
wdToRedisConnectInfo
)
import
Gargantext.Database.Prelude
(
CmdCommon
)
import
Gargantext.Database.Query.Table.User
(
getUsersWithEmail
)
import
Gargantext.Prelude
import
Gargantext.Prelude
withRedisWorker
::
(
HasWorkerBroker
RedisBroker
Job
)
withRedisWorker
::
(
HasWorkerBroker
RedisBroker
Job
,
HasSettings
env
,
CmdCommon
env
)
=>
Redis
.
ConnectInfo
=>
env
->
WorkerDefinition
->
WorkerDefinition
->
(
Async
()
->
Worker
.
State
RedisBroker
Job
->
IO
()
)
->
(
Async
()
->
Worker
.
State
RedisBroker
Job
->
IO
()
)
->
IO
()
->
IO
()
withRedisWorker
connInfo
(
WorkerDefinition
{
..
})
cb
=
do
withRedisWorker
env
wd
@
(
WorkerDefinition
{
..
})
cb
=
do
broker
<-
initializeRedisBroker
connInfo
case
wdToRedisConnectInfo
wd
of
Nothing
->
panicTrace
$
"worker definition: could not create redis conn info"
Just
connInfo
->
do
broker
<-
initializeRedisBroker
connInfo
let
state'
=
Worker
.
State
{
broker
,
queueName
=
_wdQueue
,
name
=
T
.
unpack
_wdName
,
performAction
=
performAction
env
,
onMessageReceived
=
Nothing
,
onJobFinish
=
Nothing
,
onJobTimeout
=
Nothing
,
onJobError
=
Nothing
}
withAsync
(
Worker
.
run
state'
)
(
\
a
->
cb
a
state'
)
let
state'
=
Worker
.
State
{
broker
,
queueName
=
_wdQueue
,
name
=
T
.
unpack
_wdName
,
performAction
,
onMessageReceived
=
Nothing
,
onJobFinish
=
Nothing
,
onJobTimeout
=
Nothing
,
onJobError
=
Nothing
}
withAsync
(
Worker
.
run
state'
)
(
\
a
->
cb
a
state'
)
performAction
::
(
HasWorkerBroker
b
Job
,
HasSettings
env
,
CmdCommon
env
)
=>
env
->
Worker
.
State
b
Job
performAction
::
(
HasWorkerBroker
b
Job
)
=>
Worker
.
State
b
Job
->
BrokerMessage
b
(
Worker
.
Job
Job
)
->
BrokerMessage
b
(
Worker
.
Job
Job
)
->
IO
()
->
IO
()
performAction
_state
bm
=
do
performAction
env
_state
bm
=
do
let
job'
=
toA
$
getMessage
bm
let
job'
=
toA
$
getMessage
bm
case
Worker
.
job
job'
of
case
Worker
.
job
job'
of
Ping
->
putStrLn
(
"ping"
::
Text
)
Ping
->
putStrLn
(
"ping"
::
Text
)
ForgotPassword
{
_fp_email
}
->
flip
runReaderT
env
$
do
liftBase
$
putStrLn
(
"forgot password: "
<>
_fp_email
)
us
<-
getUsersWithEmail
(
T
.
toLower
_fp_email
)
case
us
of
[
u
]
->
forgotUserPassword
u
_
->
pure
()
src/Gargantext/Core/Worker/Jobs.hs
View file @
5d61a290
...
@@ -19,28 +19,14 @@ import Async.Worker qualified as Worker
...
@@ -19,28 +19,14 @@ import Async.Worker qualified as Worker
import
Async.Worker.Types
qualified
as
Worker
import
Async.Worker.Types
qualified
as
Worker
import
Async.Worker.Types
(
HasWorkerBroker
)
import
Async.Worker.Types
(
HasWorkerBroker
)
import
Control.Lens
(
view
)
import
Control.Lens
(
view
)
import
Data.Aeson
((
.:
),
(
.=
),
object
,
withObject
)
import
Data.Aeson.Types
(
prependFailure
,
typeMismatch
)
import
Database.Redis
qualified
as
Redis
import
Database.Redis
qualified
as
Redis
import
Gargantext.API.Admin.Types
(
HasSettings
,
settings
,
workerSettings
)
import
Gargantext.API.Admin.Types
(
HasSettings
,
settings
,
workerSettings
)
import
Gargantext.Core.Worker.TOML
(
findDefinitionByName
,
WorkerDefinition
(
..
))
import
Gargantext.Core.Worker.Jobs.Types
(
Job
(
..
))
import
Gargantext.Core.Worker.TOML
(
WorkerSettings
(
..
),
WorkerDefinition
(
..
),
wdToRedisConnectInfo
)
import
Gargantext.Database.Prelude
(
Cmd
'
)
import
Gargantext.Database.Prelude
(
Cmd
'
)
import
Gargantext.Prelude
import
Gargantext.Prelude
data
Job
=
Ping
deriving
(
Show
,
Eq
)
instance
FromJSON
Job
where
parseJSON
=
withObject
"Job"
$
\
o
->
do
type_
<-
o
.:
"type"
case
type_
of
"Ping"
->
return
Ping
s
->
prependFailure
"parsing job type failed, "
(
typeMismatch
"type"
s
)
instance
ToJSON
Job
where
toJSON
Ping
=
object
[(
"type"
.=
(
"Ping"
::
Text
))]
initializeRedisBroker
::
(
HasWorkerBroker
RedisBroker
Job
)
initializeRedisBroker
::
(
HasWorkerBroker
RedisBroker
Job
)
=>
Redis
.
ConnectInfo
=>
Redis
.
ConnectInfo
->
IO
(
Broker
RedisBroker
(
Worker
.
Job
Job
))
->
IO
(
Broker
RedisBroker
(
Worker
.
Job
Job
))
...
@@ -51,17 +37,19 @@ initializeRedisBroker connInfo = do
...
@@ -51,17 +37,19 @@ initializeRedisBroker connInfo = do
sendJob
::
(
HasWorkerBroker
RedisBroker
Job
,
HasSettings
env
)
sendJob
::
(
HasWorkerBroker
RedisBroker
Job
,
HasSettings
env
)
=>
Redis
.
ConnectInfo
=>
Job
->
Text
->
Job
->
Cmd'
env
err
()
->
Cmd'
env
err
()
sendJob
connInfo
workerName
job
=
do
sendJob
job
=
do
ws
<-
view
$
settings
.
workerSettings
ws
<-
view
$
settings
.
workerSettings
let
mWd
=
findDefinitionByName
ws
workerName
-- TODO Try to guess which worker should get this job
-- let mWd = findDefinitionByName ws workerName
let
mWd
=
head
$
_wsDefinitions
ws
case
mWd
of
case
mWd
of
Nothing
->
panicTrace
$
"worker definition not found
for "
<>
workerName
Nothing
->
panicTrace
$
"worker definition not found
"
Just
wd
->
liftBase
$
do
Just
wd
->
liftBase
$
do
b
<-
initializeRedisBroker
connInfo
case
wdToRedisConnectInfo
wd
of
let
queueName
=
_wdQueue
wd
Nothing
->
panicTrace
$
"worker definition: could not create redis conn info"
_
<-
Worker
.
sendJob'
$
Worker
.
mkDefaultSendJob'
b
queueName
job
Just
connInfo
->
do
pure
()
b
<-
initializeRedisBroker
connInfo
let
queueName
=
_wdQueue
wd
void
$
Worker
.
sendJob'
$
Worker
.
mkDefaultSendJob'
b
queueName
job
src/Gargantext/Core/Worker/Jobs/Types.hs
0 → 100644
View file @
5d61a290
{-|
Module : Gargantext.Core.Worker.Jobs.Types
Description : Worker job definitions
Copyright : (c) CNRS, 2024
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-}
module
Gargantext.Core.Worker.Jobs.Types
where
import
Data.Aeson
((
.:
),
(
.=
),
object
,
withObject
)
import
Data.Aeson.Types
(
prependFailure
,
typeMismatch
)
import
Gargantext.Prelude
data
Job
=
Ping
|
ForgotPassword
{
_fp_email
::
Text
}
deriving
(
Show
,
Eq
)
instance
FromJSON
Job
where
parseJSON
=
withObject
"Job"
$
\
o
->
do
type_
<-
o
.:
"type"
case
type_
of
"Ping"
->
return
Ping
"ForgotPassword"
->
do
_fp_email
<-
o
.:
"email"
return
$
ForgotPassword
{
_fp_email
}
s
->
prependFailure
"parsing job type failed, "
(
typeMismatch
"type"
s
)
instance
ToJSON
Job
where
toJSON
Ping
=
object
[
(
"type"
.=
(
"Ping"
::
Text
))
]
toJSON
(
ForgotPassword
{
_fp_email
})
=
object
[
(
"type"
.=
(
"ForgotPassword"
::
Text
))
,
(
"email"
.=
_fp_email
)
]
src/Gargantext/Database/Query/Tree/Root.hs
View file @
5d61a290
...
@@ -14,6 +14,7 @@ module Gargantext.Database.Query.Tree.Root
...
@@ -14,6 +14,7 @@ module Gargantext.Database.Query.Tree.Root
where
where
import
Control.Arrow
(
returnA
)
import
Control.Arrow
(
returnA
)
import
Gargantext.API.Admin.Types
(
HasSettings
)
import
Gargantext.Core
(
HasDBid
(
..
))
import
Gargantext.Core
(
HasDBid
(
..
))
import
Gargantext.Core.Types.Individu
(
User
(
..
))
import
Gargantext.Core.Types.Individu
(
User
(
..
))
import
Gargantext.Core.Types.Main
(
CorpusName
)
import
Gargantext.Core.Types.Main
(
CorpusName
)
...
@@ -30,7 +31,6 @@ import Gargantext.Database.Schema.Node (NodePoly(..), NodeRead, queryNodeTable)
...
@@ -30,7 +31,6 @@ import Gargantext.Database.Schema.Node (NodePoly(..), NodeRead, queryNodeTable)
import
Gargantext.Prelude
import
Gargantext.Prelude
import
Opaleye
(
restrict
,
(
.==
),
Select
)
import
Opaleye
(
restrict
,
(
.==
),
Select
)
import
Opaleye.SqlTypes
(
sqlStrictText
,
sqlInt4
)
import
Opaleye.SqlTypes
(
sqlStrictText
,
sqlInt4
)
import
Gargantext.API.Admin.Types
(
HasSettings
)
getRootId
::
(
HasNodeError
err
)
=>
User
->
DBCmd
err
NodeId
getRootId
::
(
HasNodeError
err
)
=>
User
->
DBCmd
err
NodeId
...
...
test/Test/Core/Worker.hs
View file @
5d61a290
...
@@ -13,7 +13,7 @@ module Test.Core.Worker where
...
@@ -13,7 +13,7 @@ module Test.Core.Worker where
import
Data.Aeson
qualified
as
Aeson
import
Data.Aeson
qualified
as
Aeson
import
Gargantext.Core.Methods.Similarities.Conditional
import
Gargantext.Core.Methods.Similarities.Conditional
import
Gargantext.Core.Worker.Jobs
(
Job
(
..
))
import
Gargantext.Core.Worker.Jobs
.Types
(
Job
(
..
))
import
Gargantext.Prelude
import
Gargantext.Prelude
import
Test.Tasty
import
Test.Tasty
import
Test.Tasty.HUnit
import
Test.Tasty.HUnit
...
@@ -21,7 +21,11 @@ import Test.Tasty.QuickCheck hiding (Positive, Negative)
...
@@ -21,7 +21,11 @@ import Test.Tasty.QuickCheck hiding (Positive, Negative)
instance
Arbitrary
Job
where
instance
Arbitrary
Job
where
arbitrary
=
oneof
[
pure
Ping
]
arbitrary
=
oneof
[
pure
Ping
,
forgotPasswordGen
]
where
forgotPasswordGen
=
do
_fp_email
<-
arbitrary
return
$
ForgotPassword
{
_fp_email
}
tests
::
TestTree
tests
::
TestTree
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment