Add noteAudience; record recipient of local remotely-targetted activities in DB

This commit is contained in:
fr33domlover 2019-03-23 02:57:34 +00:00
parent 58a56b6743
commit 0032456925
6 changed files with 84 additions and 63 deletions

View file

@ -225,6 +225,7 @@ TicketClaimRequest
Discussion Discussion
RemoteDiscussion RemoteDiscussion
sharer RemoteSharerId
instance InstanceId instance InstanceId
ident LocalURI ident LocalURI
discuss DiscussionId discuss DiscussionId

View file

@ -3,6 +3,7 @@ RemoteRawObject
received UTCTime received UTCTime
RemoteDiscussion RemoteDiscussion
sharer RemoteSharerId
instance InstanceId instance InstanceId
ident Text ident Text
discuss DiscussionId discuss DiscussionId

View file

@ -146,7 +146,7 @@ handleActivity raw hActor iidActor rsidActor (Activity _id _luActor audience spe
rm E.^. RemoteMessageLostParent E.==. E.just (E.val uNote) E.&&. rm E.^. RemoteMessageLostParent E.==. E.just (E.val uNote) E.&&.
m E.^. MessageRoot `op` E.val did m E.^. MessageRoot `op` E.val did
return (rm E.^. RemoteMessageId, m E.^. MessageId) return (rm E.^. RemoteMessageId, m E.^. MessageId)
handleCreate iidActor hActor rsidActor raw audience (Note mluNote _luAttrib muParent muContext mpublished content) = do handleCreate iidActor hActor rsidActor raw audience (Note mluNote _luAttrib _aud muParent muContext mpublished content) = do
luNote <- fromMaybeE mluNote "Got Create Note without note id" luNote <- fromMaybeE mluNote "Got Create Note without note id"
(shr, prj) <- do (shr, prj) <- do
uRecip <- parseAudience audience uRecip <- parseAudience audience

View file

@ -106,7 +106,7 @@ getDiscussionMessage shr lmid = selectRep $ provideAP $ runDB $ do
m <- getJust $ localMessageRest lm m <- getJust $ localMessageRest lm
route2fed <- getEncodeRouteFed route2fed <- getEncodeRouteFed
encodeHid <- getsYesod appHashidEncode encodeHid <- getsYesod appHashidEncode
uContext <- do (uRecip, uContext) <- do
let did = messageRoot m let did = messageRoot m
mt <- getValBy $ UniqueTicketDiscussion did mt <- getValBy $ UniqueTicketDiscussion did
mrd <- getValBy $ UniqueRemoteDiscussion did mrd <- getValBy $ UniqueRemoteDiscussion did
@ -116,11 +116,22 @@ getDiscussionMessage shr lmid = selectRep $ provideAP $ runDB $ do
(Just t, Nothing) -> do (Just t, Nothing) -> do
j <- getJust $ ticketProject t j <- getJust $ ticketProject t
s <- getJust $ projectSharer j s <- getJust $ projectSharer j
return $ route2fed $ let shr = sharerIdent s
TicketR (sharerIdent s) (projectIdent j) (ticketNumber t) prj = projectIdent j
return
( route2fed $ ProjectR shr prj
, route2fed $ TicketR shr prj $ ticketNumber t
)
(Nothing, Just rd) -> do (Nothing, Just rd) -> do
i <- getJust $ remoteDiscussionInstance rd let iid = remoteDiscussionInstance rd
return $ l2f (instanceHost i) (remoteDiscussionIdent rd) i <- getJust iid
rs <- getJust $ remoteDiscussionSharer rd
unless (iid == remoteSharerInstance rs) $
fail "RemoteDiscussion and its sharer on different hosts"
return
( l2f (instanceHost i) (remoteSharerIdent rs)
, l2f (instanceHost i) (remoteDiscussionIdent rd)
)
muParent <- for (messageParent m) $ \ midParent -> do muParent <- for (messageParent m) $ \ midParent -> do
mlocal <- getBy $ UniqueLocalMessage midParent mlocal <- getBy $ UniqueLocalMessage midParent
mremote <- getValBy $ UniqueRemoteMessage midParent mremote <- getValBy $ UniqueRemoteMessage midParent
@ -143,6 +154,7 @@ getDiscussionMessage shr lmid = selectRep $ provideAP $ runDB $ do
return $ Doc host Note return $ Doc host Note
{ noteId = Just $ route2local $ MessageR shr lmhid { noteId = Just $ route2local $ MessageR shr lmhid
, noteAttrib = route2local $ SharerR shr , noteAttrib = route2local $ SharerR shr
, noteAudience = deliverTo uRecip
, noteReplyTo = Just $ fromMaybe uContext muParent , noteReplyTo = Just $ fromMaybe uContext muParent
, noteContext = Just uContext , noteContext = Just uContext
, notePublished = Just $ messageCreated m , notePublished = Just $ messageCreated m

View file

@ -250,17 +250,12 @@ postOutboxR = do
activity = Activity activity = Activity
{ activityId = appendPath actor "/fake-activity" { activityId = appendPath actor "/fake-activity"
, activityActor = actor , activityActor = actor
, activityAudience = Audience , activityAudience = deliverTo to
{ audienceTo = V.singleton to
, audienceBto = V.empty
, audienceCc = V.empty
, audienceBcc = V.empty
, audienceGeneral = V.empty
}
, activitySpecific = CreateActivity Create , activitySpecific = CreateActivity Create
{ createObject = Note { createObject = Note
{ noteId = Just $ appendPath actor "/fake-note" { noteId = Just $ appendPath actor "/fake-note"
, noteAttrib = actor , noteAttrib = actor
, noteAudience = deliverTo to
, noteReplyTo = mparent , noteReplyTo = mparent
, noteContext = mcontext , noteContext = mcontext
, notePublished = Just now , notePublished = Just now

View file

@ -44,6 +44,7 @@ module Web.ActivityPub
-- * Utilities -- * Utilities
, publicURI , publicURI
, deliverTo
, hActivityPubActor , hActivityPubActor
, provideAP , provideAP
, APGetError (..) , APGetError (..)
@ -316,10 +317,67 @@ instance ActivityPub Actor where
<> "inbox" .= l2f host inbox <> "inbox" .= l2f host inbox
<> "publicKey" `pair` encodePublicKeySet host pkeys <> "publicKey" `pair` encodePublicKeySet host pkeys
data Audience = Audience
{ audienceTo :: Vector FedURI
, audienceBto :: Vector FedURI
, audienceCc :: Vector FedURI
, audienceBcc :: Vector FedURI
, audienceGeneral :: Vector FedURI
}
deliverTo :: FedURI -> Audience
deliverTo to = Audience
{ audienceTo = V.singleton to
, audienceBto = V.empty
, audienceCc = V.empty
, audienceBcc = V.empty
, audienceGeneral = V.empty
}
newtype AdaptAudience = AdaptAudience
{ unAdapt :: FedURI
}
instance FromJSON AdaptAudience where
parseJSON = parseJSON . adapt
where
adapt v =
case v of
String t
| t == "Public" -> String publicT
| t == "as:Public" -> String publicT
_ -> v
parseAudience :: Object -> Parser Audience
parseAudience o =
Audience
<$> o .:? "to" .!= V.empty
<*> o .:? "bto" .!= V.empty
<*> o .:? "cc" .!= V.empty
<*> o .:? "bcc" .!= V.empty
<*> o .:? "audience" .!= V.empty
where
obj .:& key = do
vec <- obj .:? key .!= V.empty
return $ unAdapt <$> vec
encodeAudience :: Audience -> Series
encodeAudience (Audience to bto cc bcc aud)
= "to" .=% to
<> "bto" .=% bto
<> "cc" .=% cc
<> "bcc" .=% bcc
<> "audience" .=% aud
where
t .=% v =
if V.null v
then mempty
else t .= v
data Note = Note data Note = Note
{ noteId :: Maybe LocalURI { noteId :: Maybe LocalURI
, noteAttrib :: LocalURI , noteAttrib :: LocalURI
--, noteTo :: FedURI , noteAudience :: Audience
, noteReplyTo :: Maybe FedURI , noteReplyTo :: Maybe FedURI
, noteContext :: Maybe FedURI , noteContext :: Maybe FedURI
, notePublished :: Maybe UTCTime , notePublished :: Maybe UTCTime
@ -350,14 +408,16 @@ instance ActivityPub Note where
Note Note
<$> withHostM h (fmap f2l <$> o .:? "id") <$> withHostM h (fmap f2l <$> o .:? "id")
<*> pure attrib <*> pure attrib
<*> parseAudience o
<*> o .:? "inReplyTo" <*> o .:? "inReplyTo"
<*> o .:? "context" <*> o .:? "context"
<*> o .:? "published" <*> o .:? "published"
<*> o .: "content" <*> o .: "content"
toSeries host (Note mid attrib mreply mcontext mpublished content) toSeries host (Note mid attrib aud mreply mcontext mpublished content)
= "type" .= ("Note" :: Text) = "type" .= ("Note" :: Text)
<> "id" .=? (l2f host <$> mid) <> "id" .=? (l2f host <$> mid)
<> "attributedTo" .= l2f host attrib <> "attributedTo" .= l2f host attrib
<> encodeAudience aud
<> "inReplyTo" .=? mreply <> "inReplyTo" .=? mreply
<> "context" .=? mcontext <> "context" .=? mcontext
<> "published" .=? mpublished <> "published" .=? mpublished
@ -452,54 +512,6 @@ parseReject o = Reject <$> o .: "object"
encodeReject :: Reject -> Series encodeReject :: Reject -> Series
encodeReject (Reject obj) = "object" .= obj encodeReject (Reject obj) = "object" .= obj
data Audience = Audience
{ audienceTo :: Vector FedURI
, audienceBto :: Vector FedURI
, audienceCc :: Vector FedURI
, audienceBcc :: Vector FedURI
, audienceGeneral :: Vector FedURI
}
newtype AdaptAudience = AdaptAudience
{ unAdapt :: FedURI
}
instance FromJSON AdaptAudience where
parseJSON = parseJSON . adapt
where
adapt v =
case v of
String t
| t == "Public" -> String publicT
| t == "as:Public" -> String publicT
_ -> v
parseAudience :: Object -> Parser Audience
parseAudience o =
Audience
<$> o .:? "to" .!= V.empty
<*> o .:? "bto" .!= V.empty
<*> o .:? "cc" .!= V.empty
<*> o .:? "bcc" .!= V.empty
<*> o .:? "audience" .!= V.empty
where
obj .:& key = do
vec <- obj .:? key .!= V.empty
return $ unAdapt <$> vec
encodeAudience :: Audience -> Series
encodeAudience (Audience to bto cc bcc aud)
= "to" .=% to
<> "bto" .=% bto
<> "cc" .=% cc
<> "bcc" .=% bcc
<> "audience" .=% aud
where
t .=% v =
if V.null v
then mempty
else t .= v
data SpecificActivity data SpecificActivity
= AcceptActivity Accept = AcceptActivity Accept
| CreateActivity Create | CreateActivity Create