{-# LANGUAGE PatternSynonyms #-}
module Signet.Unstable where
import qualified Control.Monad.Catch as Exception
import qualified Control.Monad.IO.Class as MonadIO
import qualified Data.Bifunctor as Bifunctor
import qualified Data.ByteString as ByteString
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Time as Time
import qualified Signet.Unstable.Exception.InvalidId as InvalidId
import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage
import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature
import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner
import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp
import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier
import qualified Signet.Unstable.Exception.SignetException as SignetException
import qualified Signet.Unstable.Exception.UnknownSignature as UnknownSignature
import qualified Signet.Unstable.Extra.Either as Either
import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature
import qualified Signet.Unstable.Type.Id as Id
import qualified Signet.Unstable.Type.Message as Message
import qualified Signet.Unstable.Type.Payload as Payload
import qualified Signet.Unstable.Type.PublicKey as PublicKey
import qualified Signet.Unstable.Type.Secret as Secret
import qualified Signet.Unstable.Type.SecretKey as SecretKey
import qualified Signet.Unstable.Type.Signature as Signature
import qualified Signet.Unstable.Type.Signatures as Signatures
import qualified Signet.Unstable.Type.Signer as Signer
import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature
import qualified Signet.Unstable.Type.Timestamp as Timestamp
import qualified Signet.Unstable.Type.Tolerance as Tolerance
import qualified Signet.Unstable.Type.Verifier as Verifier
verifyWebhookText ::
(MonadIO.MonadIO m, Exception.MonadThrow m) =>
Text.Text ->
Text.Text ->
Text.Text ->
Text.Text ->
Text.Text ->
m Signature.Signature
verifyWebhookText :: forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
Text -> Text -> Text -> Text -> Text -> m Signature
verifyWebhookText Text
v Text
i Text
t Text
p Text
s =
ByteString
-> ByteString
-> ByteString
-> ByteString
-> ByteString
-> m Signature
forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
ByteString
-> ByteString
-> ByteString
-> ByteString
-> ByteString
-> m Signature
verifyWebhookByteString
(Text -> ByteString
Text.encodeUtf8 Text
v)
(Text -> ByteString
Text.encodeUtf8 Text
i)
(Text -> ByteString
Text.encodeUtf8 Text
t)
(Text -> ByteString
Text.encodeUtf8 Text
p)
(Text -> ByteString
Text.encodeUtf8 Text
s)
verifyWebhookByteString ::
(MonadIO.MonadIO m, Exception.MonadThrow m) =>
ByteString.ByteString ->
ByteString.ByteString ->
ByteString.ByteString ->
ByteString.ByteString ->
ByteString.ByteString ->
m Signature.Signature
verifyWebhookByteString :: forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
ByteString
-> ByteString
-> ByteString
-> ByteString
-> ByteString
-> m Signature
verifyWebhookByteString ByteString
v ByteString
i ByteString
t ByteString
p ByteString
s = do
verifier <- Either InvalidVerifier Verifier -> m Verifier
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidVerifier Verifier -> m Verifier)
-> Either InvalidVerifier Verifier -> m Verifier
forall a b. (a -> b) -> a -> b
$ ByteString -> Either InvalidVerifier Verifier
parseVerifier ByteString
v
id_ <- Either.throw $ parseId i
timestamp <- Either.throw $ parseTimestamp t
let payload = ByteString -> Payload
Payload.MkPayload ByteString
p
let message =
Message.MkMessage
{ id_ :: Id
Message.id_ = Id
id_,
timestamp :: Timestamp
Message.timestamp = Timestamp
timestamp,
payload :: Payload
Message.payload = Payload
payload
}
(_, signatures) <- Either.throw $ parseSignatures s
verifyWebhook verifier message signatures
verifyWebhook ::
(MonadIO.MonadIO m, Exception.MonadThrow m) =>
Verifier.Verifier ->
Message.Message ->
Signatures.Signatures ->
m Signature.Signature
verifyWebhook :: forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
Verifier -> Message -> Signatures -> m Signature
verifyWebhook Verifier
verifier Message
message Signatures
signatures = do
now <- IO UTCTime -> m UTCTime
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
MonadIO.liftIO IO UTCTime
Time.getCurrentTime
Either.throw $ verifyWebhookWith typicalTolerance now verifier message signatures
verifyWebhookWith ::
Tolerance.Tolerance ->
Time.UTCTime ->
Verifier.Verifier ->
Message.Message ->
Signatures.Signatures ->
Either SignetException.SignetException Signature.Signature
verifyWebhookWith :: Tolerance
-> UTCTime
-> Verifier
-> Message
-> Signatures
-> Either SignetException Signature
verifyWebhookWith Tolerance
tolerance UTCTime
now Verifier
verifier Message
message Signatures
signatures = do
(ToleranceException -> SignetException)
-> Either ToleranceException () -> Either SignetException ()
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
Bifunctor.first ToleranceException -> SignetException
SignetException.ToleranceException
(Either ToleranceException () -> Either SignetException ())
-> (Timestamp -> Either ToleranceException ())
-> Timestamp
-> Either SignetException ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tolerance -> UTCTime -> Timestamp -> Either ToleranceException ()
Tolerance.check Tolerance
tolerance UTCTime
now
(Timestamp -> Either SignetException ())
-> Timestamp -> Either SignetException ()
forall a b. (a -> b) -> a -> b
$ Message -> Timestamp
Message.timestamp Message
message
(VerificationException -> SignetException)
-> Either VerificationException Signature
-> Either SignetException Signature
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
Bifunctor.first VerificationException -> SignetException
SignetException.VerificationException (Either VerificationException Signature
-> Either SignetException Signature)
-> Either VerificationException Signature
-> Either SignetException Signature
forall a b. (a -> b) -> a -> b
$
Verifier
-> Message -> Signatures -> Either VerificationException Signature
Verifier.verify Verifier
verifier Message
message Signatures
signatures
typicalTolerance :: Tolerance.Tolerance
typicalTolerance :: Tolerance
typicalTolerance = Tolerance
Tolerance.typical
parseVerifier :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier.Verifier
parseVerifier :: ByteString -> Either InvalidVerifier Verifier
parseVerifier = ByteString -> Either InvalidVerifier Verifier
Verifier.parse
parseId :: ByteString.ByteString -> Either InvalidId.InvalidId Id.Id
parseId :: ByteString -> Either InvalidId Id
parseId = ByteString -> Either InvalidId Id
Id.parse
parseTimestamp :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp.Timestamp
parseTimestamp :: ByteString -> Either InvalidTimestamp Timestamp
parseTimestamp = ByteString -> Either InvalidTimestamp Timestamp
Timestamp.parse
parseMessage :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message.Message
parseMessage :: ByteString -> Either InvalidMessage Message
parseMessage = ByteString -> Either InvalidMessage Message
Message.parse
parseSignatures ::
ByteString.ByteString ->
Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures.Signatures)
parseSignatures :: ByteString
-> Either InvalidSignature ([UnknownSignature], Signatures)
parseSignatures = ByteString
-> Either InvalidSignature ([UnknownSignature], Signatures)
Signatures.parse
pattern AsymmetricVerifier :: PublicKey.PublicKey -> Verifier.Verifier
pattern $bAsymmetricVerifier :: PublicKey -> Verifier
$mAsymmetricVerifier :: forall {r}. Verifier -> (PublicKey -> r) -> ((# #) -> r) -> r
AsymmetricVerifier publicKey = Verifier.Asymmetric publicKey
pattern SymmetricVerifier :: Secret.Secret -> Verifier.Verifier
pattern $bSymmetricVerifier :: Secret -> Verifier
$mSymmetricVerifier :: forall {r}. Verifier -> (Secret -> r) -> ((# #) -> r) -> r
SymmetricVerifier secret = Verifier.Symmetric secret
{-# COMPLETE AsymmetricVerifier, SymmetricVerifier #-}
signWebhook :: Signer.Signer -> Message.Message -> Signature.Signature
signWebhook :: Signer -> Message -> Signature
signWebhook = Signer -> Message -> Signature
Signer.sign
parseSigner :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer.Signer
parseSigner :: ByteString -> Either InvalidSigner Signer
parseSigner = ByteString -> Either InvalidSigner Signer
Signer.parse
pattern AsymmetricSigner :: SecretKey.SecretKey -> Signer.Signer
pattern $bAsymmetricSigner :: SecretKey -> Signer
$mAsymmetricSigner :: forall {r}. Signer -> (SecretKey -> r) -> ((# #) -> r) -> r
AsymmetricSigner secretKey = Signer.Asymmetric secretKey
pattern SymmetricSigner :: Secret.Secret -> Signer.Signer
pattern $bSymmetricSigner :: Secret -> Signer
$mSymmetricSigner :: forall {r}. Signer -> (Secret -> r) -> ((# #) -> r) -> r
SymmetricSigner secret = Signer.Symmetric secret
{-# COMPLETE AsymmetricSigner, SymmetricSigner #-}
pattern AsymmetricSignature :: AsymmetricSignature.AsymmetricSignature -> Signature.Signature
pattern $bAsymmetricSignature :: AsymmetricSignature -> Signature
$mAsymmetricSignature :: forall {r}.
Signature -> (AsymmetricSignature -> r) -> ((# #) -> r) -> r
AsymmetricSignature asymmetricSignature = Signature.Asymmetric asymmetricSignature
pattern SymmetricSignature :: SymmetricSignature.SymmetricSignature -> Signature.Signature
pattern $bSymmetricSignature :: SymmetricSignature -> Signature
$mSymmetricSignature :: forall {r}.
Signature -> (SymmetricSignature -> r) -> ((# #) -> r) -> r
SymmetricSignature symmetricSignature = Signature.Symmetric symmetricSignature
{-# COMPLETE AsymmetricSignature, SymmetricSignature #-}