S2S: Re-implement and re-enable deckResolveF
This commit is contained in:
parent
25e1203ed8
commit
f76e80c028
2 changed files with 139 additions and 108 deletions
|
@ -25,7 +25,7 @@ module Vervis.Federation.Ticket
|
||||||
--, deckOfferDepF
|
--, deckOfferDepF
|
||||||
--, repoOfferDepF
|
--, repoOfferDepF
|
||||||
|
|
||||||
--, deckResolveF
|
, deckResolveF
|
||||||
--, repoResolveF
|
--, repoResolveF
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
@ -91,6 +91,7 @@ import qualified Data.Text.UTF8.Local as TU
|
||||||
|
|
||||||
import Development.PatchMediaType
|
import Development.PatchMediaType
|
||||||
|
|
||||||
|
import Vervis.Access
|
||||||
import Vervis.ActivityPub
|
import Vervis.ActivityPub
|
||||||
import Vervis.Cloth
|
import Vervis.Cloth
|
||||||
import Vervis.Data.Actor
|
import Vervis.Data.Actor
|
||||||
|
@ -1870,135 +1871,165 @@ deckResolveF
|
||||||
-> ActivityBody
|
-> ActivityBody
|
||||||
-> Maybe (RecipientRoutes, ByteString)
|
-> Maybe (RecipientRoutes, ByteString)
|
||||||
-> LocalURI
|
-> LocalURI
|
||||||
-> Resolve URIMode
|
-> AP.Resolve URIMode
|
||||||
-> ExceptT Text Handler Text
|
-> ExceptT Text Handler (Text, Maybe (ExceptT Text Worker Text))
|
||||||
deckResolveF now recipHash author body mfwd luResolve (Resolve uObject) = do
|
deckResolveF now recipDeckHash author body mfwd luResolve (AP.Resolve uObject) = (,Nothing) <$> do
|
||||||
error "projectResolveF temporarily disabled"
|
|
||||||
|
|
||||||
|
-- Check input
|
||||||
|
recipDeckID <- decodeKeyHashid404 recipDeckHash
|
||||||
|
taskID <- nameExceptT "Resolve object" $ do
|
||||||
|
route <- do
|
||||||
|
routeOrRemote <- parseFedURI uObject
|
||||||
|
case routeOrRemote of
|
||||||
|
Left route -> pure route
|
||||||
|
Right _ -> throwE "Remote, so definitely not mine"
|
||||||
|
case route of
|
||||||
|
TicketR deckHash taskHash | deckHash == recipDeckHash ->
|
||||||
|
decodeKeyHashidE taskHash "Invalid task keyhashid"
|
||||||
|
_ -> throwE "Local route but not a ticket of mine"
|
||||||
|
|
||||||
{-
|
-- Verify the capability URI is one of:
|
||||||
|
-- * Outbox item URI of a local actor, i.e. a local activity
|
||||||
|
-- * A remote URI
|
||||||
|
capID <- do
|
||||||
|
uCap <- do
|
||||||
|
fromMaybeE
|
||||||
|
(activityCapability $ actbActivity body)
|
||||||
|
"Asking to resolve ticket but no capability provided"
|
||||||
|
nameExceptT "Resolve capability" $ parseActivityURI uCap
|
||||||
|
|
||||||
|
maybeHttp <- runDBExcept $ do
|
||||||
|
|
||||||
object <- parseWorkItem "Resolve object" uObject
|
-- Find recipient deck in DB, returning 404 if doesn't exist because
|
||||||
mmmmhttp <- runDBExcept $ do
|
-- we're in the deck's inbox post handler
|
||||||
(Entity jidRecip projectRecip, actorRecip) <- lift $ do
|
recipDeck <- lift $ get404 recipDeckID
|
||||||
sid <- getKeyBy404 $ UniqueSharer shrRecip
|
let recipDeckActorID = deckActor recipDeck
|
||||||
ej@(Entity _ j) <- getBy404 $ UniqueProject prjRecip sid
|
recipDeckActor <- lift $ getJust recipDeckActorID
|
||||||
(ej,) <$> getJust (projectActor j)
|
|
||||||
mltid <-
|
-- Insert the Resolve to deck's inbox
|
||||||
case relevantObject object of
|
mractid <- lift $ insertToInbox now author body (actorInbox recipDeckActor) luResolve False
|
||||||
Nothing -> do
|
for mractid $ \ resolveID -> do
|
||||||
case object of
|
|
||||||
Left wi -> verifyWorkItemExists wi
|
-- Find ticket in DB, verify it's not resolved
|
||||||
Right _ -> return ()
|
ticketID <- do
|
||||||
return Nothing
|
maybeTicket <- lift $ getTicket recipDeckID taskID
|
||||||
Just ltid -> Just . (ltid,) <$> getObjectLtid ltid
|
(_deck, _task, Entity ticketID _, _author, maybeResolve) <-
|
||||||
mractid <- lift $ insertToInbox now author body (actorInbox actorRecip) luResolve False
|
fromMaybeE maybeTicket "I don't have such a ticket in DB"
|
||||||
lift $ for mractid $ \ ractid -> for mltid $ \ (ltid, tid) -> do
|
unless (isNothing maybeResolve) $
|
||||||
mremotesHttpFwd <- for mfwd $ \ (localRecips, sig) -> do
|
throwE "Ticket is already resolved"
|
||||||
ltkhid <- encodeKeyHashid ltid
|
return ticketID
|
||||||
|
|
||||||
|
-- Verify the sender is authorized by the deck to resolve a ticket
|
||||||
|
capability <-
|
||||||
|
case capID of
|
||||||
|
Left (capActor, _, capItem) -> return (capActor, capItem)
|
||||||
|
Right _ -> throwE "Capability is a remote URI, i.e. not authored by the local deck"
|
||||||
|
verifyCapability
|
||||||
|
capability
|
||||||
|
(Right $ remoteAuthorId author)
|
||||||
|
(GrantResourceDeck recipDeckID)
|
||||||
|
|
||||||
|
-- Forward the Resolve activity to relevant local stages, and
|
||||||
|
-- schedule delivery for unavailable remote members of them
|
||||||
|
maybeHttpFwdResolve <- lift $ for mfwd $ \ (localRecips, sig) -> do
|
||||||
|
taskHash <- encodeKeyHashid taskID
|
||||||
let sieve =
|
let sieve =
|
||||||
makeRecipientSet
|
makeRecipientSet
|
||||||
[]
|
[]
|
||||||
[ LocalPersonCollectionProjectTicketFollowers shrRecip prjRecip ltkhid
|
[ LocalStageDeckFollowers recipDeckHash
|
||||||
, LocalPersonCollectionProjectTeam shrRecip prjRecip
|
, LocalStageTicketFollowers recipDeckHash taskHash
|
||||||
, LocalPersonCollectionProjectFollowers shrRecip prjRecip
|
|
||||||
]
|
]
|
||||||
remoteRecips <-
|
forwardActivityDB
|
||||||
insertRemoteActivityToLocalInboxes
|
(actbBL body) localRecips sig recipDeckActorID
|
||||||
False ractid $
|
(LocalActorDeck recipDeckHash) sieve resolveID
|
||||||
localRecipSieve'
|
|
||||||
sieve False False localRecips
|
-- Mark ticket in DB as resolved by the Resolve
|
||||||
(sig,) <$> deliverRemoteDB_J (actbBL body) ractid jidRecip sig remoteRecips
|
acceptID <-
|
||||||
obiidAccept <- insertEmptyOutboxItem (actorOutbox actorRecip) now
|
lift $ insertEmptyOutboxItem (actorOutbox recipDeckActor) now
|
||||||
mmtrrid <- insertResolve author ltid ractid obiidAccept
|
lift $ insertResolve ticketID resolveID acceptID
|
||||||
case mmtrrid of
|
|
||||||
Just (Just _) -> update tid [TicketStatus =. TSClosed]
|
-- Prepare an Accept activity and insert to deck's outbox
|
||||||
_ -> delete obiidAccept
|
(actionAccept, localRecipsAccept, remoteRecipsAccept, fwdHostsAccept) <-
|
||||||
for mmtrrid $ \ mtrrid -> for mtrrid $ \ trrid -> do
|
lift $ prepareAccept taskID
|
||||||
(docAccept, localRecipsAccept, remoteRecipsAccept, fwdHostsAccept) <-
|
_luAccept <- lift $ updateOutboxItem (LocalActorDeck recipDeckID) acceptID actionAccept
|
||||||
insertAccept luResolve ltid obiidAccept
|
|
||||||
knownRemoteRecipsAccept <-
|
-- Deliver the Accept to local recipients, and schedule delivery
|
||||||
deliverLocal'
|
-- for unavailable remote recipients
|
||||||
False
|
deliverHttpAccept <-
|
||||||
(LocalActorProject shrRecip prjRecip)
|
deliverActivityDB
|
||||||
(actorInbox actorRecip)
|
(LocalActorDeck recipDeckHash) recipDeckActorID
|
||||||
obiidAccept
|
localRecipsAccept remoteRecipsAccept fwdHostsAccept
|
||||||
localRecipsAccept
|
acceptID actionAccept
|
||||||
(mremotesHttpFwd,obiidAccept,docAccept,fwdHostsAccept,) <$>
|
|
||||||
deliverRemoteDB fwdHostsAccept obiidAccept remoteRecipsAccept knownRemoteRecipsAccept
|
-- Return instructions for HTTP inbox-forwarding of the Resolve
|
||||||
case mmmmhttp of
|
-- activity, and for HTTP delivery of the Accept activity to
|
||||||
Nothing -> return "I already have this activity in my inbox, doing nothing"
|
-- remote recipients
|
||||||
Just mmmhttp ->
|
return (maybeHttpFwdResolve, deliverHttpAccept)
|
||||||
case mmmhttp of
|
|
||||||
Nothing -> return "Object not mine, just stored in inbox"
|
-- Launch asynchronous HTTP forwarding of the Resolve activity and HTTP
|
||||||
Just mmhttp ->
|
-- delivery of the Accept activity
|
||||||
case mmhttp of
|
case maybeHttp of
|
||||||
Nothing -> return "Ticket already resolved"
|
Nothing ->
|
||||||
Just mhttp ->
|
return "I already have this activity in my inbox, doing nothing"
|
||||||
case mhttp of
|
Just (maybeHttpFwdResolve, deliverHttpAccept) -> do
|
||||||
Nothing -> return "Activity already resolved a ticket"
|
for_ maybeHttpFwdResolve $
|
||||||
Just (mremotesHttpFwd, obiid, doc, fwdHosts, recips) -> do
|
forkWorker "deckResolveF inbox-forwarding"
|
||||||
for_ mremotesHttpFwd $ \ (sig, remotes) ->
|
forkWorker "deckResolveF Accept HTTP delivery" deliverHttpAccept
|
||||||
forkWorker "projectResolveF inbox-forwarding" $
|
return $
|
||||||
deliverRemoteHTTP_J now shrRecip prjRecip (actbBL body) sig remotes
|
case maybeHttpFwdResolve of
|
||||||
forkWorker "projectResolveF Accept HTTP delivery" $
|
Nothing -> "Resolved ticket, no inbox-forwarding to do"
|
||||||
deliverRemoteHttp' fwdHosts obiid doc recips
|
Just _ ->
|
||||||
return $
|
"Resolved ticket and ran inbox-forwarding of the Resolve"
|
||||||
if isJust mremotesHttpFwd
|
|
||||||
then "Ticket is mine, now resolved, did inbox-forwarding"
|
|
||||||
else "Ticket is mine, now resolved, no inbox-forwarding to do"
|
|
||||||
where
|
where
|
||||||
relevantObject (Left (WorkItemProjectTicket shr prj ltid))
|
|
||||||
| shr == shrRecip && prj == prjRecip = Just ltid
|
|
||||||
relevantObject _ = Nothing
|
|
||||||
|
|
||||||
getObjectLtid ltid = do
|
insertResolve ticketID resolveID acceptID = do
|
||||||
(_, _, Entity tid _, _, _, _, _, _) <- do
|
trid <- insert TicketResolve
|
||||||
mticket <- lift $ getProjectTicket shrRecip prjRecip ltid
|
{ ticketResolveTicket = ticketID
|
||||||
fromMaybeE mticket $ "Object" <> ": No such project-ticket"
|
, ticketResolveAccept = acceptID
|
||||||
return tid
|
}
|
||||||
|
insert_ TicketResolveRemote
|
||||||
|
{ ticketResolveRemoteTicket = trid
|
||||||
|
, ticketResolveRemoteActivity = resolveID
|
||||||
|
, ticketResolveRemoteActor = remoteAuthorId author
|
||||||
|
}
|
||||||
|
|
||||||
insertAccept luResolve ltid obiidAccept = do
|
prepareAccept taskID = do
|
||||||
encodeRouteLocal <- getEncodeRouteLocal
|
|
||||||
encodeRouteHome <- getEncodeRouteHome
|
encodeRouteHome <- getEncodeRouteHome
|
||||||
hLocal <- asksSite siteInstanceHost
|
|
||||||
obikhidAccept <- encodeKeyHashid obiidAccept
|
taskHash <- encodeKeyHashid taskID
|
||||||
ltkhid <- encodeKeyHashid ltid
|
|
||||||
ra <- getJust $ remoteAuthorId author
|
ra <- getJust $ remoteAuthorId author
|
||||||
|
|
||||||
let ObjURI hAuthor luAuthor = remoteAuthorURI author
|
let ObjURI hAuthor luAuthor = remoteAuthorURI author
|
||||||
|
|
||||||
audAuthor =
|
audSender =
|
||||||
AudRemote hAuthor [luAuthor] (maybeToList $ remoteActorFollowers ra)
|
AudRemote hAuthor
|
||||||
|
[luAuthor]
|
||||||
audTicket =
|
(maybeToList $ remoteActorFollowers ra)
|
||||||
|
audTracker =
|
||||||
AudLocal
|
AudLocal
|
||||||
[]
|
[]
|
||||||
[ LocalPersonCollectionProjectTicketFollowers shrRecip prjRecip ltkhid
|
[ LocalStageDeckFollowers recipDeckHash
|
||||||
, LocalPersonCollectionProjectTeam shrRecip prjRecip
|
, LocalStageTicketFollowers recipDeckHash taskHash
|
||||||
, LocalPersonCollectionProjectFollowers shrRecip prjRecip
|
|
||||||
]
|
]
|
||||||
|
|
||||||
(recipientSet, remoteActors, fwdHosts, audLocal, audRemote) =
|
(recipientSet, remoteActors, fwdHosts, audLocal, audRemote) =
|
||||||
collectAudience [audAuthor, audTicket]
|
collectAudience [audSender, audTracker]
|
||||||
|
|
||||||
recips = map encodeRouteHome audLocal ++ audRemote
|
recips = map encodeRouteHome audLocal ++ audRemote
|
||||||
doc = Doc hLocal Activity
|
action = AP.Action
|
||||||
{ activityId =
|
{ AP.actionCapability = Nothing
|
||||||
Just $ encodeRouteLocal $
|
, AP.actionSummary = Nothing
|
||||||
ProjectOutboxItemR shrRecip prjRecip obikhidAccept
|
, AP.actionAudience = AP.Audience recips [] [] [] [] []
|
||||||
, activityActor = encodeRouteLocal $ ProjectR shrRecip prjRecip
|
, AP.actionFulfills = []
|
||||||
, activityCapability = Nothing
|
, AP.actionSpecific = AP.AcceptActivity AP.Accept
|
||||||
, activitySummary = Nothing
|
{ AP.acceptObject = ObjURI hAuthor luResolve
|
||||||
, activityAudience = Audience recips [] [] [] [] []
|
, AP.acceptResult = Nothing
|
||||||
, activitySpecific = AcceptActivity Accept
|
|
||||||
{ acceptObject = ObjURI hAuthor luResolve
|
|
||||||
, acceptResult = Nothing
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update obiidAccept [OutboxItemActivity =. persistJSONObjectFromDoc doc]
|
|
||||||
return (doc, recipientSet, remoteActors, fwdHosts)
|
return (action, recipientSet, remoteActors, fwdHosts)
|
||||||
-}
|
|
||||||
|
|
||||||
repoResolveF
|
repoResolveF
|
||||||
:: UTCTime
|
:: UTCTime
|
||||||
|
|
|
@ -211,9 +211,9 @@ postDeckInboxR recipDeckHash =
|
||||||
projectOfferDepF now shrRecip prjRecip remoteAuthor body mfwd luActivity dep target
|
projectOfferDepF now shrRecip prjRecip remoteAuthor body mfwd luActivity dep target
|
||||||
-}
|
-}
|
||||||
_ -> return ("Unsupported offer object type for decks", Nothing)
|
_ -> return ("Unsupported offer object type for decks", Nothing)
|
||||||
|
AP.ResolveActivity resolve ->
|
||||||
|
deckResolveF now recipDeckHash author body mfwd luActivity resolve
|
||||||
{-
|
{-
|
||||||
ResolveActivity resolve ->
|
|
||||||
(,Nothing) <$> projectResolveF now shrRecip prjRecip remoteAuthor body mfwd luActivity resolve
|
|
||||||
UndoActivity undo ->
|
UndoActivity undo ->
|
||||||
(,Nothing) <$> projectUndoF shrRecip prjRecip now remoteAuthor body mfwd luActivity undo
|
(,Nothing) <$> projectUndoF shrRecip prjRecip now remoteAuthor body mfwd luActivity undo
|
||||||
-}
|
-}
|
||||||
|
|
Loading…
Reference in a new issue