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 (..)
|
||||
, LocalRecipientSet
|
||||
, concatRecipients
|
||||
, parseLocalActor
|
||||
, parseAudience
|
||||
, actorRecips
|
||||
)
|
||||
|
|
|
@ -129,7 +129,7 @@ handleSharerInbox
|
|||
-> ActivityAuthentication
|
||||
-> ActivityBody
|
||||
-> ExceptT Text Handler Text
|
||||
handleSharerInbox _now shrRecip (ActivityAuthLocalPerson pidAuthor) body = do
|
||||
handleSharerInbox _now shrRecip (ActivityAuthLocal (ActivityAuthLocalPerson pidAuthor)) body = do
|
||||
(shrActivity, obiid) <- do
|
||||
luAct <-
|
||||
fromMaybeE
|
||||
|
@ -173,7 +173,7 @@ handleSharerInbox _now shrRecip (ActivityAuthLocalPerson pidAuthor) body = do
|
|||
"Activity already exists in inbox of /s/" <> recip
|
||||
Just _ ->
|
||||
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
|
||||
luAct <-
|
||||
fromMaybeE
|
||||
|
@ -217,6 +217,50 @@ handleSharerInbox _now shrRecip (ActivityAuthLocalProject jidAuthor) body = do
|
|||
"Activity already exists in inbox of /s/" <> recip
|
||||
Just _ ->
|
||||
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 =
|
||||
case activitySpecific $ actbActivity body of
|
||||
AcceptActivity accept ->
|
||||
|
@ -231,7 +275,7 @@ handleSharerInbox now shrRecip (ActivityAuthRemote author) body =
|
|||
sharerRejectF shrRecip now author body reject
|
||||
UndoActivity undo ->
|
||||
sharerUndoF shrRecip now author body undo
|
||||
_ -> return "Unsupported activity type"
|
||||
_ -> return "Unsupported activity type for sharers"
|
||||
|
||||
handleProjectInbox
|
||||
:: UTCTime
|
||||
|
@ -243,14 +287,7 @@ handleProjectInbox
|
|||
handleProjectInbox now shrRecip prjRecip auth body = do
|
||||
remoteAuthor <-
|
||||
case auth of
|
||||
ActivityAuthLocalPerson pid ->
|
||||
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)
|
||||
ActivityAuthLocal local -> throwE $ errorLocalForwarded local
|
||||
ActivityAuthRemote ra -> return ra
|
||||
case activitySpecific $ actbActivity body of
|
||||
CreateActivity (Create note) ->
|
||||
|
@ -261,7 +298,17 @@ handleProjectInbox now shrRecip prjRecip auth body = do
|
|||
projectOfferTicketF now shrRecip prjRecip remoteAuthor body offer
|
||||
UndoActivity 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
|
||||
:: UTCTime
|
||||
|
@ -273,21 +320,24 @@ handleRepoInbox
|
|||
handleRepoInbox now shrRecip rpRecip auth body = do
|
||||
remoteAuthor <-
|
||||
case auth of
|
||||
ActivityAuthLocalPerson pid ->
|
||||
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)
|
||||
ActivityAuthLocal local -> throwE $ errorLocalForwarded local
|
||||
ActivityAuthRemote ra -> return ra
|
||||
case activitySpecific $ actbActivity body of
|
||||
FollowActivity follow ->
|
||||
repoFollowF shrRecip rpRecip now remoteAuthor body follow
|
||||
UndoActivity 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 = do
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
module Vervis.Federation.Auth
|
||||
( RemoteAuthor (..)
|
||||
, ActivityAuthenticationLocal (..)
|
||||
, ActivityAuthentication (..)
|
||||
, ActivityBody (..)
|
||||
, authenticateActivity
|
||||
|
@ -93,6 +94,7 @@ import Database.Persist.Local
|
|||
import Yesod.Persist.Local
|
||||
|
||||
import Vervis.ActivityPub
|
||||
import Vervis.ActivityPub.Recipient
|
||||
import Vervis.ActorKey
|
||||
import Vervis.FedURI
|
||||
import Vervis.Foundation
|
||||
|
@ -107,9 +109,13 @@ data RemoteAuthor = RemoteAuthor
|
|||
, remoteAuthorId :: RemoteActorId
|
||||
}
|
||||
|
||||
data ActivityAuthentication
|
||||
data ActivityAuthenticationLocal
|
||||
= ActivityAuthLocalPerson PersonId
|
||||
| ActivityAuthLocalProject ProjectId
|
||||
| ActivityAuthLocalRepo RepoId
|
||||
|
||||
data ActivityAuthentication
|
||||
= ActivityAuthLocal ActivityAuthenticationLocal
|
||||
| ActivityAuthRemote RemoteAuthor
|
||||
|
||||
data ActivityBody = ActivityBody
|
||||
|
@ -260,26 +266,25 @@ verifySelfSig
|
|||
-> LocalRefURI
|
||||
-> ByteString
|
||||
-> Signature
|
||||
-> ExceptT String Handler (Either PersonId ProjectId)
|
||||
-> ExceptT String Handler ActivityAuthenticationLocal
|
||||
verifySelfSig luAuthor (LocalRefURI lruKey) input (Signature sig) = do
|
||||
author <- do
|
||||
route <-
|
||||
case decodeRouteLocal luAuthor of
|
||||
Nothing -> throwE "Local author ID isn't a valid route"
|
||||
Just r -> return r
|
||||
case route of
|
||||
SharerR shr -> return $ Left shr
|
||||
ProjectR shr prj -> return $ Right (shr, prj)
|
||||
_ -> throwE "Local author ID isn't an actor route"
|
||||
fromMaybeE
|
||||
(decodeRouteLocal luAuthor)
|
||||
"Local author ID isn't a valid route"
|
||||
fromMaybeE
|
||||
(parseLocalActor route)
|
||||
"Local author ID isn't an actor route"
|
||||
akey <- do
|
||||
route <- do
|
||||
luKey <-
|
||||
case lruKey of
|
||||
Left l -> return l
|
||||
Right _ -> throwE "Local key ID has a fragment"
|
||||
case decodeRouteLocal luKey of
|
||||
Nothing -> throwE "Local key ID isn't a valid route"
|
||||
Just r -> return r
|
||||
fromMaybeE
|
||||
(decodeRouteLocal luKey)
|
||||
"Local key ID isn't a valid route"
|
||||
(akey1, akey2, _) <- liftIO . readTVarIO =<< getsYesod appActorKeys
|
||||
case route of
|
||||
ActorKey1R -> return akey1
|
||||
|
@ -290,18 +295,21 @@ verifySelfSig luAuthor (LocalRefURI lruKey) input (Signature sig) = do
|
|||
unless valid $
|
||||
throwE "Self sig verification says not valid"
|
||||
ExceptT $ runDB $ do
|
||||
mauthorId <- runMaybeT $ bitraverse getPerson getProject author
|
||||
mauthorId <- runMaybeT $ getLocalActor author
|
||||
return $
|
||||
case mauthorId of
|
||||
Nothing -> Left "Local author: No such user/project"
|
||||
Just id_ -> Right id_
|
||||
where
|
||||
getPerson shr = do
|
||||
getLocalActor (LocalActorSharer shr) = do
|
||||
sid <- MaybeT $ getKeyBy $ UniqueSharer shr
|
||||
MaybeT $ getKeyBy $ UniquePersonIdent sid
|
||||
getProject (shr, prj) = do
|
||||
ActivityAuthLocalPerson <$> MaybeT (getKeyBy $ UniquePersonIdent sid)
|
||||
getLocalActor (LocalActorProject shr prj) = do
|
||||
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
|
||||
:: Host
|
||||
|
@ -314,11 +322,8 @@ verifyForwardedSig hAuthor luAuthor (Verification malgo keyid input signature) =
|
|||
throwE "Author and forwarded sig key on different hosts"
|
||||
local <- hostIsLocal hKey
|
||||
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)
|
||||
where
|
||||
mkauth (Left pid) = ActivityAuthLocalPerson pid
|
||||
mkauth (Right jid) = ActivityAuthLocalProject jid
|
||||
|
||||
verifyContentTypeAP :: MonadHandler m => m ()
|
||||
verifyContentTypeAP = do
|
||||
|
|
Loading…
Reference in a new issue