Generate FEP-8b32 authenticity proofs when delivering activities
Limitations: - Verification of proofs not implemeneted yet, just generation. Verification probably coming in the next commit. - Only jcs-eddsa-2022 is supported. Can add more cryptosuites once they're updated for the requirements of the VC Data Integrity spec. - Bug: The proofs aren't stored in the DB versions of outgoing activities, i.e. HTTP GETing an activity won't include the proof. Probably not urgent to fix. Ideally, change the whole PersistJSONObject/Envelope/etc. thing to allow to serialize the activity exactly once.
This commit is contained in:
parent
ba02d62eb5
commit
e8e587af26
11 changed files with 128 additions and 46 deletions
|
@ -179,7 +179,7 @@ generateActorKey = mk <$> generateSecretKey
|
||||||
-- renderPEM = pemWriteBS . PEM "PUBLIC KEY" [] . convert
|
-- renderPEM = pemWriteBS . PEM "PUBLIC KEY" [] . convert
|
||||||
|
|
||||||
-- | A loop that runs forever and periodically generates new actor keys,
|
-- | A loop that runs forever and periodically generates new actor keys,
|
||||||
-- storing them in a 'TVar'. It manages a pait of keys, and each time it toggles
|
-- storing them in a 'TVar'. It manages a pair of keys, and each time it toggles
|
||||||
-- which key gets rotated.
|
-- which key gets rotated.
|
||||||
actorKeyRotator :: TimeInterval -> TVar (ActorKey, ActorKey, Bool) -> IO ()
|
actorKeyRotator :: TimeInterval -> TVar (ActorKey, ActorKey, Bool) -> IO ()
|
||||||
actorKeyRotator interval keys = periodically interval $ do
|
actorKeyRotator interval keys = periodically interval $ do
|
||||||
|
|
|
@ -1174,6 +1174,7 @@ createPatchTrackerC (Entity pidUser personUser) senderActor maybeCap localRecips
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = AP.Audience recips [] [] [] [] []
|
, activityAudience = AP.Audience recips [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = FollowActivity AP.Follow
|
, activitySpecific = FollowActivity AP.Follow
|
||||||
{ AP.followObject = encodeRouteHome $ LoomR loomHash
|
{ AP.followObject = encodeRouteHome $ LoomR loomHash
|
||||||
, AP.followContext = Nothing
|
, AP.followContext = Nothing
|
||||||
|
@ -1198,6 +1199,7 @@ createPatchTrackerC (Entity pidUser personUser) senderActor maybeCap localRecips
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = Audience recips [] [] [] [] []
|
, activityAudience = Audience recips [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = AcceptActivity Accept
|
, activitySpecific = AcceptActivity Accept
|
||||||
{ acceptObject = ObjURI hLocal luFollow
|
{ acceptObject = ObjURI hLocal luFollow
|
||||||
, acceptResult = Nothing
|
, acceptResult = Nothing
|
||||||
|
@ -1400,6 +1402,7 @@ createRepositoryC (Entity pidUser personUser) senderActor maybeCap localRecips r
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = AP.Audience recips [] [] [] [] []
|
, activityAudience = AP.Audience recips [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = FollowActivity AP.Follow
|
, activitySpecific = FollowActivity AP.Follow
|
||||||
{ AP.followObject = encodeRouteHome $ RepoR repoHash
|
{ AP.followObject = encodeRouteHome $ RepoR repoHash
|
||||||
, AP.followContext = Nothing
|
, AP.followContext = Nothing
|
||||||
|
@ -1424,6 +1427,7 @@ createRepositoryC (Entity pidUser personUser) senderActor maybeCap localRecips r
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = Audience recips [] [] [] [] []
|
, activityAudience = Audience recips [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = AcceptActivity Accept
|
, activitySpecific = AcceptActivity Accept
|
||||||
{ acceptObject = ObjURI hLocal luFollow
|
{ acceptObject = ObjURI hLocal luFollow
|
||||||
, acceptResult = Nothing
|
, acceptResult = Nothing
|
||||||
|
@ -1652,6 +1656,7 @@ createTicketTrackerC (Entity pidUser personUser) senderActor maybeCap localRecip
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = AP.Audience recips [] [] [] [] []
|
, activityAudience = AP.Audience recips [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = FollowActivity AP.Follow
|
, activitySpecific = FollowActivity AP.Follow
|
||||||
{ AP.followObject = encodeRouteHome $ DeckR deckHash
|
{ AP.followObject = encodeRouteHome $ DeckR deckHash
|
||||||
, AP.followContext = Nothing
|
, AP.followContext = Nothing
|
||||||
|
@ -1676,6 +1681,7 @@ createTicketTrackerC (Entity pidUser personUser) senderActor maybeCap localRecip
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = Audience recips [] [] [] [] []
|
, activityAudience = Audience recips [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = AcceptActivity Accept
|
, activitySpecific = AcceptActivity Accept
|
||||||
{ acceptObject = ObjURI hLocal luFollow
|
{ acceptObject = ObjURI hLocal luFollow
|
||||||
, acceptResult = Nothing
|
, acceptResult = Nothing
|
||||||
|
|
|
@ -65,43 +65,6 @@ import qualified Data.Text as T
|
||||||
import qualified Database.Esqueleto as E
|
import qualified Database.Esqueleto as E
|
||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
|
|
||||||
import Data.Time.Interval
|
|
||||||
import Network.HTTP.Signature hiding (requestHeaders)
|
|
||||||
import Yesod.HttpSignature
|
|
||||||
|
|
||||||
import Crypto.PublicVerifKey
|
|
||||||
import Database.Persist.JSON
|
|
||||||
import Network.FedURI
|
|
||||||
import Network.HTTP.Digest
|
|
||||||
import Web.ActivityPub hiding (Follow, Ticket)
|
|
||||||
import Yesod.ActivityPub
|
|
||||||
import Yesod.Auth.Unverified
|
|
||||||
import Yesod.FedURI
|
|
||||||
import Yesod.Hashids
|
|
||||||
import Yesod.MonadSite
|
|
||||||
|
|
||||||
import qualified Web.ActivityPub as AP
|
|
||||||
|
|
||||||
import Control.Monad.Trans.Except.Local
|
|
||||||
import Data.Aeson.Local
|
|
||||||
import Data.Either.Local
|
|
||||||
import Data.List.Local
|
|
||||||
import Data.List.NonEmpty.Local
|
|
||||||
import Data.Maybe.Local
|
|
||||||
import Data.Tuple.Local
|
|
||||||
import Database.Persist.Local
|
|
||||||
import Yesod.Persist.Local
|
|
||||||
|
|
||||||
import Vervis.ActivityPub
|
|
||||||
import Vervis.ActorKey
|
|
||||||
import Vervis.Web.Delivery
|
|
||||||
import Vervis.Federation.Auth
|
|
||||||
import Vervis.Foundation
|
|
||||||
import Vervis.Model
|
|
||||||
import Vervis.Recipient
|
|
||||||
import Vervis.RemoteActorStore
|
|
||||||
import Vervis.Settings
|
|
||||||
|
|
||||||
{-
|
{-
|
||||||
|
|
||||||
handleProjectInbox
|
handleProjectInbox
|
||||||
|
|
|
@ -75,7 +75,7 @@ import qualified Network.HTTP.Signature as S (Algorithm (..))
|
||||||
|
|
||||||
import Control.Concurrent.Actor hiding (Message)
|
import Control.Concurrent.Actor hiding (Message)
|
||||||
import Crypto.ActorKey
|
import Crypto.ActorKey
|
||||||
import Crypto.PublicVerifKey
|
--import Crypto.PublicVerifKey
|
||||||
import Network.FedURI
|
import Network.FedURI
|
||||||
import Web.ActivityAccess
|
import Web.ActivityAccess
|
||||||
import Web.Actor.Persist
|
import Web.Actor.Persist
|
||||||
|
|
|
@ -193,7 +193,7 @@ postPersonOutboxR personHash = do
|
||||||
unless (federation || null remoteRecips) $
|
unless (federation || null remoteRecips) $
|
||||||
throwE "Federation disabled, but remote recipients found"
|
throwE "Federation disabled, but remote recipients found"
|
||||||
|
|
||||||
handle eperson actorDB (AP.Activity _mid _actorAP muCap summary audience _fulfills specific) = do
|
handle eperson actorDB (AP.Activity _mid _actorAP muCap summary audience _fulfills _mproof specific) = do
|
||||||
maybeCap <- traverse (nameExceptT "Capability" . parseActivityURI) muCap
|
maybeCap <- traverse (nameExceptT "Capability" . parseActivityURI) muCap
|
||||||
ParsedAudience localRecips remoteRecips blinded fwdHosts <- do
|
ParsedAudience localRecips remoteRecips blinded fwdHosts <- do
|
||||||
mrecips <- parseAudience audience
|
mrecips <- parseAudience audience
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- This file is part of Vervis.
|
{- This file is part of Vervis.
|
||||||
-
|
-
|
||||||
- Written in 2016, 2018, 2019, 2020, 2021, 2022
|
- Written in 2016, 2018, 2019, 2020, 2021, 2022, 2023
|
||||||
- by fr33domlover <fr33domlover@riseup.net>.
|
- by fr33domlover <fr33domlover@riseup.net>.
|
||||||
-
|
-
|
||||||
- ♡ Copying is an act of love. Please copy, reuse and share.
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
|
@ -581,6 +581,7 @@ changes hLocal ctx =
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = Audience [] [] [] [] [] []
|
, activityAudience = Audience [] [] [] [] [] []
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = RejectActivity $ Reject fedUri
|
, activitySpecific = RejectActivity $ Reject fedUri
|
||||||
}
|
}
|
||||||
insertEntity $ OutboxItem20190612 pid (persistJSONObjectFromDoc doc) defaultTime
|
insertEntity $ OutboxItem20190612 pid (persistJSONObjectFromDoc doc) defaultTime
|
||||||
|
|
|
@ -82,6 +82,8 @@ module Web.ActivityPub
|
||||||
, Resolve (..)
|
, Resolve (..)
|
||||||
, Undo (..)
|
, Undo (..)
|
||||||
, Audience (..)
|
, Audience (..)
|
||||||
|
, ProofConfig (..)
|
||||||
|
, Proof (..)
|
||||||
, SpecificActivity (..)
|
, SpecificActivity (..)
|
||||||
, activityType
|
, activityType
|
||||||
, Action (..)
|
, Action (..)
|
||||||
|
@ -160,6 +162,9 @@ import Yesod.Core.Handler (ProvidedRep, provideRepType)
|
||||||
import Network.HTTP.Client.Signature
|
import Network.HTTP.Client.Signature
|
||||||
|
|
||||||
import qualified Data.Attoparsec.ByteString as A
|
import qualified Data.Attoparsec.ByteString as A
|
||||||
|
import qualified Data.ByteArray as BA
|
||||||
|
import qualified Data.ByteString as B
|
||||||
|
import qualified Data.ByteString.Base58 as B58
|
||||||
import qualified Data.ByteString.Base64 as B64
|
import qualified Data.ByteString.Base64 as B64
|
||||||
import qualified Data.ByteString.Char8 as BC
|
import qualified Data.ByteString.Char8 as BC
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
|
@ -180,6 +185,34 @@ import Web.Text
|
||||||
|
|
||||||
import Data.Aeson.Local
|
import Data.Aeson.Local
|
||||||
|
|
||||||
|
-- JSON CANONICALIZATION
|
||||||
|
--
|
||||||
|
-- In order to produce JSON-based sigs, we need the ability to produce a
|
||||||
|
-- canonical ByteString from a given ToJSON-able object. Is aeson's encoder
|
||||||
|
-- already compatible?
|
||||||
|
--
|
||||||
|
-- * Before aeson-2, clearly no, because a HashMap is used for objects
|
||||||
|
-- * After aeson-2, possibly, since ordered-map mode exists and on by default
|
||||||
|
--
|
||||||
|
-- I'm gonna list requirements here and then we can compare this with aeson.
|
||||||
|
--
|
||||||
|
-- - [ ] JSON number data MUST be expressible as IEEE 754 [IEEE754]
|
||||||
|
-- double-precision values. For applications needing higher precision or longer
|
||||||
|
-- integers than offered by IEEE 754 double precision, it is RECOMMENDED to
|
||||||
|
-- represent such numbers as JSON strings
|
||||||
|
-- - [ ] objects must be sorted by key
|
||||||
|
-- - [ ] The sorting process is applied to property name strings in their "raw" (unescaped) form. That is, a newline character is treated as U+000A
|
||||||
|
-- - [ ] Property name strings to be sorted are formatted as arrays of UTF-16 [UNICODE] code units. The sorting is based on pure value comparisons, where code units are treated as unsigned integers, independent of locale settings
|
||||||
|
--
|
||||||
|
-- Looks like the primary things to verify are key ordering and number
|
||||||
|
-- serialization.
|
||||||
|
--
|
||||||
|
-- When to encode? We need to encode the activity and then:
|
||||||
|
--
|
||||||
|
-- 1. Put it in the DB
|
||||||
|
-- 2. Send to local actors via system
|
||||||
|
-- 3. Send to remote actors via HTTP
|
||||||
|
|
||||||
{-
|
{-
|
||||||
data Link = Link
|
data Link = Link
|
||||||
{ linkHref :: URI
|
{ linkHref :: URI
|
||||||
|
@ -1857,6 +1890,57 @@ parseUndo a o = Undo <$> o .: "object"
|
||||||
encodeUndo :: UriMode u => Authority u -> Undo u -> Series
|
encodeUndo :: UriMode u => Authority u -> Undo u -> Series
|
||||||
encodeUndo a (Undo obj) = "object" .= obj
|
encodeUndo a (Undo obj) = "object" .= obj
|
||||||
|
|
||||||
|
data ProofConfig u = ProofConfig
|
||||||
|
{ proofKey :: LocalRefURI
|
||||||
|
, proofCreated :: UTCTime
|
||||||
|
}
|
||||||
|
|
||||||
|
instance ActivityPub ProofConfig where
|
||||||
|
jsonldContext _ = []
|
||||||
|
parseObject o = do
|
||||||
|
typ <- o .: "type"
|
||||||
|
guard $ typ == ("DataIntegrityProof" :: Text)
|
||||||
|
purpose <- o .: "proofPurpose"
|
||||||
|
guard $ purpose == ("assertionMethod" :: Text)
|
||||||
|
suite <- o .: "cryptosuite"
|
||||||
|
guard $ suite == ("jcs-eddsa-2022" :: Text)
|
||||||
|
RefURI h lruKey <- o .: "verificationMethod"
|
||||||
|
fmap (h,) $ ProofConfig
|
||||||
|
<$> pure lruKey
|
||||||
|
<*> o .: "created"
|
||||||
|
toSeries h (ProofConfig lruKey created)
|
||||||
|
= "type" .= ("DataIntegrityProof" :: Text)
|
||||||
|
<> "proofPurpose" .= ("assertionMethod" :: Text)
|
||||||
|
<> "cryptosuite" .= ("jcs-eddsa-2022" :: Text)
|
||||||
|
<> "verificationMethod" .= RefURI h lruKey
|
||||||
|
<> "created" .= created
|
||||||
|
|
||||||
|
data Proof u = Proof
|
||||||
|
{ proofConfig :: ProofConfig u
|
||||||
|
, proofValue :: ByteString
|
||||||
|
}
|
||||||
|
|
||||||
|
instance ActivityPub Proof where
|
||||||
|
jsonldContext _ = []
|
||||||
|
parseObject o = do
|
||||||
|
(h, config) <- parseObject o
|
||||||
|
value <- do
|
||||||
|
t <- o .: "proofValue"
|
||||||
|
t58 <-
|
||||||
|
case T.uncons t of
|
||||||
|
Just ('z', t') -> return t'
|
||||||
|
_ -> fail $ "No multibase 'z' prefix: " ++ T.unpack t
|
||||||
|
let b = TE.encodeUtf8 t58
|
||||||
|
case B58.decodeBase58 B58.bitcoinAlphabet b of
|
||||||
|
Nothing ->
|
||||||
|
fail $ "base58-btc decoding failed:" ++ T.unpack t
|
||||||
|
Just val -> return val
|
||||||
|
return (h, Proof config value)
|
||||||
|
toSeries h (Proof config sig)
|
||||||
|
= toSeries h config
|
||||||
|
<> "proofValue" .=
|
||||||
|
T.cons 'z' (TE.decodeUtf8 $ B58.encodeBase58 B58.bitcoinAlphabet sig)
|
||||||
|
|
||||||
data SpecificActivity u
|
data SpecificActivity u
|
||||||
= AcceptActivity (Accept u)
|
= AcceptActivity (Accept u)
|
||||||
| AddActivity (Add u)
|
| AddActivity (Add u)
|
||||||
|
@ -1903,6 +1987,7 @@ makeActivity luId luActor Action{..} = Activity
|
||||||
, activitySummary = actionSummary
|
, activitySummary = actionSummary
|
||||||
, activityAudience = actionAudience
|
, activityAudience = actionAudience
|
||||||
, activityFulfills = actionFulfills
|
, activityFulfills = actionFulfills
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific = actionSpecific
|
, activitySpecific = actionSpecific
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1913,6 +1998,7 @@ data Activity u = Activity
|
||||||
, activitySummary :: Maybe HTML
|
, activitySummary :: Maybe HTML
|
||||||
, activityAudience :: Audience u
|
, activityAudience :: Audience u
|
||||||
, activityFulfills :: [ObjURI u]
|
, activityFulfills :: [ObjURI u]
|
||||||
|
, activityProof :: Maybe (Proof u)
|
||||||
, activitySpecific :: SpecificActivity u
|
, activitySpecific :: SpecificActivity u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1928,6 +2014,9 @@ instance ActivityPub Activity where
|
||||||
<*> o .:? "summary"
|
<*> o .:? "summary"
|
||||||
<*> parseAudience o
|
<*> parseAudience o
|
||||||
<*> o .:? "fulfills" .!= []
|
<*> o .:? "fulfills" .!= []
|
||||||
|
<*> (do mp <- o .:? "proof"
|
||||||
|
for mp $ withAuthorityT a . parseObject
|
||||||
|
)
|
||||||
<*> do
|
<*> do
|
||||||
typ <- o .: "type"
|
typ <- o .: "type"
|
||||||
case typ of
|
case typ of
|
||||||
|
@ -1947,7 +2036,7 @@ instance ActivityPub Activity where
|
||||||
_ ->
|
_ ->
|
||||||
fail $
|
fail $
|
||||||
"Unrecognized activity type: " ++ T.unpack typ
|
"Unrecognized activity type: " ++ T.unpack typ
|
||||||
toSeries authority (Activity id_ actor mcap summary audience fulfills specific)
|
toSeries authority (Activity id_ actor mcap summary audience fulfills mproof specific)
|
||||||
= "type" .= activityType specific
|
= "type" .= activityType specific
|
||||||
<> "id" .=? (ObjURI authority <$> id_)
|
<> "id" .=? (ObjURI authority <$> id_)
|
||||||
<> "actor" .= ObjURI authority actor
|
<> "actor" .= ObjURI authority actor
|
||||||
|
@ -1955,6 +2044,7 @@ instance ActivityPub Activity where
|
||||||
<> "summary" .=? summary
|
<> "summary" .=? summary
|
||||||
<> encodeAudience audience
|
<> encodeAudience audience
|
||||||
<> "fulfills" .=% fulfills
|
<> "fulfills" .=% fulfills
|
||||||
|
<> "proof" .=? (Doc authority <$> mproof)
|
||||||
<> encodeSpecific authority actor specific
|
<> encodeSpecific authority actor specific
|
||||||
where
|
where
|
||||||
encodeSpecific h _ (AcceptActivity a) = encodeAccept h a
|
encodeSpecific h _ (AcceptActivity a) = encodeAccept h a
|
||||||
|
@ -1982,6 +2072,7 @@ emptyActivity = Activity
|
||||||
, activitySummary = Nothing
|
, activitySummary = Nothing
|
||||||
, activityAudience = emptyAudience
|
, activityAudience = emptyAudience
|
||||||
, activityFulfills = []
|
, activityFulfills = []
|
||||||
|
, activityProof = Nothing
|
||||||
, activitySpecific =
|
, activitySpecific =
|
||||||
RejectActivity $ Reject $ ObjURI (Authority "" Nothing) topLocalURI
|
RejectActivity $ Reject $ ObjURI (Authority "" Nothing) topLocalURI
|
||||||
}
|
}
|
||||||
|
@ -2157,17 +2248,31 @@ sending
|
||||||
:: UriMode u
|
:: UriMode u
|
||||||
=> LocalRefURI
|
=> LocalRefURI
|
||||||
-> (ByteString -> S.Signature)
|
-> (ByteString -> S.Signature)
|
||||||
|
-> Maybe (ProofConfig u, ByteString -> ByteString)
|
||||||
-> Bool
|
-> Bool
|
||||||
-> ObjURI u
|
-> ObjURI u
|
||||||
-> LocalURI
|
-> LocalURI
|
||||||
-> Action u
|
-> Action u
|
||||||
-> Envelope u
|
-> Envelope u
|
||||||
sending lruKey sign holder uActor@(ObjURI hActor luActor) luId action =
|
sending lruKey sign mprove holder uActor@(ObjURI hActor luActor) luId action =
|
||||||
Envelope
|
Envelope
|
||||||
{ envelopeKey = RefURI hActor lruKey
|
{ envelopeKey = RefURI hActor lruKey
|
||||||
, envelopeSign = sign
|
, envelopeSign = sign
|
||||||
, envelopeHolder = guard holder >> Just luActor
|
, envelopeHolder = guard holder >> Just luActor
|
||||||
, envelopeBody = encode $ Doc hActor $ makeActivity luId luActor action
|
, envelopeBody =
|
||||||
|
let act = makeActivity luId luActor action
|
||||||
|
lb = encode $ Doc hActor act
|
||||||
|
in case mprove of
|
||||||
|
Nothing -> lb
|
||||||
|
Just (config, prove) ->
|
||||||
|
let configLB = encode $ Doc hActor config
|
||||||
|
configHash = hashWith SHA256 $ BL.toStrict configLB
|
||||||
|
bodyHash = hashWith SHA256 $ BL.toStrict lb
|
||||||
|
input = BA.convert configHash `B.append` BA.convert bodyHash
|
||||||
|
proof = Proof config (prove input)
|
||||||
|
actWithProof = act { activityProof = Just proof }
|
||||||
|
in encode $ Doc hActor actWithProof
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retrying
|
retrying
|
||||||
|
|
|
@ -53,10 +53,12 @@ module Web.Actor
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
import Control.Monad.IO.Class
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Data.Proxy
|
import Data.Proxy
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import Data.Time.Clock
|
||||||
|
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
|
|
||||||
|
@ -176,10 +178,13 @@ prepareToSend
|
||||||
prepareToSend keyR sign holder actorR idR action = do
|
prepareToSend keyR sign holder actorR idR action = do
|
||||||
encodeRouteLocal <- getEncodeRouteLocal
|
encodeRouteLocal <- getEncodeRouteLocal
|
||||||
encodeRouteHome <- getEncodeRouteHome
|
encodeRouteHome <- getEncodeRouteHome
|
||||||
|
now <- liftActor $ liftIO getCurrentTime
|
||||||
let lruKey = LocalRefURI $ Left $ encodeRouteLocal keyR
|
let lruKey = LocalRefURI $ Left $ encodeRouteLocal keyR
|
||||||
uActor = encodeRouteHome actorR
|
uActor = encodeRouteHome actorR
|
||||||
luId = encodeRouteLocal idR
|
luId = encodeRouteLocal idR
|
||||||
return $ AP.sending lruKey sign holder uActor luId action
|
config = AP.ProofConfig lruKey now
|
||||||
|
signB = S.unSignature . sign
|
||||||
|
return $ AP.sending lruKey sign (Just (config, signB)) holder uActor luId action
|
||||||
|
|
||||||
prepareToForward
|
prepareToForward
|
||||||
:: (MonadActor m, ActorEnv m ~ s, StageWebRoute s, StageURIMode s ~ u)
|
:: (MonadActor m, ActorEnv m ~ s, StageWebRoute s, StageURIMode s ~ u)
|
||||||
|
|
|
@ -104,7 +104,7 @@ prepareToSend keyR sign holder actorR idR action = do
|
||||||
let lruKey = LocalRefURI $ Left $ encodeRouteLocal keyR
|
let lruKey = LocalRefURI $ Left $ encodeRouteLocal keyR
|
||||||
uActor = encodeRouteHome actorR
|
uActor = encodeRouteHome actorR
|
||||||
luId = encodeRouteLocal idR
|
luId = encodeRouteLocal idR
|
||||||
return $ AP.sending lruKey sign holder uActor luId action
|
return $ AP.sending lruKey sign Nothing holder uActor luId action
|
||||||
|
|
||||||
prepareToRetry
|
prepareToRetry
|
||||||
:: (MonadSite m, SiteEnv m ~ site, SiteFedURI site, SiteFedURIMode site ~ u)
|
:: (MonadSite m, SiteEnv m ~ site, SiteFedURI site, SiteFedURIMode site ~ u)
|
||||||
|
|
|
@ -56,6 +56,7 @@ extra-deps:
|
||||||
- url-2.1.3
|
- url-2.1.3
|
||||||
- annotated-exception-0.2.0.4
|
- annotated-exception-0.2.0.4
|
||||||
- retry-0.9.3.1
|
- retry-0.9.3.1
|
||||||
|
- base58-bytestring-0.1.0
|
||||||
|
|
||||||
# Override default flag values for local packages and extra-deps
|
# Override default flag values for local packages and extra-deps
|
||||||
flags:
|
flags:
|
||||||
|
|
|
@ -303,6 +303,7 @@ library
|
||||||
, base
|
, base
|
||||||
-- for hex display of Darcs patch hashes
|
-- for hex display of Darcs patch hashes
|
||||||
, base16-bytestring
|
, base16-bytestring
|
||||||
|
, base58-bytestring
|
||||||
, base64-bytestring
|
, base64-bytestring
|
||||||
-- for Data.Binary.Local
|
-- for Data.Binary.Local
|
||||||
, binary
|
, binary
|
||||||
|
|
Loading…
Reference in a new issue