S2S: Group: Add: Implement resource-passive mode
This commit is contained in:
parent
f7d3d6d957
commit
83590ba6ff
7 changed files with 116 additions and 14 deletions
|
@ -147,6 +147,17 @@ import Vervis.Web.Collab
|
||||||
-- * Create a Source/Dest record in DB
|
-- * Create a Source/Dest record in DB
|
||||||
-- * Forward the Add to my followers
|
-- * Forward the Add to my followers
|
||||||
--
|
--
|
||||||
|
-- * If I'm the object, being added to some resource's teams list:
|
||||||
|
-- * Verify the target is a non-team resource's teams list, find in DB/HTTP
|
||||||
|
-- * Verify it's not already an active resource of mine
|
||||||
|
-- * Verify it's not already in an Origin-Us process where I saw the Add
|
||||||
|
-- and sent my Accept
|
||||||
|
-- * Verify it's not already in an Origin-Them process, where I saw the
|
||||||
|
-- Add and the potential resource's Accept
|
||||||
|
-- * Insert the Add to my inbox
|
||||||
|
-- * Create an Effort record in DB
|
||||||
|
-- * Forward the Add to my followers
|
||||||
|
--
|
||||||
-- * Otherwise, error
|
-- * Otherwise, error
|
||||||
groupAdd
|
groupAdd
|
||||||
:: UTCTime
|
:: UTCTime
|
||||||
|
@ -173,6 +184,8 @@ groupAdd now groupID (Verse authorIdMsig body) add = do
|
||||||
addChildPassive $ Left j
|
addChildPassive $ Left j
|
||||||
Left (ATGroupChildren j) | j /= groupID ->
|
Left (ATGroupChildren j) | j /= groupID ->
|
||||||
addParentPassive $ Left j
|
addParentPassive $ Left j
|
||||||
|
Left at | isJust $ addTargetResourceTeams at ->
|
||||||
|
addResourcePassive $ Left $ fromJust $ addTargetResourceTeams at
|
||||||
Right (ObjURI h luColl) -> do
|
Right (ObjURI h luColl) -> do
|
||||||
-- NOTE this is HTTP GET done synchronously in the activity
|
-- NOTE this is HTTP GET done synchronously in the activity
|
||||||
-- handler
|
-- handler
|
||||||
|
@ -189,6 +202,8 @@ groupAdd now groupID (Verse authorIdMsig body) add = do
|
||||||
then addParentPassive $ Right $ ObjURI h lu
|
then addParentPassive $ Right $ ObjURI h lu
|
||||||
else if typ == AP.ActorTypeTeam && Just luColl == AP.rwcParentsOrProjects rwc
|
else if typ == AP.ActorTypeTeam && Just luColl == AP.rwcParentsOrProjects rwc
|
||||||
then addChildPassive $ Right $ ObjURI h lu
|
then addChildPassive $ Right $ ObjURI h lu
|
||||||
|
else if AP.actorTypeIsResourceNT typ && Just luColl == AP.rwcTeams rwc
|
||||||
|
then addResourcePassive $ Right $ ObjURI h lu
|
||||||
else throwE "Weird collection situation"
|
else throwE "Weird collection situation"
|
||||||
_ -> throwE "I'm being added somewhere irrelevant"
|
_ -> throwE "I'm being added somewhere irrelevant"
|
||||||
_ -> throwE "This Add isn't for me"
|
_ -> throwE "This Add isn't for me"
|
||||||
|
@ -755,6 +770,87 @@ groupAdd now groupID (Verse authorIdMsig body) add = do
|
||||||
|
|
||||||
return (action, recipientSet, remoteActors, fwdHosts)
|
return (action, recipientSet, remoteActors, fwdHosts)
|
||||||
|
|
||||||
|
addResourcePassive resource = do
|
||||||
|
|
||||||
|
-- If resource is local, find it in our DB
|
||||||
|
-- If resource is remote, HTTP GET it, verify it's an actor of Group
|
||||||
|
-- type, and store in our DB (if it's already there, no need for HTTP)
|
||||||
|
--
|
||||||
|
-- NOTE: This is a blocking HTTP GET done right here in the handler,
|
||||||
|
-- which is NOT a good idea. Ideally, it would be done async, and the
|
||||||
|
-- handler result would be sent later in a separate (e.g. Accept) activity.
|
||||||
|
-- But for the PoC level, the current situation will hopefully do.
|
||||||
|
resourceDB <-
|
||||||
|
bitraverse
|
||||||
|
(\ ng ->
|
||||||
|
withDBExcept $
|
||||||
|
getLocalResourceEntityE (resourceFromNG ng) "Resource not found in DB"
|
||||||
|
)
|
||||||
|
(\ u@(ObjURI h lu) -> do
|
||||||
|
instanceID <-
|
||||||
|
lift $ withDB $ either entityKey id <$> insertBy' (Instance h)
|
||||||
|
result <-
|
||||||
|
ExceptT $ first (T.pack . displayException) <$>
|
||||||
|
fetchRemoteActor' instanceID h lu
|
||||||
|
case result of
|
||||||
|
Left Nothing -> throwE "Resource @id mismatch"
|
||||||
|
Left (Just err) -> throwE $ T.pack $ displayException err
|
||||||
|
Right Nothing -> throwE "Resource isn't an actor"
|
||||||
|
Right (Just actor) -> do
|
||||||
|
if AP.actorTypeIsResourceNT $ remoteActorType $ entityVal actor
|
||||||
|
then pure ()
|
||||||
|
else throwE "Remote resource type isn't a resource"
|
||||||
|
return (u, actor)
|
||||||
|
)
|
||||||
|
resource
|
||||||
|
let resourceDB' = bimap localResourceID (entityKey . snd) resourceDB
|
||||||
|
|
||||||
|
maybeNew <- withDBExcept $ do
|
||||||
|
|
||||||
|
-- Grab me from DB
|
||||||
|
(group, actorRecip) <- lift $ do
|
||||||
|
p <- getJust groupID
|
||||||
|
(p,) <$> getJust (groupActor p)
|
||||||
|
|
||||||
|
-- Verify the target isn't already a resource of mine, and that no
|
||||||
|
-- Effort record is already in Add-Accept state
|
||||||
|
verifyNoStartedGroupResources groupID resourceDB'
|
||||||
|
|
||||||
|
-- Insert the Add to my inbox
|
||||||
|
mractid <- lift $ insertToInbox now authorIdMsig body (actorInbox actorRecip) False
|
||||||
|
lift $ for mractid $ \ (inboxItemID, addDB) -> do
|
||||||
|
|
||||||
|
-- Create an Effort record in DB
|
||||||
|
insertEffort resourceDB' addDB
|
||||||
|
|
||||||
|
-- Prepare forwarding the Add to my followers
|
||||||
|
sieve <- do
|
||||||
|
groupHash <- encodeKeyHashid groupID
|
||||||
|
return $ makeRecipientSet [] [LocalStageGroupFollowers groupHash]
|
||||||
|
|
||||||
|
return (groupActor group, sieve, inboxItemID)
|
||||||
|
|
||||||
|
case maybeNew of
|
||||||
|
Nothing -> done "I already have this activity in my inbox"
|
||||||
|
Just (groupActorID, sieve, inboxItemID) -> do
|
||||||
|
forwardActivity
|
||||||
|
authorIdMsig body (LocalActorGroup groupID) groupActorID sieve
|
||||||
|
doneDB inboxItemID "[Resource-passive] Recorded a resource-in-progress, forwarded the Add"
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
insertEffort topicDB addDB = do
|
||||||
|
effortID <- insert $ Effort AP.RoleAdmin groupID
|
||||||
|
case topicDB of
|
||||||
|
Left r -> insert_ $ EffortTopicLocal effortID r
|
||||||
|
Right a -> insert_ $ EffortTopicRemote effortID a
|
||||||
|
themID <- insert $ EffortOriginThem effortID
|
||||||
|
case addDB of
|
||||||
|
Left (_, _, addID) ->
|
||||||
|
insert_ $ EffortThemGestureLocal themID addID
|
||||||
|
Right (author, _, addID) ->
|
||||||
|
insert_ $ EffortThemGestureRemote themID (remoteAuthorId author) addID
|
||||||
|
|
||||||
-- Meaning: An actor accepted something
|
-- Meaning: An actor accepted something
|
||||||
-- Behavior:
|
-- Behavior:
|
||||||
-- * Check if I know the activity that's being Accepted:
|
-- * Check if I know the activity that's being Accepted:
|
||||||
|
|
|
@ -652,7 +652,7 @@ personInvite now recipPersonID (Verse authorIdMsig body) invite = do
|
||||||
manager <- asksEnv envHttpManager
|
manager <- asksEnv envHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ mluCollabs _mluComps mluMembers _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ mluCollabs _mluComps mluMembers _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
if mluCollabs == Just luColl || mluMembers == Just luColl
|
if mluCollabs == Just luColl || mluMembers == Just luColl
|
||||||
then Just . (role,) . Right <$> do
|
then Just . (role,) . Right <$> do
|
||||||
instanceID <-
|
instanceID <-
|
||||||
|
|
|
@ -266,7 +266,7 @@ clientAdd now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHosts a
|
||||||
manager <- asksEnv envHttpManager
|
manager <- asksEnv envHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luComps
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luComps
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ _ _ _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ _ _ _ _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
|
|
||||||
instanceID <-
|
instanceID <-
|
||||||
lift $ withDB $ either entityKey id <$> insertBy' (Instance h)
|
lift $ withDB $ either entityKey id <$> insertBy' (Instance h)
|
||||||
|
@ -895,7 +895,7 @@ clientInvite now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHost
|
||||||
manager <- asksEnv envHttpManager
|
manager <- asksEnv envHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ mluCollabs mluComps mluMembers _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ mluCollabs mluComps mluMembers _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
unless (mluCollabs == Just luColl || mluComps == Just luColl || mluMembers == Just luColl) $
|
unless (mluCollabs == Just luColl || mluComps == Just luColl || mluMembers == Just luColl) $
|
||||||
throwE "Invite target isn't a collabs/components list"
|
throwE "Invite target isn't a collabs/components list"
|
||||||
|
|
||||||
|
@ -1044,7 +1044,7 @@ clientJoin now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHosts
|
||||||
manager <- asksEnv envHttpManager
|
manager <- asksEnv envHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ mluCollabs mluComps mluMembers _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ mluCollabs mluComps mluMembers _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
let isCollabs = mluCollabs == Just luColl || mluMembers == Just luColl
|
let isCollabs = mluCollabs == Just luColl || mluMembers == Just luColl
|
||||||
unless (isCollabs || mluComps == Just luColl) $
|
unless (isCollabs || mluComps == Just luColl) $
|
||||||
throwE "Join resource isn't a collabs/components list"
|
throwE "Join resource isn't a collabs/components list"
|
||||||
|
@ -1249,7 +1249,7 @@ clientRemove now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHost
|
||||||
manager <- asksEnv envHttpManager
|
manager <- asksEnv envHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ _ _ _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ _ _ _ _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
return $ ObjURI h lu
|
return $ ObjURI h lu
|
||||||
)
|
)
|
||||||
resource
|
resource
|
||||||
|
|
|
@ -1150,7 +1150,7 @@ invite personID uRecipient uResourceCollabs role = do
|
||||||
manager <- asksSite appHttpManager
|
manager <- asksSite appHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ mluCollabs _ mluMembers _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ mluCollabs _ mluMembers _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
unless (mluCollabs == Just luColl || mluMembers == Just luColl) $
|
unless (mluCollabs == Just luColl || mluMembers == Just luColl) $
|
||||||
throwE "Invite target isn't a collabs list"
|
throwE "Invite target isn't a collabs list"
|
||||||
return $ ObjURI h lu
|
return $ ObjURI h lu
|
||||||
|
@ -1241,7 +1241,7 @@ add personID uRecipient uCollection role = do
|
||||||
manager <- asksSite appHttpManager
|
manager <- asksSite appHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote collection has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote collection has no 'context'"
|
||||||
AP.ResourceWithCollections _ _ _ _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ _ _ _ _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
return $ ObjURI h lu
|
return $ ObjURI h lu
|
||||||
)
|
)
|
||||||
target
|
target
|
||||||
|
@ -1327,7 +1327,7 @@ remove personID uRecipient uCollection = do
|
||||||
manager <- asksSite appHttpManager
|
manager <- asksSite appHttpManager
|
||||||
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
coll <- ExceptT $ liftIO $ first T.pack <$> AP.fetchAPID manager AP.collectionId h luColl
|
||||||
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
lu <- fromMaybeE (AP.collectionContext (coll :: AP.Collection FedURI URIMode)) "Remote topic collabs has no 'context'"
|
||||||
AP.ResourceWithCollections _ _mluCollabs _ _mluMembers _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
AP.ResourceWithCollections _ _mluCollabs _ _mluMembers _ _ _ _ <- ExceptT $ liftIO $ first (T.pack . show) <$> AP.fetchRWC manager h lu
|
||||||
return $ ObjURI h lu
|
return $ ObjURI h lu
|
||||||
)
|
)
|
||||||
resource
|
resource
|
||||||
|
|
|
@ -32,6 +32,7 @@ module Vervis.Data.Collab
|
||||||
, AddTarget (..)
|
, AddTarget (..)
|
||||||
, addTargetResource
|
, addTargetResource
|
||||||
, addTargetComponentProjects
|
, addTargetComponentProjects
|
||||||
|
, addTargetResourceTeams
|
||||||
, parseAdd
|
, parseAdd
|
||||||
|
|
||||||
, ComponentBy (..)
|
, ComponentBy (..)
|
||||||
|
@ -478,6 +479,13 @@ addTargetComponentProjects = \case
|
||||||
ATLoomProjects l -> Just $ ComponentLoom l
|
ATLoomProjects l -> Just $ ComponentLoom l
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
|
addTargetResourceTeams = \case
|
||||||
|
ATProjectTeams j -> Just $ LocalResourceProject' j
|
||||||
|
ATRepoTeams r -> Just $ LocalResourceRepo' r
|
||||||
|
ATDeckTeams d -> Just $ LocalResourceDeck' d
|
||||||
|
ATLoomTeams l -> Just $ LocalResourceLoom' l
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
parseAdd
|
parseAdd
|
||||||
:: StageRoute Env ~ Route App
|
:: StageRoute Env ~ Route App
|
||||||
=> Either (LocalActorBy Key) FedURI
|
=> Either (LocalActorBy Key) FedURI
|
||||||
|
|
|
@ -80,13 +80,8 @@ import Vervis.Model.TH
|
||||||
import Vervis.Model.Ticket
|
import Vervis.Model.Ticket
|
||||||
import Vervis.Model.Workflow
|
import Vervis.Model.Workflow
|
||||||
|
|
||||||
-- For migrations 77, 114
|
|
||||||
|
|
||||||
import Data.Int
|
import Data.Int
|
||||||
|
|
||||||
import Database.Persist.JSON
|
import Database.Persist.JSON
|
||||||
import Network.FedURI
|
|
||||||
import Web.ActivityPub
|
|
||||||
|
|
||||||
makeEntitiesMigration "285"
|
makeEntitiesMigration "285"
|
||||||
$(modelFile "migrations/2022_06_14_collab_mig.model")
|
$(modelFile "migrations/2022_06_14_collab_mig.model")
|
||||||
|
|
|
@ -903,6 +903,7 @@ data ResourceWithCollections u = ResourceWithCollections
|
||||||
, rwcParentsOrProjects :: Maybe LocalURI
|
, rwcParentsOrProjects :: Maybe LocalURI
|
||||||
, rwcSubprojects :: Maybe LocalURI
|
, rwcSubprojects :: Maybe LocalURI
|
||||||
, rwcSubteams :: Maybe LocalURI
|
, rwcSubteams :: Maybe LocalURI
|
||||||
|
, rwcTeams :: Maybe LocalURI
|
||||||
}
|
}
|
||||||
|
|
||||||
instance ActivityPub ResourceWithCollections where
|
instance ActivityPub ResourceWithCollections where
|
||||||
|
@ -916,7 +917,8 @@ instance ActivityPub ResourceWithCollections where
|
||||||
<*> withAuthorityMaybeO h (o .:? "context")
|
<*> withAuthorityMaybeO h (o .:? "context")
|
||||||
<*> withAuthorityMaybeO h (o .:? "subprojects")
|
<*> withAuthorityMaybeO h (o .:? "subprojects")
|
||||||
<*> withAuthorityMaybeO h (o .:? "subteams")
|
<*> withAuthorityMaybeO h (o .:? "subteams")
|
||||||
toSeries h (ResourceWithCollections r collabs comps members ctx subj subt)
|
<*> withAuthorityMaybeO h (o .:? "teams")
|
||||||
|
toSeries h (ResourceWithCollections r collabs comps members ctx subj subt teams)
|
||||||
= toSeries h r
|
= toSeries h r
|
||||||
<> "collaborators" .=? (ObjURI h <$> collabs)
|
<> "collaborators" .=? (ObjURI h <$> collabs)
|
||||||
<> "components" .=? (ObjURI h <$> comps)
|
<> "components" .=? (ObjURI h <$> comps)
|
||||||
|
@ -924,6 +926,7 @@ instance ActivityPub ResourceWithCollections where
|
||||||
<> "context" .=? (ObjURI h <$> ctx)
|
<> "context" .=? (ObjURI h <$> ctx)
|
||||||
<> "subprojects" .=? (ObjURI h <$> subj)
|
<> "subprojects" .=? (ObjURI h <$> subj)
|
||||||
<> "subteams" .=? (ObjURI h <$> subt)
|
<> "subteams" .=? (ObjURI h <$> subt)
|
||||||
|
<> "teams" .=? (ObjURI h <$> teams)
|
||||||
|
|
||||||
data Project u = Project
|
data Project u = Project
|
||||||
{ projectActor :: Actor u
|
{ projectActor :: Actor u
|
||||||
|
|
Loading…
Reference in a new issue