S2S: Group: Accept: Implement resource mode
This commit is contained in:
parent
47736bb0a8
commit
cd18217f08
1 changed files with 287 additions and 3 deletions
|
@ -944,6 +944,41 @@ groupAdd now groupID (Verse authorIdMsig body) add = do
|
||||||
-- delegation Grant I got from B
|
-- delegation Grant I got from B
|
||||||
-- * To: The parent/collaborator/team to whom I'd sent the Grant
|
-- * To: The parent/collaborator/team to whom I'd sent the Grant
|
||||||
-- * CC: -
|
-- * CC: -
|
||||||
|
--
|
||||||
|
-- * Give me a new resource active EffortOriginUs
|
||||||
|
-- * Verify we haven't yet seen resource's Accept
|
||||||
|
-- * Insert the Accept to my inbox
|
||||||
|
-- * If sender is the resource, record the Accept into the Effort record
|
||||||
|
-- * Prepare to send degelator-Grant
|
||||||
|
-- * Otherwise nothing to do
|
||||||
|
-- * Forward the Accept to my followers
|
||||||
|
-- * Possibly send a Grant:
|
||||||
|
-- * If sender is the resource
|
||||||
|
-- * delegator-Grant
|
||||||
|
-- * To: Resource
|
||||||
|
-- * CC:
|
||||||
|
-- - Resource's followers
|
||||||
|
-- - My followers
|
||||||
|
--
|
||||||
|
-- * Give me a new resource passive EffortOriginThem
|
||||||
|
-- * Option 1: We haven't seen resource's Accept yet
|
||||||
|
-- * Verify sender is the resource
|
||||||
|
-- * Option 2: We saw it, but not my collaborator's Accept
|
||||||
|
-- * Verify the Accept is authorized
|
||||||
|
-- * Otherwise respond with error, no Accept is needed
|
||||||
|
-- * Insert the Accept to my inbox
|
||||||
|
-- * Option 1: Record resource's Accept in Effort record
|
||||||
|
-- * Option 2: Record my collaborator's Accept
|
||||||
|
-- * Prepare to send delegator-Grant
|
||||||
|
-- * Forward the Accept to my followers
|
||||||
|
-- * Possibly send a Grant:
|
||||||
|
-- * In option 2
|
||||||
|
-- * delegator-Grant
|
||||||
|
-- * To: Resource
|
||||||
|
-- * CC:
|
||||||
|
-- - Resource's followers
|
||||||
|
-- - My followers
|
||||||
|
-- - The Accept sender (my collaborator)
|
||||||
groupAccept
|
groupAccept
|
||||||
:: UTCTime
|
:: UTCTime
|
||||||
-> GroupId
|
-> GroupId
|
||||||
|
@ -972,8 +1007,10 @@ groupAccept now groupID (Verse authorIdMsig body) accept = do
|
||||||
let adapt = maybe (Right Nothing) (either Left (Right . Just))
|
let adapt = maybe (Right Nothing) (either Left (Right . Just))
|
||||||
maybeCollab <-
|
maybeCollab <-
|
||||||
ExceptT $ fmap adapt $ runMaybeT $
|
ExceptT $ fmap adapt $ runMaybeT $
|
||||||
runExceptT (Left <$> tryInviteCollab accepteeDB) <|>
|
runExceptT (Left . Left <$> tryInviteCollab accepteeDB) <|>
|
||||||
runExceptT (Left <$> tryJoinCollab accepteeDB) <|>
|
runExceptT (Left . Left <$> tryJoinCollab accepteeDB) <|>
|
||||||
|
runExceptT (Left . Right <$> tryAddResourceActive accepteeDB) <|>
|
||||||
|
runExceptT (Left . Right <$> tryAddResourcePassive accepteeDB) <|>
|
||||||
runExceptT (Right . Left <$> tryAddChildActive accepteeDB) <|>
|
runExceptT (Right . Left <$> tryAddChildActive accepteeDB) <|>
|
||||||
runExceptT (Right . Left <$> tryAddChildPassive accepteeDB) <|>
|
runExceptT (Right . Left <$> tryAddChildPassive accepteeDB) <|>
|
||||||
runExceptT (Right . Left <$> tryAddParentActive accepteeDB) <|>
|
runExceptT (Right . Left <$> tryAddParentActive accepteeDB) <|>
|
||||||
|
@ -984,7 +1021,8 @@ groupAccept now groupID (Verse authorIdMsig body) accept = do
|
||||||
"Accepted activity isn't an Invite/Join/Add/Remove I'm aware of"
|
"Accepted activity isn't an Invite/Join/Add/Remove I'm aware of"
|
||||||
|
|
||||||
case collabOrComp_or_child of
|
case collabOrComp_or_child of
|
||||||
Left collab -> addCollab collab
|
Left (Left collab) -> addCollab collab
|
||||||
|
Left (Right resource) -> addResource resource
|
||||||
Right (Left cp) -> addChildParent cp
|
Right (Left cp) -> addChildParent cp
|
||||||
Right (Right parent) -> removeParent parent
|
Right (Right parent) -> removeParent parent
|
||||||
|
|
||||||
|
@ -1174,6 +1212,41 @@ groupAccept now groupID (Verse authorIdMsig body) accept = do
|
||||||
lift $ MaybeT $ getValBy $ UniqueInboxItemRemote inboxID remoteActivityID
|
lift $ MaybeT $ getValBy $ UniqueInboxItemRemote inboxID remoteActivityID
|
||||||
tryRemoveParent' i
|
tryRemoveParent' i
|
||||||
|
|
||||||
|
verifyEffortHolder :: EffortId -> MaybeT ActDB ()
|
||||||
|
verifyEffortHolder effortID = do
|
||||||
|
Effort _ g <- lift $ getJust effortID
|
||||||
|
guard $ g == groupID
|
||||||
|
|
||||||
|
tryAddResourceActive' usID = do
|
||||||
|
EffortOriginUs effortID <- lift . lift $ getJust usID
|
||||||
|
lift $ verifyEffortHolder effortID
|
||||||
|
topic <- lift . lift $ getEffortTopic effortID
|
||||||
|
return (effortID, topic, Left ())
|
||||||
|
|
||||||
|
tryAddResourceActive (Left (_actorByKey, _actorEntity, itemID)) = do
|
||||||
|
EffortUsGestureLocal usID _ <-
|
||||||
|
lift $ MaybeT $ getValBy $ UniqueEffortUsGestureLocalAdd itemID
|
||||||
|
tryAddResourceActive' usID
|
||||||
|
tryAddResourceActive (Right remoteActivityID) = do
|
||||||
|
EffortUsGestureRemote usID _ _ <-
|
||||||
|
lift $ MaybeT $ getValBy $ UniqueEffortUsGestureRemoteAdd remoteActivityID
|
||||||
|
tryAddResourceActive' usID
|
||||||
|
|
||||||
|
tryAddResourcePassive' themID = do
|
||||||
|
EffortOriginThem effortID <- lift . lift $ getJust themID
|
||||||
|
lift $ verifyEffortHolder effortID
|
||||||
|
topic <- lift . lift $ getEffortTopic effortID
|
||||||
|
return (effortID, topic, Right ())
|
||||||
|
|
||||||
|
tryAddResourcePassive (Left (_actorByKey, _actorEntity, itemID)) = do
|
||||||
|
EffortThemGestureLocal themID _ <-
|
||||||
|
lift $ MaybeT $ getValBy $ UniqueEffortThemGestureLocalAdd itemID
|
||||||
|
tryAddResourcePassive' themID
|
||||||
|
tryAddResourcePassive (Right remoteActivityID) = do
|
||||||
|
EffortThemGestureRemote themID _ _ <-
|
||||||
|
lift $ MaybeT $ getValBy $ UniqueEffortThemGestureRemoteAdd remoteActivityID
|
||||||
|
tryAddResourcePassive' themID
|
||||||
|
|
||||||
componentIsAuthor ident =
|
componentIsAuthor ident =
|
||||||
let author = bimap (view _1) (remoteAuthorId . view _1) authorIdMsig
|
let author = bimap (view _1) (remoteAuthorId . view _1) authorIdMsig
|
||||||
in author == bimap (resourceToActor . componentResource . snd) snd ident
|
in author == bimap (resourceToActor . componentResource . snd) snd ident
|
||||||
|
@ -1183,6 +1256,11 @@ groupAccept now groupID (Verse authorIdMsig body) accept = do
|
||||||
let author = bimap (view _1) (remoteAuthorId . view _1) authorIdMsig
|
let author = bimap (view _1) (remoteAuthorId . view _1) authorIdMsig
|
||||||
in author == bimap (LocalActorGroup . snd) snd ident
|
in author == bimap (LocalActorGroup . snd) snd ident
|
||||||
|
|
||||||
|
theyIsAuthor' :: Either (a, LocalResourceBy Key) (b, RemoteActorId) -> Bool
|
||||||
|
theyIsAuthor' ident =
|
||||||
|
let author = bimap (view _1) (remoteAuthorId . view _1) authorIdMsig
|
||||||
|
in author == bimap (resourceToActor . snd) snd ident
|
||||||
|
|
||||||
addCollab (collabID, fulfills, inviterOrJoiner) = do
|
addCollab (collabID, fulfills, inviterOrJoiner) = do
|
||||||
|
|
||||||
collab <-
|
collab <-
|
||||||
|
@ -1915,6 +1993,212 @@ groupAccept now groupID (Verse authorIdMsig body) accept = do
|
||||||
|
|
||||||
return (action, recipientSet, remoteActors, fwdHosts)
|
return (action, recipientSet, remoteActors, fwdHosts)
|
||||||
|
|
||||||
|
addResource (effortID, topic', mode) = do
|
||||||
|
|
||||||
|
topic <-
|
||||||
|
lift $ traverseOf _Left (traverseOf _2 $ withDB . getLocalResource) topic'
|
||||||
|
mode' <-
|
||||||
|
bitraverse
|
||||||
|
|
||||||
|
-- Resource-active mode
|
||||||
|
-- Verify we haven't yet seen resource's Accept
|
||||||
|
(\ () -> do
|
||||||
|
maybeResourceAccept <-
|
||||||
|
lift $ withDB $
|
||||||
|
case bimap fst fst topic of
|
||||||
|
Left localID -> (() <$) <$> getBy (UniqueEffortThemAcceptLocal localID)
|
||||||
|
Right remoteID -> (() <$) <$> getBy (UniqueEffortThemAcceptRemote remoteID)
|
||||||
|
verifyNothingE maybeResourceAccept "I already saw resource's Accept"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Resource-passive mode
|
||||||
|
-- Option 1: We haven't seen resource's Accept yet
|
||||||
|
-- * Verify sender is the resource
|
||||||
|
-- Option 2: We saw it, but not my collaborator's Accept
|
||||||
|
-- * Verify the Accept is authorized
|
||||||
|
-- Otherwise respond with error, no Accept is needed
|
||||||
|
(\ () -> do
|
||||||
|
(maybeResourceAccept, maybeGrant) <-
|
||||||
|
lift $ withDB $ liftA2 (,)
|
||||||
|
(case bimap fst fst topic of
|
||||||
|
Left localID -> (() <$) <$> getBy (UniqueEffortThemAcceptLocal localID)
|
||||||
|
Right remoteID -> (() <$) <$> getBy (UniqueEffortThemAcceptRemote remoteID)
|
||||||
|
)
|
||||||
|
(getBy $ UniqueEffortUsSendDelegator effortID)
|
||||||
|
case (isJust maybeResourceAccept, isJust maybeGrant) of
|
||||||
|
(False, True) -> error "Impossible/bug, didn't see resource's Accept but sent a Grant"
|
||||||
|
(False, False) -> do
|
||||||
|
unless (theyIsAuthor' topic) $
|
||||||
|
throwE "The Accept I'm waiting for is from my new resource"
|
||||||
|
return $ Left ()
|
||||||
|
(True, False) -> do
|
||||||
|
let muCap = AP.activityCapability $ actbActivity body
|
||||||
|
uCap <- fromMaybeE muCap "No capability provided"
|
||||||
|
verifyCapability''
|
||||||
|
uCap
|
||||||
|
authorIdMsig
|
||||||
|
(LocalResourceGroup groupID)
|
||||||
|
AP.RoleAdmin
|
||||||
|
return $ Right ()
|
||||||
|
(True, True) -> throwE "Resource already enabled, not needing any further Accept"
|
||||||
|
)
|
||||||
|
|
||||||
|
mode
|
||||||
|
|
||||||
|
maybeNew <- withDBExcept $ do
|
||||||
|
|
||||||
|
-- Grab me from DB
|
||||||
|
(recipActorID, recipActor) <- lift $ do
|
||||||
|
recip <- getJust groupID
|
||||||
|
let actorID = groupActor recip
|
||||||
|
(actorID,) <$> getJust actorID
|
||||||
|
|
||||||
|
maybeAcceptDB <- lift $ insertToInbox now authorIdMsig body (actorInbox recipActor) False
|
||||||
|
for maybeAcceptDB $ \ (inboxItemID, acceptDB) -> do
|
||||||
|
|
||||||
|
idsForGrant <-
|
||||||
|
lift $
|
||||||
|
bitraverse
|
||||||
|
|
||||||
|
-- Resource-active mode
|
||||||
|
-- If sender is resource, record the Accept into the
|
||||||
|
-- Effort record & prepare to send degelator-Grant
|
||||||
|
-- Othrerwise do nothing
|
||||||
|
(\ () ->
|
||||||
|
if theyIsAuthor' topic
|
||||||
|
then Just <$> do
|
||||||
|
case (topic, acceptDB) of
|
||||||
|
(Left (localID, _), Left (_, _, acceptID)) ->
|
||||||
|
insert_ $ EffortThemAcceptLocal localID acceptID
|
||||||
|
(Right (remoteID, _), Right (_, _, acceptID)) ->
|
||||||
|
insert_ $ EffortThemAcceptRemote remoteID acceptID
|
||||||
|
_ -> error "groupAccept impossible iv"
|
||||||
|
grantID <- insertEmptyOutboxItem' (actorOutbox recipActor) now
|
||||||
|
insert_ $ EffortUsSendDelegator effortID grantID
|
||||||
|
return grantID
|
||||||
|
else pure Nothing
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Resource-passive mode
|
||||||
|
(\case
|
||||||
|
|
||||||
|
-- Getting an Accept from the resource
|
||||||
|
-- Record resource's Accept in Effort record
|
||||||
|
Left () -> do
|
||||||
|
case (topic, acceptDB) of
|
||||||
|
(Left (localID, _), Left (_, _, acceptID)) ->
|
||||||
|
insert_ $ EffortThemAcceptLocal localID acceptID
|
||||||
|
(Right (remoteID, _), Right (_, _, acceptID)) ->
|
||||||
|
insert_ $ EffortThemAcceptRemote remoteID acceptID
|
||||||
|
_ -> error "groupAccept impossible v"
|
||||||
|
return Nothing
|
||||||
|
|
||||||
|
-- Getting an Accept from my collaborator
|
||||||
|
-- Record my collaborator's Accept
|
||||||
|
-- Prepare to send delegator-Grant
|
||||||
|
Right () -> Just <$> do
|
||||||
|
{-
|
||||||
|
case (topic, acceptDB) of
|
||||||
|
(Left (localID, _), Left (_, _, acceptID)) ->
|
||||||
|
insert_ $ ? localID acceptID
|
||||||
|
(Right (remoteID, _), Right (_, _, acceptID)) ->
|
||||||
|
insert_ $ ? remoteID acceptID
|
||||||
|
_ -> error "groupAccept impossible iv"
|
||||||
|
-}
|
||||||
|
grantID <- insertEmptyOutboxItem' (actorOutbox recipActor) now
|
||||||
|
insert_ $ EffortUsSendDelegator effortID grantID
|
||||||
|
return grantID
|
||||||
|
)
|
||||||
|
|
||||||
|
mode'
|
||||||
|
|
||||||
|
-- Prepare forwarding of Accept to my followers
|
||||||
|
let recipByID = LocalActorGroup groupID
|
||||||
|
recipByHash <- hashLocalActor recipByID
|
||||||
|
let sieve = makeRecipientSet [] [localActorFollowers recipByHash]
|
||||||
|
|
||||||
|
maybeAct <-
|
||||||
|
case idsForGrant of
|
||||||
|
Left mg -> for mg $ \ grantID -> lift $ do
|
||||||
|
grant@(actionGrant, _, _, _) <-
|
||||||
|
prepareEffortDelegGrant (bimap snd snd topic) False
|
||||||
|
let recipByKey = LocalActorGroup groupID
|
||||||
|
_luGrant <- updateOutboxItem' recipByKey grantID actionGrant
|
||||||
|
return (grantID, grant)
|
||||||
|
|
||||||
|
Right mg -> for mg $ \ grantID -> lift $ do
|
||||||
|
grant@(actionGrant, _, _, _) <-
|
||||||
|
prepareEffortDelegGrant (bimap snd snd topic) True
|
||||||
|
let recipByKey = LocalActorGroup groupID
|
||||||
|
_luGrant <- updateOutboxItem' recipByKey grantID actionGrant
|
||||||
|
return (grantID, grant)
|
||||||
|
|
||||||
|
return (recipActorID, sieve, maybeAct, inboxItemID)
|
||||||
|
|
||||||
|
case maybeNew of
|
||||||
|
Nothing -> done "I already have this activity in my inbox"
|
||||||
|
Just (recipActorID, sieve, maybeGrant, inboxItemID) -> do
|
||||||
|
let recipByID = LocalActorGroup groupID
|
||||||
|
forwardActivity authorIdMsig body recipByID recipActorID sieve
|
||||||
|
lift $ for_ maybeGrant $ \ (grantID, (actionGrant, localRecipsGrant, remoteRecipsGrant, fwdHostsGrant)) ->
|
||||||
|
sendActivity
|
||||||
|
recipByID recipActorID localRecipsGrant
|
||||||
|
remoteRecipsGrant fwdHostsGrant grantID actionGrant
|
||||||
|
doneDB inboxItemID "[Resource] Forwarded the Accept and maybe published a Grant/Accept"
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
prepareEffortDelegGrant ident includeAuthor = do
|
||||||
|
encodeRouteHome <- getEncodeRouteHome
|
||||||
|
encodeRouteLocal <- getEncodeRouteLocal
|
||||||
|
|
||||||
|
(uResource, audResource) <-
|
||||||
|
case ident of
|
||||||
|
Left lr -> do
|
||||||
|
la <- resourceToActor <$> hashLocalResource lr
|
||||||
|
return
|
||||||
|
( encodeRouteHome $ renderLocalActor la
|
||||||
|
, AudLocal [la] [localActorFollowers la]
|
||||||
|
)
|
||||||
|
Right raID -> do
|
||||||
|
ra <- getJust raID
|
||||||
|
u@(ObjURI h lu) <- getRemoteActorURI ra
|
||||||
|
return
|
||||||
|
( u
|
||||||
|
, AudRemote h [lu] (maybeToList $ remoteActorFollowers ra)
|
||||||
|
)
|
||||||
|
audAuthor <- lift $ makeAudSenderOnly authorIdMsig
|
||||||
|
groupHash <- encodeKeyHashid groupID
|
||||||
|
let audGroup = AudLocal [] [LocalStageGroupFollowers groupHash]
|
||||||
|
|
||||||
|
audience =
|
||||||
|
if includeAuthor
|
||||||
|
then [audResource, audGroup, audAuthor]
|
||||||
|
else [audResource, audGroup]
|
||||||
|
|
||||||
|
(recipientSet, remoteActors, fwdHosts, audLocal, audRemote) =
|
||||||
|
collectAudience audience
|
||||||
|
|
||||||
|
recips = map encodeRouteHome audLocal ++ audRemote
|
||||||
|
action = AP.Action
|
||||||
|
{ AP.actionCapability = Nothing
|
||||||
|
, AP.actionSummary = Nothing
|
||||||
|
, AP.actionAudience = AP.Audience recips [] [] [] [] []
|
||||||
|
, AP.actionFulfills = [AP.acceptObject accept]
|
||||||
|
, AP.actionSpecific = AP.GrantActivity AP.Grant
|
||||||
|
{ AP.grantObject = AP.RXDelegator
|
||||||
|
, AP.grantContext = encodeRouteHome $ GroupR groupHash
|
||||||
|
, AP.grantTarget = uResource
|
||||||
|
, AP.grantResult = Nothing
|
||||||
|
, AP.grantStart = Just now
|
||||||
|
, AP.grantEnd = Nothing
|
||||||
|
, AP.grantAllows = AP.Invoke
|
||||||
|
, AP.grantDelegates = Nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (action, recipientSet, remoteActors, fwdHosts)
|
||||||
|
|
||||||
-- Meaning: Someone has created a group with my ID URI
|
-- Meaning: Someone has created a group with my ID URI
|
||||||
-- Behavior:
|
-- Behavior:
|
||||||
-- * Verify I'm in a just-been-created state
|
-- * Verify I'm in a just-been-created state
|
||||||
|
|
Loading…
Reference in a new issue