Link to per-actor keys from actor documents

Per-actor keys are now fully supported in Vervis! Caveats:

- The HTTP Signature keys produced by Vervis are Ed25519 keys; software that
  expects only RSA keys will fail here
- Like instance keys, per-actor keys are currently served in separate
  documents, not embedded in the actor document; so software that expects
  embedded keys will fail here
This commit is contained in:
fr33domlover 2022-10-12 18:01:52 +00:00
parent 32c87e3839
commit 8424c76de7
5 changed files with 58 additions and 27 deletions

View file

@ -118,12 +118,17 @@ import qualified Vervis.Client as C
getDeckR :: KeyHashid Deck -> Handler TypedContent getDeckR :: KeyHashid Deck -> Handler TypedContent
getDeckR deckHash = do getDeckR deckHash = do
deckID <- decodeKeyHashid404 deckHash deckID <- decodeKeyHashid404 deckHash
(deck, repoIDs, actor) <- runDB $ do (deck, repoIDs, actor, sigKeyIDs) <- runDB $ do
d <- get404 deckID d <- get404 deckID
rs <- selectKeysList [RepoProject ==. Just deckID] [Asc RepoId] rs <- selectKeysList [RepoProject ==. Just deckID] [Asc RepoId]
(d,rs,) <$> getJust (deckActor d) let aid = deckActor d
a <- getJust aid
sigKeys <- selectKeysList [SigKeyActor ==. aid] [Asc SigKeyId]
return (d, rs, a, sigKeys)
encodeRouteLocal <- getEncodeRouteLocal encodeRouteLocal <- getEncodeRouteLocal
hashSigKey <- getEncodeKeyHashid
perActor <- asksSite $ appPerActorKeys . appSettings
let deckAP = AP.TicketTracker let deckAP = AP.TicketTracker
{ AP.ticketTrackerActor = AP.Actor { AP.ticketTrackerActor = AP.Actor
{ AP.actorLocal = AP.ActorLocal { AP.actorLocal = AP.ActorLocal
@ -135,9 +140,10 @@ getDeckR deckHash = do
Just $ encodeRouteLocal $ DeckFollowersR deckHash Just $ encodeRouteLocal $ DeckFollowersR deckHash
, AP.actorFollowing = Nothing , AP.actorFollowing = Nothing
, AP.actorPublicKeys = , AP.actorPublicKeys =
[ Left $ encodeRouteLocal ActorKey1R map (Left . encodeRouteLocal) $
, Left $ encodeRouteLocal ActorKey2R if perActor
] then map (DeckStampR deckHash . hashSigKey) sigKeyIDs
else [ActorKey1R, ActorKey2R]
, AP.actorSshKeys = [] , AP.actorSshKeys = []
} }
, AP.actorDetail = AP.ActorDetail , AP.actorDetail = AP.ActorDetail

View file

@ -56,6 +56,7 @@ import Network.FedURI
import Yesod.ActivityPub import Yesod.ActivityPub
import Yesod.FedURI import Yesod.FedURI
import Yesod.Hashids import Yesod.Hashids
import Yesod.MonadSite
import qualified Web.ActivityPub as AP import qualified Web.ActivityPub as AP
@ -64,16 +65,22 @@ import Vervis.FedURI
import Vervis.Foundation import Vervis.Foundation
import Vervis.Model import Vervis.Model
import Vervis.Recipient import Vervis.Recipient
import Vervis.Settings
import Vervis.Web.Actor import Vervis.Web.Actor
getGroupR :: KeyHashid Group -> Handler TypedContent getGroupR :: KeyHashid Group -> Handler TypedContent
getGroupR groupHash = do getGroupR groupHash = do
groupID <- decodeKeyHashid404 groupHash groupID <- decodeKeyHashid404 groupHash
(group, actor) <- runDB $ do (group, actor, sigKeyIDs) <- runDB $ do
g <- get404 groupID g <- get404 groupID
(g,) <$> getJust (groupActor g) let aid = groupActor g
a <- getJust aid
sigKeys <- selectKeysList [SigKeyActor ==. aid] [Asc SigKeyId]
return (g, a, sigKeys)
encodeRouteLocal <- getEncodeRouteLocal encodeRouteLocal <- getEncodeRouteLocal
hashSigKey <- getEncodeKeyHashid
perActor <- asksSite $ appPerActorKeys . appSettings
let route mk = encodeRouteLocal $ mk groupHash let route mk = encodeRouteLocal $ mk groupHash
groupAP = AP.Actor groupAP = AP.Actor
@ -84,9 +91,10 @@ getGroupR groupHash = do
, AP.actorFollowers = Just $ route GroupFollowersR , AP.actorFollowers = Just $ route GroupFollowersR
, AP.actorFollowing = Nothing , AP.actorFollowing = Nothing
, AP.actorPublicKeys = , AP.actorPublicKeys =
[ Left $ encodeRouteLocal ActorKey1R map (Left . encodeRouteLocal) $
, Left $ encodeRouteLocal ActorKey2R if perActor
] then map (GroupStampR groupHash . hashSigKey) sigKeyIDs
else [ActorKey1R, ActorKey2R]
, AP.actorSshKeys = [] , AP.actorSshKeys = []
} }
, AP.actorDetail = AP.ActorDetail , AP.actorDetail = AP.ActorDetail

View file

@ -94,11 +94,16 @@ import qualified Vervis.Client as C
getLoomR :: KeyHashid Loom -> Handler TypedContent getLoomR :: KeyHashid Loom -> Handler TypedContent
getLoomR loomHash = do getLoomR loomHash = do
loomID <- decodeKeyHashid404 loomHash loomID <- decodeKeyHashid404 loomHash
(loom, actor) <- runDB $ do (loom, actor, sigKeyIDs) <- runDB $ do
l <- get404 loomID l <- get404 loomID
(l,) <$> getJust (loomActor l) let aid = loomActor l
a <- getJust aid
sigKeys <- selectKeysList [SigKeyActor ==. aid] [Asc SigKeyId]
return (l, a, sigKeys)
encodeRouteLocal <- getEncodeRouteLocal encodeRouteLocal <- getEncodeRouteLocal
hashSigKey <- getEncodeKeyHashid
perActor <- asksSite $ appPerActorKeys . appSettings
let route mk = encodeRouteLocal $ mk loomHash let route mk = encodeRouteLocal $ mk loomHash
loomAP = AP.Actor loomAP = AP.Actor
{ AP.actorLocal = AP.ActorLocal { AP.actorLocal = AP.ActorLocal
@ -108,9 +113,10 @@ getLoomR loomHash = do
, AP.actorFollowers = Just $ route LoomFollowersR , AP.actorFollowers = Just $ route LoomFollowersR
, AP.actorFollowing = Nothing , AP.actorFollowing = Nothing
, AP.actorPublicKeys = , AP.actorPublicKeys =
[ Left $ encodeRouteLocal ActorKey1R map (Left . encodeRouteLocal) $
, Left $ encodeRouteLocal ActorKey2R if perActor
] then map (LoomStampR loomHash . hashSigKey) sigKeyIDs
else [ActorKey1R, ActorKey2R]
, AP.actorSshKeys = [] , AP.actorSshKeys = []
} }
, AP.actorDetail = AP.ActorDetail , AP.actorDetail = AP.ActorDetail

View file

@ -90,13 +90,17 @@ import Vervis.Widget.Person
getPersonR :: KeyHashid Person -> Handler TypedContent getPersonR :: KeyHashid Person -> Handler TypedContent
getPersonR personHash = do getPersonR personHash = do
personID <- decodeKeyHashid404 personHash personID <- decodeKeyHashid404 personHash
(person, actor, sshKeyIDs) <- runDB $ do (person, actor, sigKeyIDs, sshKeyIDs) <- runDB $ do
p <- get404 personID p <- get404 personID
a <- getJust $ personActor p let aid = personActor p
ks <- selectKeysList [SshKeyPerson ==. personID] [Asc SshKeyId] a <- getJust aid
return (p, a, ks) sigKeys <- selectKeysList [SigKeyActor ==. aid] [Asc SigKeyId]
sshKeys <- selectKeysList [SshKeyPerson ==. personID] [Asc SshKeyId]
return (p, a, sigKeys, sshKeys)
encodeRouteLocal <- getEncodeRouteLocal encodeRouteLocal <- getEncodeRouteLocal
hashSigKey <- getEncodeKeyHashid
hashSshKey <- getEncodeKeyHashid hashSshKey <- getEncodeKeyHashid
perActor <- asksSite $ appPerActorKeys . appSettings
let personAP = AP.Actor let personAP = AP.Actor
{ AP.actorLocal = AP.ActorLocal { AP.actorLocal = AP.ActorLocal
@ -106,9 +110,10 @@ getPersonR personHash = do
, AP.actorFollowers = Just $ encodeRouteLocal $ PersonFollowersR personHash , AP.actorFollowers = Just $ encodeRouteLocal $ PersonFollowersR personHash
, AP.actorFollowing = Just $ encodeRouteLocal $ PersonFollowingR personHash , AP.actorFollowing = Just $ encodeRouteLocal $ PersonFollowingR personHash
, AP.actorPublicKeys = , AP.actorPublicKeys =
[ Left $ encodeRouteLocal ActorKey1R map (Left . encodeRouteLocal) $
, Left $ encodeRouteLocal ActorKey2R if perActor
] then map (PersonStampR personHash . hashSigKey) sigKeyIDs
else [ActorKey1R, ActorKey2R]
, AP.actorSshKeys = , AP.actorSshKeys =
map (encodeRouteLocal . SshKeyR personHash . hashSshKey) sshKeyIDs map (encodeRouteLocal . SshKeyR personHash . hashSshKey) sshKeyIDs
} }

View file

@ -181,12 +181,17 @@ import qualified Vervis.Hook as H
getRepoR :: KeyHashid Repo -> Handler TypedContent getRepoR :: KeyHashid Repo -> Handler TypedContent
getRepoR repoHash = do getRepoR repoHash = do
repoID <- decodeKeyHashid404 repoHash repoID <- decodeKeyHashid404 repoHash
(repo, actor) <- runDB $ do (repo, actor, sigKeyIDs) <- runDB $ do
r <- get404 repoID r <- get404 repoID
(r,) <$> getJust (repoActor r) let aid = repoActor r
a <- getJust aid
sigKeys <- selectKeysList [SigKeyActor ==. aid] [Asc SigKeyId]
return (r, a, sigKeys)
encodeRouteLocal <- getEncodeRouteLocal encodeRouteLocal <- getEncodeRouteLocal
hashLoom <- getEncodeKeyHashid hashLoom <- getEncodeKeyHashid
hashSigKey <- getEncodeKeyHashid
perActor <- asksSite $ appPerActorKeys . appSettings
let repoAP = AP.Repo let repoAP = AP.Repo
{ AP.repoActor = AP.Actor { AP.repoActor = AP.Actor
{ AP.actorLocal = AP.ActorLocal { AP.actorLocal = AP.ActorLocal
@ -198,9 +203,10 @@ getRepoR repoHash = do
Just $ encodeRouteLocal $ RepoFollowersR repoHash Just $ encodeRouteLocal $ RepoFollowersR repoHash
, AP.actorFollowing = Nothing , AP.actorFollowing = Nothing
, AP.actorPublicKeys = , AP.actorPublicKeys =
[ Left $ encodeRouteLocal ActorKey1R map (Left . encodeRouteLocal) $
, Left $ encodeRouteLocal ActorKey2R if perActor
] then map (RepoStampR repoHash . hashSigKey) sigKeyIDs
else [ActorKey1R, ActorKey2R]
, AP.actorSshKeys = [] , AP.actorSshKeys = []
} }
, AP.actorDetail = AP.ActorDetail , AP.actorDetail = AP.ActorDetail