C2S: grantC: Insert Collab records for Grants with remote topics too

This commit is contained in:
fr33domlover 2022-08-28 13:51:43 +00:00
parent 06c520f6aa
commit d741d0e918
4 changed files with 285 additions and 122 deletions

View file

@ -45,6 +45,7 @@ import Crypto.Hash
import Data.Aeson import Data.Aeson
import Data.Barbie import Data.Barbie
import Data.Bifunctor import Data.Bifunctor
import Data.Bifoldable
import Data.Bitraversable import Data.Bitraversable
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.Either import Data.Either
@ -1472,6 +1473,13 @@ followC (Entity pidSender personSender) summary audience follow@(AP.Follow uObje
data GrantRecipBy f = GrantRecipPerson (f Person) data GrantRecipBy f = GrantRecipPerson (f Person)
deriving (Generic, FunctorB, TraversableB, ConstraintsB) deriving (Generic, FunctorB, TraversableB, ConstraintsB)
data Result
= ResultSomeException SomeException
| ResultIdMismatch
| ResultGetError APGetError
| ResultNotActor
deriving Show
grantC grantC
:: Entity Person :: Entity Person
-> Actor -> Actor
@ -1483,14 +1491,12 @@ grantC
grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
-- Check input -- Check input
(resourceK, recipientK) <- parseGrant grant (resource, recipient) <- parseGrant grant
let input = adaptGrant resourceK recipientK
ParsedAudience localRecips remoteRecips blinded fwdHosts <- do ParsedAudience localRecips remoteRecips blinded fwdHosts <- do
mrecips <- parseAudience audience mrecips <- parseAudience audience
recips <- fromMaybeE mrecips "Create TicketTracker with no recipients" recips <- fromMaybeE mrecips "Grant with no recipients"
checkFederation $ paudRemoteActors recips checkFederation $ paudRemoteActors recips
return recips return recips
verifyRecipients input localRecips remoteRecips
-- 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
@ -1498,44 +1504,70 @@ grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
uCap <- fromMaybeE muCap "No capability provided" uCap <- fromMaybeE muCap "No capability provided"
capID <- parseActivityURI "Grant capability" uCap capID <- parseActivityURI "Grant capability" uCap
-- If resource is remote, HTTP GET it and its managing actor, and insert to
-- our DB. If resource is local, find it in our DB.
resourceDB <-
bitraverse
(runDBExcept . flip getGrantResource "Grant context not found in DB")
(\ u@(ObjURI h lu) -> do
instanceID <-
lift $ runDB $ either entityKey id <$> insertBy' (Instance h)
result <-
ExceptT $ first (T.pack . show) <$>
fetchRemoteResource instanceID h lu
case result of
Left (Entity actorID actor) ->
return (remoteActorIdent actor, actorID, u)
Right (objectID, luManager, (Entity actorID _)) ->
return (objectID, actorID, ObjURI h luManager)
)
resource
-- If recipient is remote, HTTP GET it, make sure it's an actor, and insert -- If recipient is remote, HTTP GET it, make sure it's an actor, and insert
-- it to our DB -- it to our DB. If recipient is local, find it in our DB.
inputHttp <- for input $ \ (resource, recipient) -> recipientDB <-
fmap (resource,) $ bifor recipient pure $ \ (ObjURI h lu) -> do bitraverse
instanceID <- (runDBExcept . flip getGrantRecip "Grant recipient not found in DB")
lift $ runDB $ either entityKey id <$> insertBy' (Instance h) (\ u@(ObjURI h lu) -> do
result <- instanceID <-
ExceptT $ first (T.pack . displayException) <$> lift $ runDB $ either entityKey id <$> insertBy' (Instance h)
fetchRemoteActor instanceID h lu result <-
case result of ExceptT $ first (T.pack . displayException) <$>
Left Nothing -> throwE "Recipient @id mismatch" fetchRemoteActor instanceID h lu
Left (Just err) -> throwE $ T.pack $ displayException err case result of
Right Nothing -> throwE "Recipient isn't an actor" Left Nothing -> throwE "Recipient @id mismatch"
Right (Just actor) -> return $ entityKey actor Left (Just err) -> throwE $ T.pack $ displayException err
Right Nothing -> throwE "Recipient isn't an actor"
Right (Just actor) -> return (entityKey actor, u)
)
recipient
-- Verify that resource and recipient are addressed by the Grant
bitraverse_
(verifyResourceAddressed localRecips . bmap entityKey)
(\ (_, _, u) -> verifyRemoteAddressed remoteRecips u)
resourceDB
bitraverse_
(verifyRecipientAddressed localRecips . bmap entityKey)
(verifyRemoteAddressed remoteRecips . snd)
recipientDB
now <- liftIO getCurrentTime now <- liftIO getCurrentTime
senderHash <- encodeKeyHashid pidUser senderHash <- encodeKeyHashid pidUser
(obiidGrant, deliverHttpGrant) <- runDBExcept $ do (obiidGrant, deliverHttpGrant) <- runDBExcept $ do
-- Find resource (if local) and recipient (if local) in DB -- If resource is local, verify the specified capability gives relevant
inputDB <- -- access. If resource is remote, check the specified capability as
for inputHttp $ bitraverse -- much as we can, letting the remote resource say the final word.
(flip getGrantResource "Grant context not found in DB") bitraverse_
(bitraverse (verifyCapability capID pidUser . bmap entityKey)
(flip getGrantRecip "Grant recipient not found in DB") (verifyCapabilityRemote capID pidUser . (\ (o, _, _) -> o))
pure resourceDB
)
-- If resource is loca, verify the specified capability gives relevant
-- access
for_ inputDB $ \ (resource, _) ->
verifyCapability capID pidUser (bmap entityKey resource)
-- Insert new Collab to DB -- Insert new Collab to DB
grantID <- lift $ insertEmptyOutboxItem (actorOutbox senderActor) now grantID <- lift $ insertEmptyOutboxItem (actorOutbox senderActor) now
for_ inputDB $ \ (resource, recipient) -> lift $ insertCollab resourceDB recipientDB grantID
lift $ insertCollab resource recipient grantID
-- Insert the Grant activity to author's outbox -- Insert the Grant activity to author's outbox
docGrant <- lift $ insertGrantToOutbox senderHash now uCap blinded grantID docGrant <- lift $ insertGrantToOutbox senderHash now uCap blinded grantID
@ -1543,48 +1575,52 @@ grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
-- Deliver the Grant activity to local recipients, and schedule -- Deliver the Grant activity to local recipients, and schedule
-- delivery for unavailable remote recipients -- delivery for unavailable remote recipients
remoteRecipsHttpGrant <- do remoteRecipsHttpGrant <- do
resourceH <- bitraverse hashGrantResource pure resourceK resourceHash <- bitraverse hashGrantResource pure resource
recipientH <- bitraverse hashGrantRecip pure recipientK recipientHash <- bitraverse hashGrantRecip pure recipient
let actors = catMaybes let sieveActors = catMaybes
[ case resourceH of [ case resourceHash of
Left (GrantResourceRepo r) -> Just $ LocalActorRepo r Left (GrantResourceRepo r) -> Just $ LocalActorRepo r
Left (GrantResourceDeck d) -> Just $ LocalActorDeck d Left (GrantResourceDeck d) -> Just $ LocalActorDeck d
Left (GrantResourceLoom l) -> Just $ LocalActorLoom l Left (GrantResourceLoom l) -> Just $ LocalActorLoom l
Right _ -> Nothing Right _ -> Nothing
, case recipientH of , case recipientHash of
Left (GrantRecipPerson p) -> Just $ LocalActorPerson p Left (GrantRecipPerson p) -> Just $ LocalActorPerson p
Right _ -> Nothing Right _ -> Nothing
] ]
stages = catMaybes sieveStages = catMaybes
[ Just $ LocalStagePersonFollowers senderHash [ Just $ LocalStagePersonFollowers senderHash
, case resourceH of , case resourceHash of
Left (GrantResourceRepo r) -> Just $ LocalStageRepoFollowers r Left (GrantResourceRepo r) -> Just $ LocalStageRepoFollowers r
Left (GrantResourceDeck d) -> Just $ LocalStageDeckFollowers d Left (GrantResourceDeck d) -> Just $ LocalStageDeckFollowers d
Left (GrantResourceLoom l) -> Just $ LocalStageLoomFollowers l Left (GrantResourceLoom l) -> Just $ LocalStageLoomFollowers l
Right _ -> Nothing Right _ -> Nothing
, case recipientH of , case recipientHash of
Left (GrantRecipPerson p) -> Just $ LocalStagePersonFollowers p Left (GrantRecipPerson p) -> Just $ LocalStagePersonFollowers p
Right _ -> Nothing Right _ -> Nothing
] ]
sieve = makeRecipientSet actors stages sieve = makeRecipientSet sieveActors sieveStages
moreRemoteRecips <- moreRemoteRecips <-
lift $ deliverLocal' True (LocalActorPerson senderHash) (personActor personUser) grantID $ lift $ deliverLocal' True (LocalActorPerson senderHash) (personActor personUser) grantID $
localRecipSieve sieve False localRecips localRecipSieve sieve False localRecips
checkFederation moreRemoteRecips checkFederation moreRemoteRecips
lift $ deliverRemoteDB'' fwdHosts grantID remoteRecips moreRemoteRecips lift $ deliverRemoteDB'' fwdHosts grantID remoteRecips moreRemoteRecips
-- For local resource/recipient, verify they've received the Grant -- If resource is local, verify it has received the Grant
for_ inputDB $ \ (resource, recipient) -> do case resourceDB of
let resourceActorID = Left localResource -> do
case resource of let resourceActorID =
GrantResourceRepo (Entity _ r) -> repoActor r case localResource of
GrantResourceDeck (Entity _ d) -> deckActor d GrantResourceRepo (Entity _ r) -> repoActor r
GrantResourceLoom (Entity _ l) -> loomActor l GrantResourceDeck (Entity _ d) -> deckActor d
verifyActorHasItem resourceActorID grantID "Local topic didn't receive the Grant" GrantResourceLoom (Entity _ l) -> loomActor l
case recipient of verifyActorHasItem resourceActorID grantID "Local topic didn't receive the Grant"
Left (GrantRecipPerson (Entity _ p)) -> Right _ -> pure ()
verifyActorHasItem (personActor p) grantID "Local recipient didn't receive the Grant"
Right _ -> return () -- If recipient is local, verify it has received the grant
case recipientDB of
Left (GrantRecipPerson (Entity _ p)) ->
verifyActorHasItem (personActor p) grantID "Local recipient didn't receive the Grant"
Right _ -> pure ()
-- Return instructions for HTTP delivery to remote recipients -- Return instructions for HTTP delivery to remote recipients
return return
@ -1600,6 +1636,42 @@ grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
where where
parseGrantResource (RepoR r) = Just $ GrantResourceRepo r
parseGrantResource (DeckR d) = Just $ GrantResourceDeck d
parseGrantResource (LoomR l) = Just $ GrantResourceLoom l
parseGrantResource _ = Nothing
unhashGrantResourcePure ctx = f
where
f (GrantResourceRepo r) =
GrantResourceRepo <$> decodeKeyHashidPure ctx r
f (GrantResourceDeck d) =
GrantResourceDeck <$> decodeKeyHashidPure ctx d
f (GrantResourceLoom l) =
GrantResourceLoom <$> decodeKeyHashidPure ctx l
unhashGrantResource resource = do
ctx <- asksSite siteHashidsContext
return $ unhashGrantResourcePure ctx resource
unhashGrantResourceE resource e =
ExceptT $ maybe (Left e) Right <$> unhashGrantResource resource
parseGrantRecip (PersonR p) = Just $ GrantRecipPerson p
parseGrantRecip _ = Nothing
unhashGrantRecipPure ctx = f
where
f (GrantRecipPerson p) =
GrantRecipPerson <$> decodeKeyHashidPure ctx p
unhashGrantRecip resource = do
ctx <- asksSite siteHashidsContext
return $ unhashGrantRecipPure ctx resource
unhashGrantRecipE resource e =
ExceptT $ maybe (Left e) Right <$> unhashGrantRecip resource
parseGrant parseGrant
:: Grant URIMode :: Grant URIMode
-> ExceptT Text Handler -> ExceptT Text Handler
@ -1630,24 +1702,6 @@ grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
resourceHash resourceHash
"Grant resource contains invalid hashid" "Grant resource contains invalid hashid"
else pure $ Right u else pure $ Right u
where
parseGrantResource (RepoR r) = Just $ GrantResourceRepo r
parseGrantResource (DeckR d) = Just $ GrantResourceDeck d
parseGrantResource (LoomR l) = Just $ GrantResourceLoom l
parseGrantResource _ = Nothing
unhashGrantResourcePure ctx = f
where
f (GrantResourceRepo r) =
GrantResourceRepo <$> decodeKeyHashidPure ctx r
f (GrantResourceDeck d) =
GrantResourceDeck <$> decodeKeyHashidPure ctx d
f (GrantResourceLoom l) =
GrantResourceLoom <$> decodeKeyHashidPure ctx l
unhashGrantResource resource = do
ctx <- asksSite siteHashidsContext
return $ unhashGrantResourcePure ctx resource
unhashGrantResourceE resource e =
ExceptT $ maybe (Left e) Right <$> unhashGrantResource resource
parseTarget u@(ObjURI h lu) = do parseTarget u@(ObjURI h lu) = do
hl <- hostIsLocal h hl <- hostIsLocal h
if hl if hl
@ -1669,48 +1723,42 @@ grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
throwE "Grant sender and recipient are the same Person" throwE "Grant sender and recipient are the same Person"
_ -> return recipKey _ -> return recipKey
else pure $ Right u else pure $ Right u
where
parseGrantRecip (PersonR p) = Just $ GrantRecipPerson p
parseGrantRecip _ = Nothing
unhashGrantRecipPure ctx = f
where
f (GrantRecipPerson p) =
GrantRecipPerson <$> decodeKeyHashidPure ctx p
unhashGrantRecip resource = do
ctx <- asksSite siteHashidsContext
return $ unhashGrantRecipPure ctx resource
unhashGrantRecipE resource e =
ExceptT $ maybe (Left e) Right <$> unhashGrantRecip resource
adaptGrant fetchRemoteResource instanceID host localURI = do
:: Either (GrantResourceBy Key) FedURI maybeActor <- runSiteDB $ runMaybeT $ do
-> Either (GrantRecipBy Key) FedURI roid <- MaybeT $ getKeyBy $ UniqueRemoteObject instanceID localURI
-> Maybe (GrantResourceBy Key, Either (GrantRecipBy Key) FedURI) MaybeT $ getBy $ UniqueRemoteActor roid
adaptGrant (Right _) _ = Nothing case maybeActor of
adaptGrant (Left resource) recip = Just (resource, recip) Just actor -> return $ Right $ Left actor
Nothing -> do
verifyRecipients input localRecips remoteRecips = manager <- asksSite getHttpManager
for_ input $ \ (resourceK, recipientK) -> do errorOrResource <- fetchResource manager host localURI
resourceH <- hashGrantResource resourceK case errorOrResource of
recipientH <- bitraverse hashGrantRecip pure recipientK Left maybeError ->
fromMaybeE (verifyResource resourceH) "Local resource not addressed" return $ Left $ maybe ResultIdMismatch ResultGetError maybeError
fromMaybeE (verifyRecip recipientH) "Recipient not addressed" Right resource -> do
where case resource of
verifyResource (GrantResourceRepo r) = do ResourceActor (AP.Actor local detail) -> runSiteDB $ do
routes <- lookup r $ recipRepos localRecips roid <- either entityKey id <$> insertBy' (RemoteObject instanceID localURI)
guard $ routeRepo routes let ra = RemoteActor
verifyResource (GrantResourceDeck d) = do { remoteActorIdent = roid
routes <- lookup d $ recipDecks localRecips , remoteActorName =
guard $ routeDeck $ familyDeck routes AP.actorName detail <|> AP.actorUsername detail
verifyResource (GrantResourceLoom l) = do , remoteActorInbox = AP.actorInbox local
routes <- lookup l $ recipLooms localRecips , remoteActorFollowers = AP.actorFollowers local
guard $ routeLoom $ familyLoom routes , remoteActorErrorSince = Nothing
verifyRecip (Left (GrantRecipPerson p)) = do }
routes <- lookup p $ recipPeople localRecips Right . Left . either id id <$> insertByEntity' ra
guard $ routePerson routes ResourceChild luId luManager -> do
verifyRecip (Right (ObjURI h lu)) = do roid <- runSiteDB $ either entityKey id <$> insertBy' (RemoteObject instanceID localURI)
lus <- lookup h remoteRecips result <- fetchRemoteActor instanceID host luManager
guard $ lu `elem` lus return $
case result of
Left e -> Left $ ResultSomeException e
Right (Left Nothing) -> Left ResultIdMismatch
Right (Left (Just e)) -> Left $ ResultGetError e
Right (Right Nothing) -> Left ResultNotActor
Right (Right (Just actor)) -> Right $ Right (roid, luManager, actor)
getGrantResource (GrantResourceRepo k) e = getGrantResource (GrantResourceRepo k) e =
GrantResourceRepo <$> getEntityE k e GrantResourceRepo <$> getEntityE k e
@ -1721,20 +1769,53 @@ grantC (Entity pidUser personUser) senderActor muCap summary audience grant = do
getGrantRecip (GrantRecipPerson k) e = GrantRecipPerson <$> getEntityE k e getGrantRecip (GrantRecipPerson k) e = GrantRecipPerson <$> getEntityE k e
verifyResourceAddressed localRecips resource = do
resourceHash <- hashGrantResource resource
fromMaybeE (verify resourceHash) "Local resource not addressed"
where
verify (GrantResourceRepo r) = do
routes <- lookup r $ recipRepos localRecips
guard $ routeRepo routes
verify (GrantResourceDeck d) = do
routes <- lookup d $ recipDecks localRecips
guard $ routeDeck $ familyDeck routes
verify (GrantResourceLoom l) = do
routes <- lookup l $ recipLooms localRecips
guard $ routeLoom $ familyLoom routes
verifyRecipientAddressed localRecips recipient = do
recipientHash <- hashGrantRecip recipient
fromMaybeE (verify recipientHash) "Recipient not addressed"
where
verify (GrantRecipPerson p) = do
routes <- lookup p $ recipPeople localRecips
guard $ routePerson routes
verifyRemoteAddressed remoteRecips u =
fromMaybeE (verify u) "Given remote entity not addressed"
where
verify (ObjURI h lu) = do
lus <- lookup h remoteRecips
guard $ lu `elem` lus
insertCollab resource recipient grantID = do insertCollab resource recipient grantID = do
collabID <- insert Collab collabID <- insert Collab
case resource of case resource of
GrantResourceRepo (Entity repoID _) -> Left local ->
insert_ $ CollabTopicLocalRepo collabID repoID case local of
GrantResourceDeck (Entity deckID _) -> GrantResourceRepo (Entity repoID _) ->
insert_ $ CollabTopicLocalDeck collabID deckID insert_ $ CollabTopicLocalRepo collabID repoID
GrantResourceLoom (Entity loomID _) -> GrantResourceDeck (Entity deckID _) ->
insert_ $ CollabTopicLocalLoom collabID loomID insert_ $ CollabTopicLocalDeck collabID deckID
GrantResourceLoom (Entity loomID _) ->
insert_ $ CollabTopicLocalLoom collabID loomID
Right (remoteID, _, _) ->
insert_ $ CollabTopicRemote collabID remoteID Nothing
insert_ $ CollabSenderLocal collabID grantID insert_ $ CollabSenderLocal collabID grantID
case recipient of case recipient of
Left (GrantRecipPerson (Entity personID _)) -> Left (GrantRecipPerson (Entity personID _)) ->
insert_ $ CollabRecipLocal collabID personID insert_ $ CollabRecipLocal collabID personID
Right remoteActorID -> Right (remoteActorID, _) ->
insert_ $ CollabRecipRemote collabID remoteActorID insert_ $ CollabRecipRemote collabID remoteActorID
hashGrantResource (GrantResourceRepo k) = hashGrantResource (GrantResourceRepo k) =

View file

@ -64,6 +64,7 @@ module Vervis.Access
, checkProjectAccess , checkProjectAccess
, GrantResourceBy (..) , GrantResourceBy (..)
, verifyCapability , verifyCapability
, verifyCapabilityRemote
) )
where where
@ -313,3 +314,66 @@ verifyCapability capability personID resource = do
-- Since there are currently no roles, and grants allow only the "Admin" -- Since there are currently no roles, and grants allow only the "Admin"
-- role that supports every operation, we don't need to check role access -- role that supports every operation, we don't need to check role access
return () return ()
verifyCapabilityRemote
:: Either (LocalActorBy KeyHashid, OutboxItemId) FedURI
-> PersonId
-> RemoteObjectId
-> ExceptT Text (ReaderT SqlBackend Handler) ()
verifyCapabilityRemote capability personID resourceID = do
-- Find the activity itself by URI in the DB
grant <- do
mact <- getActivity capability
fromMaybeE mact "Capability activity not known to me"
-- Find the Collab record for that activity
cid <-
case grant of
Left (_actor, obiid) -> do
mcsl <- lift $ getValBy $ UniqueCollabSenderLocalActivity obiid
collabSenderLocalCollab <$>
fromMaybeE mcsl "Capability is a local activity but no matching capability"
Right ractid -> do
mcsr <- lift $ getValBy $ UniqueCollabSenderRemoteActivity ractid
collabSenderRemoteCollab <$>
fromMaybeE mcsr "Capability is a known remote activity but no matching capability"
-- Find the recipient of that Collab
recipID <- do
mcrl <- lift $ getValBy $ UniqueCollabRecipLocal cid
crl <- fromMaybeE mcrl "No local recip for capability"
mcrr <- lift $ getBy $ UniqueCollabRecipRemote cid
for_ mcrr $ \ _ -> error "Both local & remote recip for capability!"
return $ collabRecipLocalPerson crl
-- Verify the recipient is the expected one
unless (recipID == personID) $
throwE "Collab recipient is some other Person"
-- Verify the topic isn't local
maybeRepo <- lift $ fmap (const ()) <$> getValBy (UniqueCollabTopicLocalRepo cid)
maybeDeck <- lift $ fmap (const ()) <$> getValBy (UniqueCollabTopicLocalDeck cid)
maybeLoom <- lift $ fmap (const ()) <$> getValBy (UniqueCollabTopicLocalLoom cid)
case length $ catMaybes [maybeRepo, maybeDeck, maybeLoom] of
0 -> return ()
1 -> throwE "Collab is for some other, local topic"
_ -> error "Collab with multiple topics"
-- Find the remote topic, on which this Collab gives access
topicID <- do
maybeRemote <- lift $ getValBy $ UniqueCollabTopicRemote cid
case maybeRemote of
Nothing -> error "Collab without topic"
Just remote -> return $ collabTopicRemoteTopic remote
-- Verify the topic matches the resource specified
unless (topicID == resourceID) $
throwE "Capability topic is some other remote resource"
-- Verify that the resource has accepted the grant, making it valid
maybeAccept <- lift $ getBy $ UniqueCollabTopicAcceptCollab cid
_ <- fromMaybeE maybeAccept "Collab not approved by the resource"
-- Since there are currently no roles, and grants allow only the "Admin"
-- role that supports every operation, we don't need to check role access
return ()

View file

@ -42,6 +42,7 @@ module Web.ActivityPub
, CollectionPageType (..) , CollectionPageType (..)
, CollectionPage (..) , CollectionPage (..)
, Recipient (..) , Recipient (..)
, Resource (..)
-- * Content objects -- * Content objects
, Note (..) , Note (..)
@ -99,6 +100,7 @@ module Web.ActivityPub
, fetchAPID , fetchAPID
, fetchAPID' , fetchAPID'
, fetchRecipient , fetchRecipient
, fetchResource
, keyListedByActor , keyListedByActor
, fetchUnknownKey , fetchUnknownKey
, fetchKnownPersonalKey , fetchKnownPersonalKey
@ -622,6 +624,19 @@ instance ActivityPub Recipient where
toSeries h (RecipientActor a) = toSeries h a toSeries h (RecipientActor a) = toSeries h a
toSeries h (RecipientCollection c) = toSeries h c toSeries h (RecipientCollection c) = toSeries h c
data Resource u = ResourceActor (Actor u) | ResourceChild LocalURI LocalURI
instance ActivityPub Resource where
jsonldContext _ = [as2Context, secContext, forgeContext]
parseObject o =
second ResourceActor <$> parseObject o <|> do
ObjURI h luId <- o .: "id" <|> o .: "@id"
(h,) . ResourceChild luId <$> withAuthorityO h (o .: "managedBy")
toSeries h (ResourceActor a) = toSeries h a
toSeries h (ResourceChild luId luManager)
= "id" .= ObjURI h luId
<> "managedBy" .= ObjURI h luManager
data Audience u = Audience data Audience u = Audience
{ audienceTo :: [ObjURI u] { audienceTo :: [ObjURI u]
, audienceBto :: [ObjURI u] , audienceBto :: [ObjURI u]
@ -1901,6 +1916,12 @@ fetchRecipient m = fetchAPID' m getId
getId (RecipientActor a) = actorId $ actorLocal a getId (RecipientActor a) = actorId $ actorLocal a
getId (RecipientCollection c) = collectionId c getId (RecipientCollection c) = collectionId c
fetchResource :: (MonadIO m, UriMode u) => Manager -> Authority u -> LocalURI -> m (Either (Maybe APGetError) (Resource u))
fetchResource m = fetchAPID' m getId
where
getId (ResourceActor a) = actorId $ actorLocal a
getId (ResourceChild luId _) = luId
fetchAPID :: (MonadIO m, UriMode u, ActivityPub a) => Manager -> (a u -> LocalURI) -> Authority u -> LocalURI -> m (Either String (a u)) fetchAPID :: (MonadIO m, UriMode u, ActivityPub a) => Manager -> (a u -> LocalURI) -> Authority u -> LocalURI -> m (Either String (a u))
fetchAPID m getId h lu = first showError <$> fetchAPID' m getId h lu fetchAPID m getId h lu = first showError <$> fetchAPID' m getId h lu
where where

View file

@ -620,9 +620,6 @@ CollabTopicAccept
UniqueCollabTopicAcceptCollab collab UniqueCollabTopicAcceptCollab collab
UniqueCollabTopicAcceptAccept accept UniqueCollabTopicAcceptAccept accept
-- Do we need this for S2S? Or is this just for the Client, to decide which
-- Grant URI to use as the 'capability'? If latter, look into removing this
-- table...
CollabTopicRemote CollabTopicRemote
collab CollabId collab CollabId
topic RemoteObjectId topic RemoteObjectId