1
0
Fork 0
mirror of https://code.naskya.net/repos/ndqEd synced 2025-01-10 10:46:45 +09:00

Switch Invite/Join/Remove to use resource collabs URI

Until now, the resource object itself would be specified. This no longer
works, because it's unclear whether we're adding/removing a collaborator
or a component.

From now on, adding a collaborator is done by pointing to the resource's
'collaborators' URI, not to the resource itself
This commit is contained in:
Pere Lev 2023-06-28 00:30:35 +03:00
parent 034194f2aa
commit b2657589dd
No known key found for this signature in database
GPG key ID: 5252C5C863E5E57D
11 changed files with 98 additions and 34 deletions

View file

@ -707,7 +707,7 @@ topicInvite grabActor topicResource topicField topicCollabField collabTopicCtor
let author = bimap (view _1) (remoteAuthorURI . view _1) authorIdMsig let author = bimap (view _1) (remoteAuthorURI . view _1) authorIdMsig
(role, resource, recipient) <- parseInvite author invite (role, resource, recipient) <- parseInvite author invite
unless (Left (topicResource topicKey) == resource) $ unless (Left (topicResource topicKey) == resource) $
throwE "Invite topic isn't me" throwE "Invite topic isn't my collabs URI"
return (role, recipient) return (role, recipient)
-- If target is local, find it in our DB -- If target is local, find it in our DB
@ -839,7 +839,7 @@ topicRemove grabActor topicResource topicField topicCollabField now topicKey (Ve
-- Verify the capability URI is one of: -- Verify the capability URI is one of:
-- * Outbox item URI of a local actor, i.e. a local activity -- * Outbox item URI of a local actor, i.e. a local activity
-- * A remote URI -- * A remote URI
cap <- nameExceptT "Invite capability" $ parseActivityURI' uCap cap <- nameExceptT "Remove.capability" $ parseActivityURI' uCap
-- Verify the capability is local -- Verify the capability is local
case cap of case cap of
@ -852,7 +852,7 @@ topicRemove grabActor topicResource topicField topicCollabField now topicKey (Ve
let author = bimap (view _1) (remoteAuthorURI . view _1) authorIdMsig let author = bimap (view _1) (remoteAuthorURI . view _1) authorIdMsig
(resource, member) <- parseRemove author remove (resource, member) <- parseRemove author remove
unless (Left (topicResource topicKey) == resource) $ unless (Left (topicResource topicKey) == resource) $
throwE "Remove topic isn't me" throwE "Remove topic isn't my collabs URI"
return member return member
maybeNew <- withDBExcept $ do maybeNew <- withDBExcept $ do
@ -1056,7 +1056,7 @@ topicJoin grabActor topicResource topicField topicCollabField collabTopicCtor no
-- Check input -- Check input
(role, resource) <- parseJoin join (role, resource) <- parseJoin join
unless (resource == Left (topicResource topicKey)) $ unless (resource == Left (topicResource topicKey)) $
throwE "Join's object isn't me, don't need this Join" throwE "Join's object isn't my collabs URI, don't need this Join"
maybeNew <- withDBExcept $ do maybeNew <- withDBExcept $ do

View file

@ -481,12 +481,17 @@ clientInvite now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHost
(_role, resource, recipient) <- parseInvite (Left $ LocalActorPerson personMeID) invite (_role, resource, recipient) <- parseInvite (Left $ LocalActorPerson personMeID) invite
_capID <- fromMaybeE maybeCap "No capability provided" _capID <- fromMaybeE maybeCap "No capability provided"
-- If resource is remote, HTTP GET it and its managing actor, and insert to -- If resource collabs URI is remote, HTTP GET it and its resource and its
-- our DB. If resource is local, find it in our DB. -- managing actor, and insert to our DB. If resource is local, find it in
-- our DB.
resourceDB <- resourceDB <-
bitraverse bitraverse
(withDBExcept . flip getGrantResource "Grant context not found in DB") (withDBExcept . flip getGrantResource "Grant context not found in DB")
(\ u@(ObjURI h lu) -> do (\ u@(ObjURI h luColl) -> do
manager <- asksEnv envHttpManager
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'"
instanceID <- instanceID <-
lift $ withDB $ either entityKey id <$> insertBy' (Instance h) lift $ withDB $ either entityKey id <$> insertBy' (Instance h)
result <- result <-
@ -605,11 +610,23 @@ clientRemove now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHost
(resource, member) <- parseRemove (Left $ LocalActorPerson personMeID) remove (resource, member) <- parseRemove (Left $ LocalActorPerson personMeID) remove
_capID <- fromMaybeE maybeCap "No capability provided" _capID <- fromMaybeE maybeCap "No capability provided"
-- If resource collabs is remote, HTTP GET it to determine resource
resource' <-
bitraverse
pure
(\ (ObjURI h luColl) -> do
manager <- asksEnv envHttpManager
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'"
return $ ObjURI h lu
)
resource
-- Verify that resource is addressed by the Remove -- Verify that resource is addressed by the Remove
bitraverse_ bitraverse_
(verifyResourceAddressed localRecips) (verifyResourceAddressed localRecips)
(verifyRemoteAddressed remoteRecips) (verifyRemoteAddressed remoteRecips)
resource resource'
-- Verify that member is addressed by the Remove -- Verify that member is addressed by the Remove
bitraverse_ bitraverse_
@ -624,7 +641,7 @@ clientRemove now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHost
bitraverse bitraverse
(flip getGrantResource "Resource not found in DB") (flip getGrantResource "Resource not found in DB")
pure pure
resource resource'
-- If member is local, find it in our DB -- If member is local, find it in our DB
_memberDB <- _memberDB <-
@ -644,7 +661,7 @@ clientRemove now personMeID (ClientMsg maybeCap localRecips remoteRecips fwdHost
-- Prepare local recipients for Remove delivery -- Prepare local recipients for Remove delivery
sieve <- lift $ do sieve <- lift $ do
resourceHash <- bitraverse hashGrantResource' pure resource resourceHash <- bitraverse hashGrantResource' pure resource'
recipientHash <- bitraverse hashGrantRecip pure member recipientHash <- bitraverse hashGrantRecip pure member
senderHash <- encodeKeyHashid personMeID senderHash <- encodeKeyHashid personMeID
let sieveActors = catMaybes let sieveActors = catMaybes

View file

@ -977,17 +977,27 @@ invite
-> FedURI -> FedURI
-> AP.Role -> AP.Role
-> ExceptT Text Handler (Maybe HTML, [Aud URIMode], AP.Invite URIMode) -> ExceptT Text Handler (Maybe HTML, [Aud URIMode], AP.Invite URIMode)
invite personID uRecipient uResource role = do invite personID uRecipient uResourceCollabs role = do
theater <- asksSite appTheater theater <- asksSite appTheater
env <- asksSite appEnv env <- asksSite appEnv
let activity = AP.Invite role uRecipient uResource let activity = AP.Invite role uRecipient uResourceCollabs
(_role, resource, recipient) <- (_role, resource, recipient) <-
runActE $ parseInvite (Left $ LocalActorPerson personID) activity runActE $ parseInvite (Left $ LocalActorPerson personID) activity
-- If resource is remote, we need to get it from DB/HTTP to determine its -- If resource collabs is remote, we need to get it from DB/HTTP to
-- managing actor & followers collection -- determine the resourc & its managing actor & followers collection
resource' <-
bitraverse
pure
(\ (ObjURI h luColl) -> do
manager <- asksSite appHttpManager
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'"
return $ ObjURI h lu
)
resource
resourceDB <- resourceDB <-
bitraverse bitraverse
hashGrantResource hashGrantResource
@ -1003,7 +1013,7 @@ invite personID uRecipient uResource role = do
Right (_objectID, luManager, (Entity _ actor)) -> Right (_objectID, luManager, (Entity _ actor)) ->
return (actor, ObjURI h luManager) return (actor, ObjURI h luManager)
) )
resource resource'
-- If target is remote, get it via HTTP/DB to determine its followers -- If target is remote, get it via HTTP/DB to determine its followers
-- collection -- collection
@ -1060,15 +1070,28 @@ remove
-> FedURI -> FedURI
-> FedURI -> FedURI
-> ExceptT Text Handler (Maybe HTML, [Aud URIMode], AP.Remove URIMode) -> ExceptT Text Handler (Maybe HTML, [Aud URIMode], AP.Remove URIMode)
remove personID uRecipient uResource = do remove personID uRecipient uResourceCollabs = do
theater <- asksSite appTheater theater <- asksSite appTheater
env <- asksSite appEnv env <- asksSite appEnv
let activity = AP.Remove uRecipient uResource let activity = AP.Remove uRecipient uResourceCollabs
(resource, recipient) <- (resource, recipient) <-
runActE $ parseRemove (Left $ LocalActorPerson personID) activity runActE $ parseRemove (Left $ LocalActorPerson personID) activity
-- If resource collabs is remote, we need to HTTP GET it to determine the
-- resource via collection 'context'
resource' <-
bitraverse
pure
(\ (ObjURI h luColl) -> do
manager <- asksSite appHttpManager
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'"
return $ ObjURI h lu
)
resource
-- If resource is remote, we need to get it from DB/HTTP to determine its -- If resource is remote, we need to get it from DB/HTTP to determine its
-- managing actor & followers collection -- managing actor & followers collection
resourceDB <- resourceDB <-
@ -1086,7 +1109,7 @@ remove personID uRecipient uResource = do
Right (_objectID, luManager, (Entity _ actor)) -> Right (_objectID, luManager, (Entity _ actor)) ->
return (actor, ObjURI h luManager) return (actor, ObjURI h luManager)
) )
resource resource'
-- If target is remote, get it via HTTP/DB to determine its followers -- If target is remote, get it via HTTP/DB to determine its followers
-- collection -- collection

View file

@ -92,6 +92,12 @@ parseGrantResource (LoomR l) = Just $ GrantResourceLoom l
parseGrantResource (ProjectR l) = Just $ GrantResourceProject l parseGrantResource (ProjectR l) = Just $ GrantResourceProject l
parseGrantResource _ = Nothing parseGrantResource _ = Nothing
parseGrantResourceCollabs (RepoCollabsR r) = Just $ GrantResourceRepo r
parseGrantResourceCollabs (DeckCollabsR d) = Just $ GrantResourceDeck d
parseGrantResourceCollabs (LoomCollabsR l) = Just $ GrantResourceLoom l
parseGrantResourceCollabs (ProjectCollabsR l) = Just $ GrantResourceProject l
parseGrantResourceCollabs _ = Nothing
data GrantRecipBy f = GrantRecipPerson (f Person) data GrantRecipBy f = GrantRecipPerson (f Person)
deriving (Generic, FunctorB, TraversableB, ConstraintsB) deriving (Generic, FunctorB, TraversableB, ConstraintsB)
@ -133,8 +139,8 @@ parseTopic u = do
(\ route -> do (\ route -> do
resourceHash <- resourceHash <-
fromMaybeE fromMaybeE
(parseGrantResource route) (parseGrantResourceCollabs route)
"Not a shared resource route" "Not a shared resource collabs route"
unhashGrantResourceE' unhashGrantResourceE'
resourceHash resourceHash
"Contains invalid hashid" "Contains invalid hashid"

View file

@ -911,6 +911,8 @@ instance YesodBreadcrumbs App where
RepoStampR r k -> ("Stamp #" <> keyHashidText k, Just $ RepoR r) RepoStampR r k -> ("Stamp #" <> keyHashidText k, Just $ RepoR r)
RepoCollabsR r -> ("Collaborators", Just $ RepoR r)
DeckR d -> ("Ticket Tracker =" <> keyHashidText d, Just HomeR) DeckR d -> ("Ticket Tracker =" <> keyHashidText d, Just HomeR)
DeckInboxR d -> ("Inbox", Just $ DeckR d) DeckInboxR d -> ("Inbox", Just $ DeckR d)
DeckOutboxR d -> ("Outbox", Just $ DeckR d) DeckOutboxR d -> ("Outbox", Just $ DeckR d)
@ -965,6 +967,8 @@ instance YesodBreadcrumbs App where
LoomStampR l k -> ("Stamp #" <> keyHashidText k, Just $ LoomR l) LoomStampR l k -> ("Stamp #" <> keyHashidText k, Just $ LoomR l)
LoomCollabsR l -> ("Collaborators", Just $ LoomR l)
ClothR l c -> ("#" <> keyHashidText c, Just $ LoomClothsR l) ClothR l c -> ("#" <> keyHashidText c, Just $ LoomClothsR l)
ClothDiscussionR l c -> ("Discussion", Just $ ClothR l c) ClothDiscussionR l c -> ("Discussion", Just $ ClothR l c)
ClothEventsR l c -> ("Events", Just $ ClothR l c) ClothEventsR l c -> ("Events", Just $ ClothR l c)

View file

@ -1185,7 +1185,7 @@ postPublishMergeR = do
inviteForm = renderDivs $ (,,,) inviteForm = renderDivs $ (,,,)
<$> areq fedUriField "(URI) Whom to invite" Nothing <$> areq fedUriField "(URI) Whom to invite" Nothing
<*> areq fedUriField "(URI) Resource" Nothing <*> areq fedUriField "(URI) Resource's collaborators collection" Nothing
<*> areq roleField "Role" Nothing <*> areq roleField "Role" Nothing
<*> areq capField "(URI) Grant activity to use for authorization" Nothing <*> areq capField "(URI) Grant activity to use for authorization" Nothing
where where
@ -1207,14 +1207,14 @@ postPublishInviteR = do
federation <- getsYesod $ appFederation . appSettings federation <- getsYesod $ appFederation . appSettings
unless federation badMethod unless federation badMethod
(uRecipient, uResource, role, (uCap, cap)) <- (uRecipient, uResourceCollabs, role, (uCap, cap)) <-
runFormPostRedirect PublishInviteR inviteForm runFormPostRedirect PublishInviteR inviteForm
(ep@(Entity pid _), a) <- getSender (ep@(Entity pid _), a) <- getSender
senderHash <- encodeKeyHashid pid senderHash <- encodeKeyHashid pid
result <- runExceptT $ do result <- runExceptT $ do
(maybeSummary, audience, inv) <- invite pid uRecipient uResource role (maybeSummary, audience, inv) <- invite pid uRecipient uResourceCollabs role
(localRecips, remoteRecips, fwdHosts, action) <- (localRecips, remoteRecips, fwdHosts, action) <-
makeServerInput (Just uCap) maybeSummary audience (AP.InviteActivity inv) makeServerInput (Just uCap) maybeSummary audience (AP.InviteActivity inv)
handleViaActor pid (Just cap) localRecips remoteRecips fwdHosts action handleViaActor pid (Just cap) localRecips remoteRecips fwdHosts action
@ -1229,7 +1229,7 @@ postPublishInviteR = do
removeForm = renderDivs $ (,,) removeForm = renderDivs $ (,,)
<$> areq fedUriField "(URI) Whom to remove" Nothing <$> areq fedUriField "(URI) Whom to remove" Nothing
<*> areq fedUriField "(URI) From which resource" Nothing <*> areq fedUriField "(URI) From which resource collaborators collection" Nothing
<*> areq capField "(URI) Grant activity to use for authorization" Nothing <*> areq capField "(URI) Grant activity to use for authorization" Nothing
getPublishRemoveR :: Handler Html getPublishRemoveR :: Handler Html
@ -1248,14 +1248,14 @@ postPublishRemoveR = do
federation <- getsYesod $ appFederation . appSettings federation <- getsYesod $ appFederation . appSettings
unless federation badMethod unless federation badMethod
(uRecipient, uResource, (uCap, cap)) <- (uRecipient, uResourceCollabs, (uCap, cap)) <-
runFormPostRedirect PublishRemoveR removeForm runFormPostRedirect PublishRemoveR removeForm
(ep@(Entity pid _), a) <- getSender (ep@(Entity pid _), a) <- getSender
senderHash <- encodeKeyHashid pid senderHash <- encodeKeyHashid pid
result <- runExceptT $ do result <- runExceptT $ do
(maybeSummary, audience, rmv) <- remove pid uRecipient uResource (maybeSummary, audience, rmv) <- remove pid uRecipient uResourceCollabs
(localRecips, remoteRecips, fwdHosts, action) <- (localRecips, remoteRecips, fwdHosts, action) <-
makeServerInput (Just uCap) maybeSummary audience (AP.RemoveActivity rmv) makeServerInput (Just uCap) maybeSummary audience (AP.RemoveActivity rmv)
handleViaActor pid (Just cap) localRecips remoteRecips fwdHosts action handleViaActor pid (Just cap) localRecips remoteRecips fwdHosts action

View file

@ -457,8 +457,8 @@ postDeckInviteR deckHash = do
result <- runExceptT $ do result <- runExceptT $ do
(maybeSummary, audience, invite) <- do (maybeSummary, audience, invite) <- do
let uRecipient = encodeRouteHome $ PersonR recipPersonHash let uRecipient = encodeRouteHome $ PersonR recipPersonHash
uResource = encodeRouteHome $ DeckR deckHash uResourceCollabs = encodeRouteHome $ DeckCollabsR deckHash
C.invite personID uRecipient uResource role C.invite personID uRecipient uResourceCollabs role
grantID <- do grantID <- do
maybeItem <- lift $ runDB $ getGrant CollabTopicDeckCollab CollabTopicDeckDeck deckID personID maybeItem <- lift $ runDB $ getGrant CollabTopicDeckCollab CollabTopicDeckDeck deckID personID
fromMaybeE maybeItem "You need to be a collaborator in the Deck to invite people" fromMaybeE maybeItem "You need to be a collaborator in the Deck to invite people"
@ -506,8 +506,8 @@ postDeckRemoveR deckHash ctID = do
case pidOrU of case pidOrU of
Left pid -> encodeRouteHome . PersonR <$> encodeKeyHashid pid Left pid -> encodeRouteHome . PersonR <$> encodeKeyHashid pid
Right u -> pure u Right u -> pure u
let uResource = encodeRouteHome $ DeckR deckHash let uResourceCollabs = encodeRouteHome $ DeckCollabsR deckHash
C.remove personID uRecipient uResource C.remove personID uRecipient uResourceCollabs
grantID <- do grantID <- do
maybeItem <- lift $ runDB $ getGrant CollabTopicDeckCollab CollabTopicDeckDeck deckID personID maybeItem <- lift $ runDB $ getGrant CollabTopicDeckCollab CollabTopicDeckDeck deckID personID
fromMaybeE maybeItem "You need to be a collaborator in the Deck to remove people" fromMaybeE maybeItem "You need to be a collaborator in the Deck to remove people"

View file

@ -30,6 +30,8 @@ module Vervis.Handler.Loom
, postLoomUnfollowR , postLoomUnfollowR
, getLoomStampR , getLoomStampR
, getLoomCollabsR
) )
where where
@ -339,3 +341,6 @@ postLoomUnfollowR _ = error "Temporarily disabled"
getLoomStampR :: KeyHashid Loom -> KeyHashid SigKey -> Handler TypedContent getLoomStampR :: KeyHashid Loom -> KeyHashid SigKey -> Handler TypedContent
getLoomStampR = servePerActorKey loomActor LocalActorLoom getLoomStampR = servePerActorKey loomActor LocalActorLoom
getLoomCollabsR :: KeyHashid Loom -> Handler TypedContent
getLoomCollabsR loomHash = error "TODO getLoomCollabsR"

View file

@ -268,8 +268,8 @@ postProjectInviteR projectHash = do
result <- runExceptT $ do result <- runExceptT $ do
(maybeSummary, audience, invite) <- do (maybeSummary, audience, invite) <- do
let uRecipient = encodeRouteHome $ PersonR recipPersonHash let uRecipient = encodeRouteHome $ PersonR recipPersonHash
uResource = encodeRouteHome $ ProjectR projectHash uResourceCollabs = encodeRouteHome $ ProjectCollabsR projectHash
C.invite personID uRecipient uResource role C.invite personID uRecipient uResourceCollabs role
grantID <- do grantID <- do
maybeItem <- lift $ runDB $ getGrant CollabTopicProjectCollab CollabTopicProjectProject projectID personID maybeItem <- lift $ runDB $ getGrant CollabTopicProjectCollab CollabTopicProjectProject projectID personID
fromMaybeE maybeItem "You need to be a collaborator in the Project to invite people" fromMaybeE maybeItem "You need to be a collaborator in the Project to invite people"
@ -317,8 +317,8 @@ postProjectRemoveR projectHash ctID = do
case pidOrU of case pidOrU of
Left pid -> encodeRouteHome . PersonR <$> encodeKeyHashid pid Left pid -> encodeRouteHome . PersonR <$> encodeKeyHashid pid
Right u -> pure u Right u -> pure u
let uResource = encodeRouteHome $ ProjectR projectHash let uResourceCollabs = encodeRouteHome $ ProjectCollabsR projectHash
C.remove personID uRecipient uResource C.remove personID uRecipient uResourceCollabs
grantID <- do grantID <- do
maybeItem <- lift $ runDB $ getGrant CollabTopicProjectCollab CollabTopicProjectProject projectID personID maybeItem <- lift $ runDB $ getGrant CollabTopicProjectCollab CollabTopicProjectProject projectID personID
fromMaybeE maybeItem "You need to be a collaborator in the Project to remove people" fromMaybeE maybeItem "You need to be a collaborator in the Project to remove people"

View file

@ -48,6 +48,8 @@ module Vervis.Handler.Repo
, getRepoStampR , getRepoStampR
, getRepoCollabsR
@ -772,6 +774,9 @@ postRepoLinkR repoHash loomHash = do
getRepoStampR :: KeyHashid Repo -> KeyHashid SigKey -> Handler TypedContent getRepoStampR :: KeyHashid Repo -> KeyHashid SigKey -> Handler TypedContent
getRepoStampR = servePerActorKey repoActor LocalActorRepo getRepoStampR = servePerActorKey repoActor LocalActorRepo
getRepoCollabsR :: KeyHashid Repo -> Handler TypedContent
getRepoCollabsR repoHash = error "TODO getRepoCollabsR"

View file

@ -197,6 +197,8 @@
/repos/#RepoKeyHashid/stamps/#SigKeyKeyHashid RepoStampR GET /repos/#RepoKeyHashid/stamps/#SigKeyKeyHashid RepoStampR GET
/repos/#RepoKeyHashid/collabs RepoCollabsR GET
---- Deck -------------------------------------------------------------------- ---- Deck --------------------------------------------------------------------
/decks/#DeckKeyHashid DeckR GET /decks/#DeckKeyHashid DeckR GET
@ -271,6 +273,8 @@
/looms/#LoomKeyHashid/stamps/#SigKeyKeyHashid LoomStampR GET /looms/#LoomKeyHashid/stamps/#SigKeyKeyHashid LoomStampR GET
/looms/#LoomKeyHashid/collabs LoomCollabsR GET
---- Cloth ------------------------------------------------------------------- ---- Cloth -------------------------------------------------------------------
/looms/#LoomKeyHashid/cloths/#TicketLoomKeyHashid ClothR GET /looms/#LoomKeyHashid/cloths/#TicketLoomKeyHashid ClothR GET