1
0
Fork 0
mirror of https://code.sup39.dev/repos/Wqawg synced 2024-12-31 06:44:51 +09:00

Fix handling of forwarded activities from local repos

This commit is contained in:
fr33domlover 2019-10-18 23:20:48 +00:00
parent e96749a19e
commit 1e8dd71f23
3 changed files with 98 additions and 42 deletions

View file

@ -24,6 +24,7 @@ module Vervis.ActivityPub.Recipient
, LocalSharerRelatedSet (..) , LocalSharerRelatedSet (..)
, LocalRecipientSet , LocalRecipientSet
, concatRecipients , concatRecipients
, parseLocalActor
, parseAudience , parseAudience
, actorRecips , actorRecips
) )

View file

@ -129,7 +129,7 @@ handleSharerInbox
-> ActivityAuthentication -> ActivityAuthentication
-> ActivityBody -> ActivityBody
-> ExceptT Text Handler Text -> ExceptT Text Handler Text
handleSharerInbox _now shrRecip (ActivityAuthLocalPerson pidAuthor) body = do handleSharerInbox _now shrRecip (ActivityAuthLocal (ActivityAuthLocalPerson pidAuthor)) body = do
(shrActivity, obiid) <- do (shrActivity, obiid) <- do
luAct <- luAct <-
fromMaybeE fromMaybeE
@ -173,7 +173,7 @@ handleSharerInbox _now shrRecip (ActivityAuthLocalPerson pidAuthor) body = do
"Activity already exists in inbox of /s/" <> recip "Activity already exists in inbox of /s/" <> recip
Just _ -> Just _ ->
return $ "Activity inserted to inbox of /s/" <> recip return $ "Activity inserted to inbox of /s/" <> recip
handleSharerInbox _now shrRecip (ActivityAuthLocalProject jidAuthor) body = do handleSharerInbox _now shrRecip (ActivityAuthLocal (ActivityAuthLocalProject jidAuthor)) body = do
(shrActivity, prjActivity, obiid) <- do (shrActivity, prjActivity, obiid) <- do
luAct <- luAct <-
fromMaybeE fromMaybeE
@ -217,6 +217,50 @@ handleSharerInbox _now shrRecip (ActivityAuthLocalProject jidAuthor) body = do
"Activity already exists in inbox of /s/" <> recip "Activity already exists in inbox of /s/" <> recip
Just _ -> Just _ ->
return $ "Activity inserted to inbox of /s/" <> recip return $ "Activity inserted to inbox of /s/" <> recip
handleSharerInbox _now shrRecip (ActivityAuthLocal (ActivityAuthLocalRepo ridAuthor)) body = do
(shrActivity, rpActivity, obiid) <- do
luAct <-
fromMaybeE
(activityId $ actbActivity body)
"Local activity: No 'id'"
route <-
fromMaybeE
(decodeRouteLocal luAct)
"Local activity: Not a valid route"
case route of
RepoOutboxItemR shr rp obikhid ->
(shr,rp,) <$> decodeKeyHashidE obikhid "Local activity: ID is invalid hashid"
_ -> throwE "Local activity: Not an activity route"
runDBExcept $ do
Entity pidRecip personRecip <- lift $ do
sid <- getKeyBy404 $ UniqueSharer shrRecip
getBy404 $ UniquePersonIdent sid
mobi <- lift $ get obiid
obi <- fromMaybeE mobi "Local activity: No such ID in DB"
mridOutbox <-
lift $ getKeyBy $ UniqueRepoOutbox $ outboxItemOutbox obi
ridOutbox <-
fromMaybeE mridOutbox "Local activity not in a repo outbox"
r <- lift $ getJust ridOutbox
s <- lift $ getJust $ repoSharer r
unless (sharerIdent s == shrActivity) $
throwE "Local activity: ID invalid, hashid and author shr mismatch"
unless (repoIdent r == rpActivity) $
throwE "Local activity: ID invalid, hashid and author rp mismatch"
unless (ridAuthor == ridOutbox) $
throwE "Activity author in DB and in received JSON don't match"
lift $ do
ibiid <- insert $ InboxItem True
let ibid = personInbox personRecip
miblid <- insertUnique $ InboxItemLocal ibid obiid ibiid
let recip = shr2text shrRecip
case miblid of
Nothing -> do
delete ibiid
return $
"Activity already exists in inbox of /s/" <> recip
Just _ ->
return $ "Activity inserted to inbox of /s/" <> recip
handleSharerInbox now shrRecip (ActivityAuthRemote author) body = handleSharerInbox now shrRecip (ActivityAuthRemote author) body =
case activitySpecific $ actbActivity body of case activitySpecific $ actbActivity body of
AcceptActivity accept -> AcceptActivity accept ->
@ -231,7 +275,7 @@ handleSharerInbox now shrRecip (ActivityAuthRemote author) body =
sharerRejectF shrRecip now author body reject sharerRejectF shrRecip now author body reject
UndoActivity undo -> UndoActivity undo ->
sharerUndoF shrRecip now author body undo sharerUndoF shrRecip now author body undo
_ -> return "Unsupported activity type" _ -> return "Unsupported activity type for sharers"
handleProjectInbox handleProjectInbox
:: UTCTime :: UTCTime
@ -243,14 +287,7 @@ handleProjectInbox
handleProjectInbox now shrRecip prjRecip auth body = do handleProjectInbox now shrRecip prjRecip auth body = do
remoteAuthor <- remoteAuthor <-
case auth of case auth of
ActivityAuthLocalPerson pid -> ActivityAuthLocal local -> throwE $ errorLocalForwarded local
throwE $
"Project inbox got local forwarded activity by pid#" <>
T.pack (show $ fromSqlKey pid)
ActivityAuthLocalProject jid ->
throwE $
"Project inbox got local forwarded activity by jid#" <>
T.pack (show $ fromSqlKey jid)
ActivityAuthRemote ra -> return ra ActivityAuthRemote ra -> return ra
case activitySpecific $ actbActivity body of case activitySpecific $ actbActivity body of
CreateActivity (Create note) -> CreateActivity (Create note) ->
@ -261,7 +298,17 @@ handleProjectInbox now shrRecip prjRecip auth body = do
projectOfferTicketF now shrRecip prjRecip remoteAuthor body offer projectOfferTicketF now shrRecip prjRecip remoteAuthor body offer
UndoActivity undo -> UndoActivity undo ->
projectUndoF shrRecip prjRecip now remoteAuthor body undo projectUndoF shrRecip prjRecip now remoteAuthor body undo
_ -> return "Unsupported activity type" _ -> return "Unsupported activity type for projects"
where
errorLocalForwarded (ActivityAuthLocalPerson pid) =
"Project inbox got local forwarded activity by pid#" <>
T.pack (show $ fromSqlKey pid)
errorLocalForwarded (ActivityAuthLocalProject jid) =
"Project inbox got local forwarded activity by jid#" <>
T.pack (show $ fromSqlKey jid)
errorLocalForwarded (ActivityAuthLocalRepo rid) =
"Project inbox got local forwarded activity by rid#" <>
T.pack (show $ fromSqlKey rid)
handleRepoInbox handleRepoInbox
:: UTCTime :: UTCTime
@ -273,21 +320,24 @@ handleRepoInbox
handleRepoInbox now shrRecip rpRecip auth body = do handleRepoInbox now shrRecip rpRecip auth body = do
remoteAuthor <- remoteAuthor <-
case auth of case auth of
ActivityAuthLocalPerson pid -> ActivityAuthLocal local -> throwE $ errorLocalForwarded local
throwE $
"Repo inbox got local forwarded activity by pid#" <>
T.pack (show $ fromSqlKey pid)
ActivityAuthLocalProject jid ->
throwE $
"Repo inbox got local forwarded activity by jid#" <>
T.pack (show $ fromSqlKey jid)
ActivityAuthRemote ra -> return ra ActivityAuthRemote ra -> return ra
case activitySpecific $ actbActivity body of case activitySpecific $ actbActivity body of
FollowActivity follow -> FollowActivity follow ->
repoFollowF shrRecip rpRecip now remoteAuthor body follow repoFollowF shrRecip rpRecip now remoteAuthor body follow
UndoActivity undo-> UndoActivity undo->
repoUndoF shrRecip rpRecip now remoteAuthor body undo repoUndoF shrRecip rpRecip now remoteAuthor body undo
_ -> return "Unsupported activity type" _ -> return "Unsupported activity type for repos"
where
errorLocalForwarded (ActivityAuthLocalPerson pid) =
"Repo inbox got local forwarded activity by pid#" <>
T.pack (show $ fromSqlKey pid)
errorLocalForwarded (ActivityAuthLocalProject jid) =
"Repo inbox got local forwarded activity by jid#" <>
T.pack (show $ fromSqlKey jid)
errorLocalForwarded (ActivityAuthLocalRepo rid) =
"Repo inbox got local forwarded activity by rid#" <>
T.pack (show $ fromSqlKey rid)
fixRunningDeliveries :: (MonadIO m, MonadLogger m, IsSqlBackend backend) => ReaderT backend m () fixRunningDeliveries :: (MonadIO m, MonadLogger m, IsSqlBackend backend) => ReaderT backend m ()
fixRunningDeliveries = do fixRunningDeliveries = do

View file

@ -15,6 +15,7 @@
module Vervis.Federation.Auth module Vervis.Federation.Auth
( RemoteAuthor (..) ( RemoteAuthor (..)
, ActivityAuthenticationLocal (..)
, ActivityAuthentication (..) , ActivityAuthentication (..)
, ActivityBody (..) , ActivityBody (..)
, authenticateActivity , authenticateActivity
@ -93,6 +94,7 @@ import Database.Persist.Local
import Yesod.Persist.Local import Yesod.Persist.Local
import Vervis.ActivityPub import Vervis.ActivityPub
import Vervis.ActivityPub.Recipient
import Vervis.ActorKey import Vervis.ActorKey
import Vervis.FedURI import Vervis.FedURI
import Vervis.Foundation import Vervis.Foundation
@ -107,9 +109,13 @@ data RemoteAuthor = RemoteAuthor
, remoteAuthorId :: RemoteActorId , remoteAuthorId :: RemoteActorId
} }
data ActivityAuthentication data ActivityAuthenticationLocal
= ActivityAuthLocalPerson PersonId = ActivityAuthLocalPerson PersonId
| ActivityAuthLocalProject ProjectId | ActivityAuthLocalProject ProjectId
| ActivityAuthLocalRepo RepoId
data ActivityAuthentication
= ActivityAuthLocal ActivityAuthenticationLocal
| ActivityAuthRemote RemoteAuthor | ActivityAuthRemote RemoteAuthor
data ActivityBody = ActivityBody data ActivityBody = ActivityBody
@ -260,26 +266,25 @@ verifySelfSig
-> LocalRefURI -> LocalRefURI
-> ByteString -> ByteString
-> Signature -> Signature
-> ExceptT String Handler (Either PersonId ProjectId) -> ExceptT String Handler ActivityAuthenticationLocal
verifySelfSig luAuthor (LocalRefURI lruKey) input (Signature sig) = do verifySelfSig luAuthor (LocalRefURI lruKey) input (Signature sig) = do
author <- do author <- do
route <- route <-
case decodeRouteLocal luAuthor of fromMaybeE
Nothing -> throwE "Local author ID isn't a valid route" (decodeRouteLocal luAuthor)
Just r -> return r "Local author ID isn't a valid route"
case route of fromMaybeE
SharerR shr -> return $ Left shr (parseLocalActor route)
ProjectR shr prj -> return $ Right (shr, prj) "Local author ID isn't an actor route"
_ -> throwE "Local author ID isn't an actor route"
akey <- do akey <- do
route <- do route <- do
luKey <- luKey <-
case lruKey of case lruKey of
Left l -> return l Left l -> return l
Right _ -> throwE "Local key ID has a fragment" Right _ -> throwE "Local key ID has a fragment"
case decodeRouteLocal luKey of fromMaybeE
Nothing -> throwE "Local key ID isn't a valid route" (decodeRouteLocal luKey)
Just r -> return r "Local key ID isn't a valid route"
(akey1, akey2, _) <- liftIO . readTVarIO =<< getsYesod appActorKeys (akey1, akey2, _) <- liftIO . readTVarIO =<< getsYesod appActorKeys
case route of case route of
ActorKey1R -> return akey1 ActorKey1R -> return akey1
@ -290,18 +295,21 @@ verifySelfSig luAuthor (LocalRefURI lruKey) input (Signature sig) = do
unless valid $ unless valid $
throwE "Self sig verification says not valid" throwE "Self sig verification says not valid"
ExceptT $ runDB $ do ExceptT $ runDB $ do
mauthorId <- runMaybeT $ bitraverse getPerson getProject author mauthorId <- runMaybeT $ getLocalActor author
return $ return $
case mauthorId of case mauthorId of
Nothing -> Left "Local author: No such user/project" Nothing -> Left "Local author: No such user/project"
Just id_ -> Right id_ Just id_ -> Right id_
where where
getPerson shr = do getLocalActor (LocalActorSharer shr) = do
sid <- MaybeT $ getKeyBy $ UniqueSharer shr sid <- MaybeT $ getKeyBy $ UniqueSharer shr
MaybeT $ getKeyBy $ UniquePersonIdent sid ActivityAuthLocalPerson <$> MaybeT (getKeyBy $ UniquePersonIdent sid)
getProject (shr, prj) = do getLocalActor (LocalActorProject shr prj) = do
sid <- MaybeT $ getKeyBy $ UniqueSharer shr sid <- MaybeT $ getKeyBy $ UniqueSharer shr
MaybeT $ getKeyBy $ UniqueProject prj sid ActivityAuthLocalProject <$> MaybeT (getKeyBy $ UniqueProject prj sid)
getLocalActor (LocalActorRepo shr rp) = do
sid <- MaybeT $ getKeyBy $ UniqueSharer shr
ActivityAuthLocalRepo <$> MaybeT (getKeyBy $ UniqueRepo rp sid)
verifyForwardedSig verifyForwardedSig
:: Host :: Host
@ -314,11 +322,8 @@ verifyForwardedSig hAuthor luAuthor (Verification malgo keyid input signature) =
throwE "Author and forwarded sig key on different hosts" throwE "Author and forwarded sig key on different hosts"
local <- hostIsLocal hKey local <- hostIsLocal hKey
if local if local
then mkauth <$> verifySelfSig luAuthor luKey input signature then ActivityAuthLocal <$> verifySelfSig luAuthor luKey input signature
else ActivityAuthRemote <$> verifyActorSig' malgo input signature hKey luKey (Just luAuthor) else ActivityAuthRemote <$> verifyActorSig' malgo input signature hKey luKey (Just luAuthor)
where
mkauth (Left pid) = ActivityAuthLocalPerson pid
mkauth (Right jid) = ActivityAuthLocalProject jid
verifyContentTypeAP :: MonadHandler m => m () verifyContentTypeAP :: MonadHandler m => m ()
verifyContentTypeAP = do verifyContentTypeAP = do