mirror of
https://code.sup39.dev/repos/Wqawg
synced 2024-12-29 14:04:53 +09:00
Fix handling of forwarded activities from local repos
This commit is contained in:
parent
e96749a19e
commit
1e8dd71f23
3 changed files with 98 additions and 42 deletions
|
@ -24,6 +24,7 @@ module Vervis.ActivityPub.Recipient
|
||||||
, LocalSharerRelatedSet (..)
|
, LocalSharerRelatedSet (..)
|
||||||
, LocalRecipientSet
|
, LocalRecipientSet
|
||||||
, concatRecipients
|
, concatRecipients
|
||||||
|
, parseLocalActor
|
||||||
, parseAudience
|
, parseAudience
|
||||||
, actorRecips
|
, actorRecips
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue