signet 0.2025.5.9 → 0.2025.5.12
raw patch · 140 files changed
+1988/−2005 lines, 140 filesdep ~tastyPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependency ranges changed: tasty
API changes (from Hackage documentation)
+ Signet.Unstable: parseId :: ByteString -> Either InvalidId Id
+ Signet.Unstable: parseMessage :: ByteString -> Either InvalidMessage Message
+ Signet.Unstable: parseSignatures :: ByteString -> Either InvalidSignature ([UnknownSignature], Signatures)
+ Signet.Unstable: parseSigner :: ByteString -> Either InvalidSigner Signer
+ Signet.Unstable: parseTimestamp :: ByteString -> Either InvalidTimestamp Timestamp
+ Signet.Unstable: parseVerifier :: ByteString -> Either InvalidVerifier Verifier
+ Signet.Unstable: pattern AsymmetricSignature :: AsymmetricSignature -> Signature
+ Signet.Unstable: pattern AsymmetricSigner :: SecretKey -> Signer
+ Signet.Unstable: pattern AsymmetricVerifier :: PublicKey -> Verifier
+ Signet.Unstable: pattern SymmetricSignature :: SymmetricSignature -> Signature
+ Signet.Unstable: pattern SymmetricSigner :: Secret -> Signer
+ Signet.Unstable: pattern SymmetricVerifier :: Secret -> Verifier
+ Signet.Unstable: signWebhook :: Signer -> Message -> Signature
+ Signet.Unstable: typicalTolerance :: Tolerance
+ Signet.Unstable: verifyWebhook :: (MonadIO m, MonadThrow m) => Verifier -> Message -> Signatures -> m Signature
+ Signet.Unstable: verifyWebhookByteString :: (MonadIO m, MonadThrow m) => ByteString -> ByteString -> ByteString -> ByteString -> ByteString -> m Signature
+ Signet.Unstable: verifyWebhookText :: (MonadIO m, MonadThrow m) => Text -> Text -> Text -> Text -> Text -> m Signature
+ Signet.Unstable: verifyWebhookWith :: Tolerance -> UTCTime -> Verifier -> Message -> Signatures -> Either SignetException Signature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: MkInvalidAsymmetricSignature :: ByteString -> InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: instance GHC.Show.Show Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: newtype InvalidAsymmetricSignature
+ Signet.Unstable.Exception.InvalidAsymmetricSignature: unwrap :: InvalidAsymmetricSignature -> ByteString
+ Signet.Unstable.Exception.InvalidAsymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidId: MkInvalidId :: ByteString -> InvalidId
+ Signet.Unstable.Exception.InvalidId: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidId.InvalidId
+ Signet.Unstable.Exception.InvalidId: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidId.InvalidId
+ Signet.Unstable.Exception.InvalidId: instance GHC.Show.Show Signet.Unstable.Exception.InvalidId.InvalidId
+ Signet.Unstable.Exception.InvalidId: newtype InvalidId
+ Signet.Unstable.Exception.InvalidId: unwrap :: InvalidId -> ByteString
+ Signet.Unstable.Exception.InvalidIdTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidMessage: InvalidId :: InvalidId -> InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: InvalidTimestamp :: InvalidTimestamp -> InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: data InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidMessage.InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidMessage.InvalidMessage
+ Signet.Unstable.Exception.InvalidMessage: instance GHC.Show.Show Signet.Unstable.Exception.InvalidMessage.InvalidMessage
+ Signet.Unstable.Exception.InvalidMessageTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidPublicKey: MkInvalidPublicKey :: ByteString -> InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: instance GHC.Show.Show Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: newtype InvalidPublicKey
+ Signet.Unstable.Exception.InvalidPublicKey: unwrap :: InvalidPublicKey -> ByteString
+ Signet.Unstable.Exception.InvalidPublicKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSecret: MkInvalidSecret :: ByteString -> InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSecret.InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSecret.InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSecret.InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: newtype InvalidSecret
+ Signet.Unstable.Exception.InvalidSecret: unwrap :: InvalidSecret -> ByteString
+ Signet.Unstable.Exception.InvalidSecretKey: MkInvalidSecretKey :: ByteString -> InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: newtype InvalidSecretKey
+ Signet.Unstable.Exception.InvalidSecretKey: unwrap :: InvalidSecretKey -> ByteString
+ Signet.Unstable.Exception.InvalidSecretKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSecretTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSignature: InvalidAsymmetricSignature :: InvalidAsymmetricSignature -> InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: InvalidSymmetricSignature :: InvalidSymmetricSignature -> InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: data InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSignature.InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSignature.InvalidSignature
+ Signet.Unstable.Exception.InvalidSignature: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSignature.InvalidSignature
+ Signet.Unstable.Exception.InvalidSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSigner: MkInvalidSigner :: ByteString -> InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSigner.InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSigner.InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSigner.InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: newtype InvalidSigner
+ Signet.Unstable.Exception.InvalidSigner: unwrap :: InvalidSigner -> ByteString
+ Signet.Unstable.Exception.InvalidSignerTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidSymmetricSignature: MkInvalidSymmetricSignature :: ByteString -> InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: instance GHC.Show.Show Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: newtype InvalidSymmetricSignature
+ Signet.Unstable.Exception.InvalidSymmetricSignature: unwrap :: InvalidSymmetricSignature -> ByteString
+ Signet.Unstable.Exception.InvalidSymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidTimestamp: MkInvalidTimestamp :: ByteString -> InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: instance GHC.Show.Show Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: newtype InvalidTimestamp
+ Signet.Unstable.Exception.InvalidTimestamp: unwrap :: InvalidTimestamp -> ByteString
+ Signet.Unstable.Exception.InvalidTimestampTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.InvalidVerifier: MkInvalidVerifier :: ByteString -> InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: instance GHC.Classes.Eq Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: instance GHC.Show.Show Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: newtype InvalidVerifier
+ Signet.Unstable.Exception.InvalidVerifier: unwrap :: InvalidVerifier -> ByteString
+ Signet.Unstable.Exception.InvalidVerifierTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.SignetException: ToleranceException :: ToleranceException -> SignetException
+ Signet.Unstable.Exception.SignetException: VerificationException :: VerificationException -> SignetException
+ Signet.Unstable.Exception.SignetException: data SignetException
+ Signet.Unstable.Exception.SignetException: instance GHC.Classes.Eq Signet.Unstable.Exception.SignetException.SignetException
+ Signet.Unstable.Exception.SignetException: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.SignetException.SignetException
+ Signet.Unstable.Exception.SignetException: instance GHC.Show.Show Signet.Unstable.Exception.SignetException.SignetException
+ Signet.Unstable.Exception.SignetExceptionTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.ToleranceException: MkToleranceException :: Timestamp -> ToleranceException
+ Signet.Unstable.Exception.ToleranceException: instance GHC.Classes.Eq Signet.Unstable.Exception.ToleranceException.ToleranceException
+ Signet.Unstable.Exception.ToleranceException: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.ToleranceException.ToleranceException
+ Signet.Unstable.Exception.ToleranceException: instance GHC.Show.Show Signet.Unstable.Exception.ToleranceException.ToleranceException
+ Signet.Unstable.Exception.ToleranceException: newtype ToleranceException
+ Signet.Unstable.Exception.ToleranceException: unwrap :: ToleranceException -> Timestamp
+ Signet.Unstable.Exception.ToleranceExceptionTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Exception.VerificationException: MkVerificationException :: Id -> VerificationException
+ Signet.Unstable.Exception.VerificationException: instance GHC.Classes.Eq Signet.Unstable.Exception.VerificationException.VerificationException
+ Signet.Unstable.Exception.VerificationException: instance GHC.Exception.Type.Exception Signet.Unstable.Exception.VerificationException.VerificationException
+ Signet.Unstable.Exception.VerificationException: instance GHC.Show.Show Signet.Unstable.Exception.VerificationException.VerificationException
+ Signet.Unstable.Exception.VerificationException: newtype VerificationException
+ Signet.Unstable.Exception.VerificationException: unwrap :: VerificationException -> Id
+ Signet.Unstable.Exception.VerificationExceptionTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Extra.Either: hush :: Either x a -> Maybe a
+ Signet.Unstable.Extra.Either: throw :: (Exception e, MonadThrow m) => Either e a -> m a
+ Signet.Unstable.Extra.EitherTest: MkTestException :: TestException
+ Signet.Unstable.Extra.EitherTest: data TestException
+ Signet.Unstable.Extra.EitherTest: instance GHC.Classes.Eq Signet.Unstable.Extra.EitherTest.TestException
+ Signet.Unstable.Extra.EitherTest: instance GHC.Exception.Type.Exception Signet.Unstable.Extra.EitherTest.TestException
+ Signet.Unstable.Extra.EitherTest: instance GHC.Show.Show Signet.Unstable.Extra.EitherTest.TestException
+ Signet.Unstable.Extra.EitherTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Extra.Http: hWebhookId :: HeaderName
+ Signet.Unstable.Extra.Http: hWebhookSignature :: HeaderName
+ Signet.Unstable.Extra.Http: hWebhookTimestamp :: HeaderName
+ Signet.Unstable.Extra.HttpTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Extra.Maybe: note :: e -> Maybe a -> Either e a
+ Signet.Unstable.Extra.MaybeTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.AsymmetricSignature: MkAsymmetricSignature :: Signature -> AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: instance GHC.Show.Show Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: newtype AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: parse :: ByteString -> Either InvalidAsymmetricSignature AsymmetricSignature
+ Signet.Unstable.Type.AsymmetricSignature: render :: AsymmetricSignature -> ByteString
+ Signet.Unstable.Type.AsymmetricSignature: unwrap :: AsymmetricSignature -> Signature
+ Signet.Unstable.Type.AsymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Id: MkId :: ByteString -> Id
+ Signet.Unstable.Type.Id: instance GHC.Classes.Eq Signet.Unstable.Type.Id.Id
+ Signet.Unstable.Type.Id: instance GHC.Show.Show Signet.Unstable.Type.Id.Id
+ Signet.Unstable.Type.Id: newtype Id
+ Signet.Unstable.Type.Id: parse :: ByteString -> Either InvalidId Id
+ Signet.Unstable.Type.Id: render :: Id -> ByteString
+ Signet.Unstable.Type.Id: separator :: Word8
+ Signet.Unstable.Type.Id: unwrap :: Id -> ByteString
+ Signet.Unstable.Type.IdTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Message: MkMessage :: Id -> Timestamp -> Payload -> Message
+ Signet.Unstable.Type.Message: [id_] :: Message -> Id
+ Signet.Unstable.Type.Message: [payload] :: Message -> Payload
+ Signet.Unstable.Type.Message: [timestamp] :: Message -> Timestamp
+ Signet.Unstable.Type.Message: data Message
+ Signet.Unstable.Type.Message: instance GHC.Classes.Eq Signet.Unstable.Type.Message.Message
+ Signet.Unstable.Type.Message: instance GHC.Show.Show Signet.Unstable.Type.Message.Message
+ Signet.Unstable.Type.Message: parse :: ByteString -> Either InvalidMessage Message
+ Signet.Unstable.Type.Message: render :: Message -> ByteString
+ Signet.Unstable.Type.MessageTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Payload: MkPayload :: ByteString -> Payload
+ Signet.Unstable.Type.Payload: instance GHC.Classes.Eq Signet.Unstable.Type.Payload.Payload
+ Signet.Unstable.Type.Payload: instance GHC.Show.Show Signet.Unstable.Type.Payload.Payload
+ Signet.Unstable.Type.Payload: newtype Payload
+ Signet.Unstable.Type.Payload: unwrap :: Payload -> ByteString
+ Signet.Unstable.Type.PayloadTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.PublicKey: MkPublicKey :: PublicKey -> PublicKey
+ Signet.Unstable.Type.PublicKey: instance GHC.Classes.Eq Signet.Unstable.Type.PublicKey.PublicKey
+ Signet.Unstable.Type.PublicKey: instance GHC.Show.Show Signet.Unstable.Type.PublicKey.PublicKey
+ Signet.Unstable.Type.PublicKey: newtype PublicKey
+ Signet.Unstable.Type.PublicKey: parse :: ByteString -> Either InvalidPublicKey PublicKey
+ Signet.Unstable.Type.PublicKey: prefix :: ByteString
+ Signet.Unstable.Type.PublicKey: render :: PublicKey -> ByteString
+ Signet.Unstable.Type.PublicKey: unwrap :: PublicKey -> PublicKey
+ Signet.Unstable.Type.PublicKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Secret: MkSecret :: ScrubbedBytes -> Secret
+ Signet.Unstable.Type.Secret: instance GHC.Classes.Eq Signet.Unstable.Type.Secret.Secret
+ Signet.Unstable.Type.Secret: instance GHC.Show.Show Signet.Unstable.Type.Secret.Secret
+ Signet.Unstable.Type.Secret: newtype Secret
+ Signet.Unstable.Type.Secret: parse :: ByteString -> Either InvalidSecret Secret
+ Signet.Unstable.Type.Secret: prefix :: ByteString
+ Signet.Unstable.Type.Secret: render :: Secret -> ByteString
+ Signet.Unstable.Type.Secret: unwrap :: Secret -> ScrubbedBytes
+ Signet.Unstable.Type.SecretKey: MkSecretKey :: SecretKey -> SecretKey
+ Signet.Unstable.Type.SecretKey: instance GHC.Classes.Eq Signet.Unstable.Type.SecretKey.SecretKey
+ Signet.Unstable.Type.SecretKey: instance GHC.Show.Show Signet.Unstable.Type.SecretKey.SecretKey
+ Signet.Unstable.Type.SecretKey: newtype SecretKey
+ Signet.Unstable.Type.SecretKey: parse :: ByteString -> Either InvalidSecretKey SecretKey
+ Signet.Unstable.Type.SecretKey: prefix :: ByteString
+ Signet.Unstable.Type.SecretKey: render :: SecretKey -> ByteString
+ Signet.Unstable.Type.SecretKey: unwrap :: SecretKey -> SecretKey
+ Signet.Unstable.Type.SecretKeyTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.SecretTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Signature: Asymmetric :: AsymmetricSignature -> Signature
+ Signet.Unstable.Type.Signature: Symmetric :: SymmetricSignature -> Signature
+ Signet.Unstable.Type.Signature: asymmetricPrefix :: ByteString
+ Signet.Unstable.Type.Signature: data Signature
+ Signet.Unstable.Type.Signature: instance GHC.Classes.Eq Signet.Unstable.Type.Signature.Signature
+ Signet.Unstable.Type.Signature: instance GHC.Show.Show Signet.Unstable.Type.Signature.Signature
+ Signet.Unstable.Type.Signature: parse :: ByteString -> Either InvalidSignature (Either UnknownSignature Signature)
+ Signet.Unstable.Type.Signature: render :: Signature -> ByteString
+ Signet.Unstable.Type.Signature: separator :: Word8
+ Signet.Unstable.Type.Signature: symmetricPrefix :: ByteString
+ Signet.Unstable.Type.SignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Signatures: MkSignatures :: [Signature] -> Signatures
+ Signet.Unstable.Type.Signatures: instance GHC.Classes.Eq Signet.Unstable.Type.Signatures.Signatures
+ Signet.Unstable.Type.Signatures: instance GHC.Show.Show Signet.Unstable.Type.Signatures.Signatures
+ Signet.Unstable.Type.Signatures: newtype Signatures
+ Signet.Unstable.Type.Signatures: parse :: ByteString -> Either InvalidSignature ([UnknownSignature], Signatures)
+ Signet.Unstable.Type.Signatures: render :: Signatures -> ByteString
+ Signet.Unstable.Type.Signatures: separator :: Word8
+ Signet.Unstable.Type.Signatures: unwrap :: Signatures -> [Signature]
+ Signet.Unstable.Type.SignaturesTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Signer: Asymmetric :: SecretKey -> Signer
+ Signet.Unstable.Type.Signer: Symmetric :: Secret -> Signer
+ Signet.Unstable.Type.Signer: asymmetric :: SecretKey -> Message -> AsymmetricSignature
+ Signet.Unstable.Type.Signer: data Signer
+ Signet.Unstable.Type.Signer: instance GHC.Classes.Eq Signet.Unstable.Type.Signer.Signer
+ Signet.Unstable.Type.Signer: instance GHC.Show.Show Signet.Unstable.Type.Signer.Signer
+ Signet.Unstable.Type.Signer: parse :: ByteString -> Either InvalidSigner Signer
+ Signet.Unstable.Type.Signer: render :: Signer -> ByteString
+ Signet.Unstable.Type.Signer: sign :: Signer -> Message -> Signature
+ Signet.Unstable.Type.Signer: symmetric :: Secret -> Message -> SymmetricSignature
+ Signet.Unstable.Type.SignerTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.SymmetricSignature: MkSymmetricSignature :: Digest SHA256 -> SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: instance GHC.Classes.Eq Signet.Unstable.Type.SymmetricSignature.SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: instance GHC.Show.Show Signet.Unstable.Type.SymmetricSignature.SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: newtype SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: parse :: ByteString -> Either InvalidSymmetricSignature SymmetricSignature
+ Signet.Unstable.Type.SymmetricSignature: render :: SymmetricSignature -> ByteString
+ Signet.Unstable.Type.SymmetricSignature: unwrap :: SymmetricSignature -> Digest SHA256
+ Signet.Unstable.Type.SymmetricSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Test: MkTest :: (HasCallStack => String -> IO Void) -> (String -> spec () -> spec ()) -> (String -> IO () -> spec ()) -> Test (spec :: Type -> Type)
+ Signet.Unstable.Type.Test: [assertFailure] :: Test (spec :: Type -> Type) -> HasCallStack => String -> IO Void
+ Signet.Unstable.Type.Test: [describe] :: Test (spec :: Type -> Type) -> String -> spec () -> spec ()
+ Signet.Unstable.Type.Test: [it] :: Test (spec :: Type -> Type) -> String -> IO () -> spec ()
+ Signet.Unstable.Type.Test: assertEq :: forall a (tree :: Type -> Type). (HasCallStack, Eq a, Show a) => Test tree -> a -> a -> IO ()
+ Signet.Unstable.Type.Test: data Test (spec :: Type -> Type)
+ Signet.Unstable.Type.Timestamp: MkTimestamp :: UTCTime -> Timestamp
+ Signet.Unstable.Type.Timestamp: format :: String
+ Signet.Unstable.Type.Timestamp: instance GHC.Classes.Eq Signet.Unstable.Type.Timestamp.Timestamp
+ Signet.Unstable.Type.Timestamp: instance GHC.Show.Show Signet.Unstable.Type.Timestamp.Timestamp
+ Signet.Unstable.Type.Timestamp: newtype Timestamp
+ Signet.Unstable.Type.Timestamp: parse :: ByteString -> Either InvalidTimestamp Timestamp
+ Signet.Unstable.Type.Timestamp: render :: Timestamp -> ByteString
+ Signet.Unstable.Type.Timestamp: unwrap :: Timestamp -> UTCTime
+ Signet.Unstable.Type.TimestampTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Tolerance: MkTolerance :: NominalDiffTime -> Tolerance
+ Signet.Unstable.Type.Tolerance: check :: Tolerance -> UTCTime -> Timestamp -> Either ToleranceException ()
+ Signet.Unstable.Type.Tolerance: instance GHC.Classes.Eq Signet.Unstable.Type.Tolerance.Tolerance
+ Signet.Unstable.Type.Tolerance: instance GHC.Show.Show Signet.Unstable.Type.Tolerance.Tolerance
+ Signet.Unstable.Type.Tolerance: newtype Tolerance
+ Signet.Unstable.Type.Tolerance: typical :: Tolerance
+ Signet.Unstable.Type.Tolerance: unwrap :: Tolerance -> NominalDiffTime
+ Signet.Unstable.Type.ToleranceTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.UnknownSignature: MkUnknownSignature :: ByteString -> UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: instance GHC.Classes.Eq Signet.Unstable.Type.UnknownSignature.UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: instance GHC.Show.Show Signet.Unstable.Type.UnknownSignature.UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: newtype UnknownSignature
+ Signet.Unstable.Type.UnknownSignature: unwrap :: UnknownSignature -> ByteString
+ Signet.Unstable.Type.UnknownSignatureTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.Unstable.Type.Verifier: Asymmetric :: PublicKey -> Verifier
+ Signet.Unstable.Type.Verifier: Symmetric :: Secret -> Verifier
+ Signet.Unstable.Type.Verifier: asymmetric :: PublicKey -> Message -> Signatures -> Either VerificationException AsymmetricSignature
+ Signet.Unstable.Type.Verifier: data Verifier
+ Signet.Unstable.Type.Verifier: instance GHC.Classes.Eq Signet.Unstable.Type.Verifier.Verifier
+ Signet.Unstable.Type.Verifier: instance GHC.Show.Show Signet.Unstable.Type.Verifier.Verifier
+ Signet.Unstable.Type.Verifier: parse :: ByteString -> Either InvalidVerifier Verifier
+ Signet.Unstable.Type.Verifier: render :: Verifier -> ByteString
+ Signet.Unstable.Type.Verifier: symmetric :: Secret -> Message -> Signatures -> Either VerificationException SymmetricSignature
+ Signet.Unstable.Type.Verifier: verify :: Verifier -> Message -> Signatures -> Either VerificationException Signature
+ Signet.Unstable.Type.VerifierTest: spec :: Monad tree => Test tree -> tree ()
+ Signet.UnstableTest: spec :: Monad tree => Test tree -> tree ()
+ SignetTest: spec :: Monad tree => Test tree -> tree ()
Files
- signet.cabal +48/−71
- source/libraries/signet/Signet.hs +0/−88
- source/libraries/test/Signet/Unstable/Exception/InvalidAsymmetricSignatureTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidIdTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidMessageTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidPublicKeyTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidSecretKeyTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidSecretTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidSignatureTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidSignerTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidSymmetricSignatureTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidTimestampTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/InvalidVerifierTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/SignetExceptionTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/ToleranceExceptionTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Exception/VerificationExceptionTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Extra/EitherTest.hs +0/−31
- source/libraries/test/Signet/Unstable/Extra/HttpTest.hs +0/−21
- source/libraries/test/Signet/Unstable/Extra/MaybeTest.hs +0/−15
- source/libraries/test/Signet/Unstable/Extra/Tasty.hs +0/−13
- source/libraries/test/Signet/Unstable/Type/AsymmetricSignatureTest.hs +0/−27
- source/libraries/test/Signet/Unstable/Type/IdTest.hs +0/−26
- source/libraries/test/Signet/Unstable/Type/MessageTest.hs +0/−47
- source/libraries/test/Signet/Unstable/Type/PayloadTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Type/PublicKeyTest.hs +0/−32
- source/libraries/test/Signet/Unstable/Type/SecretKeyTest.hs +0/−32
- source/libraries/test/Signet/Unstable/Type/SecretTest.hs +0/−31
- source/libraries/test/Signet/Unstable/Type/SignatureTest.hs +0/−53
- source/libraries/test/Signet/Unstable/Type/SignaturesTest.hs +0/−72
- source/libraries/test/Signet/Unstable/Type/SignerTest.hs +0/−76
- source/libraries/test/Signet/Unstable/Type/SymmetricSignatureTest.hs +0/−27
- source/libraries/test/Signet/Unstable/Type/TimestampTest.hs +0/−33
- source/libraries/test/Signet/Unstable/Type/ToleranceTest.hs +0/−34
- source/libraries/test/Signet/Unstable/Type/UnknownSignatureTest.hs +0/−7
- source/libraries/test/Signet/Unstable/Type/VerifierTest.hs +0/−110
- source/libraries/test/Signet/UnstableTest.hs +0/−57
- source/libraries/test/SignetTest.hs +0/−73
- source/libraries/unstable/Signet/Unstable.hs +0/−196
- source/libraries/unstable/Signet/Unstable/Exception/InvalidAsymmetricSignature.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidId.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidMessage.hs +0/−18
- source/libraries/unstable/Signet/Unstable/Exception/InvalidPublicKey.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidSecret.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidSecretKey.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidSignature.hs +0/−18
- source/libraries/unstable/Signet/Unstable/Exception/InvalidSigner.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidSymmetricSignature.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidTimestamp.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/InvalidVerifier.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/SignetException.hs +0/−18
- source/libraries/unstable/Signet/Unstable/Exception/ToleranceException.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Exception/VerificationException.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Extra/Either.hs +0/−9
- source/libraries/unstable/Signet/Unstable/Extra/Http.hs +0/−14
- source/libraries/unstable/Signet/Unstable/Extra/Maybe.hs +0/−4
- source/libraries/unstable/Signet/Unstable/Type/AsymmetricSignature.hs +0/−28
- source/libraries/unstable/Signet/Unstable/Type/Id.hs +0/−26
- source/libraries/unstable/Signet/Unstable/Type/Message.hs +0/−36
- source/libraries/unstable/Signet/Unstable/Type/Payload.hs +0/−10
- source/libraries/unstable/Signet/Unstable/Type/PublicKey.hs +0/−31
- source/libraries/unstable/Signet/Unstable/Type/Secret.hs +0/−27
- source/libraries/unstable/Signet/Unstable/Type/SecretKey.hs +0/−31
- source/libraries/unstable/Signet/Unstable/Type/Signature.hs +0/−49
- source/libraries/unstable/Signet/Unstable/Type/Signatures.hs +0/−30
- source/libraries/unstable/Signet/Unstable/Type/Signer.hs +0/−49
- source/libraries/unstable/Signet/Unstable/Type/SymmetricSignature.hs +0/−28
- source/libraries/unstable/Signet/Unstable/Type/Timestamp.hs +0/−33
- source/libraries/unstable/Signet/Unstable/Type/Tolerance.hs +0/−29
- source/libraries/unstable/Signet/Unstable/Type/UnknownSignature.hs +0/−10
- source/libraries/unstable/Signet/Unstable/Type/Verifier.hs +0/−75
- source/library/Signet.hs +88/−0
- source/library/Signet/Unstable.hs +196/−0
- source/library/Signet/Unstable/Exception/InvalidAsymmetricSignature.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidAsymmetricSignatureTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidId.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidIdTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidMessage.hs +18/−0
- source/library/Signet/Unstable/Exception/InvalidMessageTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidPublicKey.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidPublicKeyTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidSecret.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidSecretKey.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidSecretKeyTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidSecretTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidSignature.hs +18/−0
- source/library/Signet/Unstable/Exception/InvalidSignatureTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidSigner.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidSignerTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidSymmetricSignature.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidSymmetricSignatureTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidTimestamp.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidTimestampTest.hs +7/−0
- source/library/Signet/Unstable/Exception/InvalidVerifier.hs +14/−0
- source/library/Signet/Unstable/Exception/InvalidVerifierTest.hs +7/−0
- source/library/Signet/Unstable/Exception/SignetException.hs +18/−0
- source/library/Signet/Unstable/Exception/SignetExceptionTest.hs +7/−0
- source/library/Signet/Unstable/Exception/ToleranceException.hs +14/−0
- source/library/Signet/Unstable/Exception/ToleranceExceptionTest.hs +7/−0
- source/library/Signet/Unstable/Exception/VerificationException.hs +14/−0
- source/library/Signet/Unstable/Exception/VerificationExceptionTest.hs +7/−0
- source/library/Signet/Unstable/Extra/Either.hs +9/−0
- source/library/Signet/Unstable/Extra/EitherTest.hs +30/−0
- source/library/Signet/Unstable/Extra/Http.hs +14/−0
- source/library/Signet/Unstable/Extra/HttpTest.hs +20/−0
- source/library/Signet/Unstable/Extra/Maybe.hs +4/−0
- source/library/Signet/Unstable/Extra/MaybeTest.hs +14/−0
- source/library/Signet/Unstable/Type/AsymmetricSignature.hs +28/−0
- source/library/Signet/Unstable/Type/AsymmetricSignatureTest.hs +26/−0
- source/library/Signet/Unstable/Type/Id.hs +26/−0
- source/library/Signet/Unstable/Type/IdTest.hs +25/−0
- source/library/Signet/Unstable/Type/Message.hs +36/−0
- source/library/Signet/Unstable/Type/MessageTest.hs +49/−0
- source/library/Signet/Unstable/Type/Payload.hs +10/−0
- source/library/Signet/Unstable/Type/PayloadTest.hs +7/−0
- source/library/Signet/Unstable/Type/PublicKey.hs +31/−0
- source/library/Signet/Unstable/Type/PublicKeyTest.hs +31/−0
- source/library/Signet/Unstable/Type/Secret.hs +27/−0
- source/library/Signet/Unstable/Type/SecretKey.hs +31/−0
- source/library/Signet/Unstable/Type/SecretKeyTest.hs +31/−0
- source/library/Signet/Unstable/Type/SecretTest.hs +30/−0
- source/library/Signet/Unstable/Type/Signature.hs +49/−0
- source/library/Signet/Unstable/Type/SignatureTest.hs +52/−0
- source/library/Signet/Unstable/Type/Signatures.hs +30/−0
- source/library/Signet/Unstable/Type/SignaturesTest.hs +71/−0
- source/library/Signet/Unstable/Type/Signer.hs +49/−0
- source/library/Signet/Unstable/Type/SignerTest.hs +75/−0
- source/library/Signet/Unstable/Type/SymmetricSignature.hs +28/−0
- source/library/Signet/Unstable/Type/SymmetricSignatureTest.hs +26/−0
- source/library/Signet/Unstable/Type/Test.hs +20/−0
- source/library/Signet/Unstable/Type/Timestamp.hs +33/−0
- source/library/Signet/Unstable/Type/TimestampTest.hs +32/−0
- source/library/Signet/Unstable/Type/Tolerance.hs +29/−0
- source/library/Signet/Unstable/Type/ToleranceTest.hs +33/−0
- source/library/Signet/Unstable/Type/UnknownSignature.hs +10/−0
- source/library/Signet/Unstable/Type/UnknownSignatureTest.hs +7/−0
- source/library/Signet/Unstable/Type/Verifier.hs +75/−0
- source/library/Signet/Unstable/Type/VerifierTest.hs +109/−0
- source/library/Signet/UnstableTest.hs +56/−0
- source/library/SignetTest.hs +72/−0
- source/test-suite/Main.hs +15/−1
signet.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: signet-version: 0.2025.5.9+version: 0.2025.5.12 synopsis: Standard Webhooks description: Signet is a Haskell library for working with Standard Webhooks.@@ -32,6 +32,7 @@ -Wno-missing-deriving-strategies -Wno-missing-export-lists -Wno-missing-kind-signatures+ -Wno-missing-role-annotations -Wno-missing-safe-haskell-mode -Wno-prepositive-qualified-module -Wno-safe@@ -40,127 +41,103 @@ if flag(pedantic) ghc-options: -Werror -common executable+library import: library- ghc-options:- -rtsopts- -threaded--common dependencies build-depends: bytestring ^>=0.12, case-insensitive ^>=1.2.1.0, crypton ^>=0.34 || ^>=1.0.4, exceptions ^>=0.10.7,- memory ^>=0.18.0,- time ^>=1.12.2,--library unstable- import: library, dependencies- build-depends: http-types ^>=0.12.4,+ memory ^>=0.18.0, text ^>=2.0 || ^>=2.1,+ time ^>=1.12.2, - -- cabal-gild: discover source/libraries/unstable+ -- cabal-gild: discover source/library exposed-modules:+ Signet Signet.Unstable Signet.Unstable.Exception.InvalidAsymmetricSignature+ Signet.Unstable.Exception.InvalidAsymmetricSignatureTest Signet.Unstable.Exception.InvalidId+ Signet.Unstable.Exception.InvalidIdTest Signet.Unstable.Exception.InvalidMessage+ Signet.Unstable.Exception.InvalidMessageTest Signet.Unstable.Exception.InvalidPublicKey+ Signet.Unstable.Exception.InvalidPublicKeyTest Signet.Unstable.Exception.InvalidSecret Signet.Unstable.Exception.InvalidSecretKey- Signet.Unstable.Exception.InvalidSignature- Signet.Unstable.Exception.InvalidSigner- Signet.Unstable.Exception.InvalidSymmetricSignature- Signet.Unstable.Exception.InvalidTimestamp- Signet.Unstable.Exception.InvalidVerifier- Signet.Unstable.Exception.SignetException- Signet.Unstable.Exception.ToleranceException- Signet.Unstable.Exception.VerificationException- Signet.Unstable.Extra.Either- Signet.Unstable.Extra.Http- Signet.Unstable.Extra.Maybe- Signet.Unstable.Type.AsymmetricSignature- Signet.Unstable.Type.Id- Signet.Unstable.Type.Message- Signet.Unstable.Type.Payload- Signet.Unstable.Type.PublicKey- Signet.Unstable.Type.Secret- Signet.Unstable.Type.SecretKey- Signet.Unstable.Type.Signature- Signet.Unstable.Type.Signatures- Signet.Unstable.Type.Signer- Signet.Unstable.Type.SymmetricSignature- Signet.Unstable.Type.Timestamp- Signet.Unstable.Type.Tolerance- Signet.Unstable.Type.UnknownSignature- Signet.Unstable.Type.Verifier-- hs-source-dirs: source/libraries/unstable- visibility: public--library- import: library- build-depends: signet:unstable- -- cabal-gild: discover source/libraries/signet- exposed-modules: Signet- hs-source-dirs: source/libraries/signet--library test- import: library, dependencies- build-depends:- signet:unstable,- tasty ^>=1.4 || ^>=1.5.3,- tasty-hunit ^>=0.10.2,- transformers ^>=0.6.1.0,-- -- cabal-gild: discover source/libraries/test- exposed-modules:- Signet.Unstable.Exception.InvalidAsymmetricSignatureTest- Signet.Unstable.Exception.InvalidIdTest- Signet.Unstable.Exception.InvalidMessageTest- Signet.Unstable.Exception.InvalidPublicKeyTest Signet.Unstable.Exception.InvalidSecretKeyTest Signet.Unstable.Exception.InvalidSecretTest+ Signet.Unstable.Exception.InvalidSignature Signet.Unstable.Exception.InvalidSignatureTest+ Signet.Unstable.Exception.InvalidSigner Signet.Unstable.Exception.InvalidSignerTest+ Signet.Unstable.Exception.InvalidSymmetricSignature Signet.Unstable.Exception.InvalidSymmetricSignatureTest+ Signet.Unstable.Exception.InvalidTimestamp Signet.Unstable.Exception.InvalidTimestampTest+ Signet.Unstable.Exception.InvalidVerifier Signet.Unstable.Exception.InvalidVerifierTest+ Signet.Unstable.Exception.SignetException Signet.Unstable.Exception.SignetExceptionTest+ Signet.Unstable.Exception.ToleranceException Signet.Unstable.Exception.ToleranceExceptionTest+ Signet.Unstable.Exception.VerificationException Signet.Unstable.Exception.VerificationExceptionTest+ Signet.Unstable.Extra.Either Signet.Unstable.Extra.EitherTest+ Signet.Unstable.Extra.Http Signet.Unstable.Extra.HttpTest+ Signet.Unstable.Extra.Maybe Signet.Unstable.Extra.MaybeTest- Signet.Unstable.Extra.Tasty+ Signet.Unstable.Type.AsymmetricSignature Signet.Unstable.Type.AsymmetricSignatureTest+ Signet.Unstable.Type.Id Signet.Unstable.Type.IdTest+ Signet.Unstable.Type.Message Signet.Unstable.Type.MessageTest+ Signet.Unstable.Type.Payload Signet.Unstable.Type.PayloadTest+ Signet.Unstable.Type.PublicKey Signet.Unstable.Type.PublicKeyTest+ Signet.Unstable.Type.Secret+ Signet.Unstable.Type.SecretKey Signet.Unstable.Type.SecretKeyTest Signet.Unstable.Type.SecretTest+ Signet.Unstable.Type.Signature Signet.Unstable.Type.SignatureTest+ Signet.Unstable.Type.Signatures Signet.Unstable.Type.SignaturesTest+ Signet.Unstable.Type.Signer Signet.Unstable.Type.SignerTest+ Signet.Unstable.Type.SymmetricSignature Signet.Unstable.Type.SymmetricSignatureTest+ Signet.Unstable.Type.Test+ Signet.Unstable.Type.Timestamp Signet.Unstable.Type.TimestampTest+ Signet.Unstable.Type.Tolerance Signet.Unstable.Type.ToleranceTest+ Signet.Unstable.Type.UnknownSignature Signet.Unstable.Type.UnknownSignatureTest+ Signet.Unstable.Type.Verifier Signet.Unstable.Type.VerifierTest Signet.UnstableTest SignetTest - hs-source-dirs: source/libraries/test- visibility: public+ hs-source-dirs: source/library test-suite signet-test-suite- import: executable+ import: library build-depends:- signet:test,- tasty,+ signet,+ tasty ^>=1.4 || ^>=1.5.3,+ tasty-hunit ^>=0.10.2,+ transformers ^>=0.6.1.0,++ ghc-options:+ -rtsopts+ -threaded hs-source-dirs: source/test-suite main-is: Main.hs
− source/libraries/signet/Signet.hs
@@ -1,88 +0,0 @@-module Signet- ( -- * Verification- Signet.Unstable.verifyWebhookText,- Signet.Unstable.verifyWebhookByteString,- Signet.Unstable.verifyWebhook,- Signet.Unstable.verifyWebhookWith,-- -- * Signing- Signet.Unstable.signWebhook,-- -- * Headers- Signet.Unstable.Extra.Http.hWebhookId,- Signet.Unstable.Extra.Http.hWebhookTimestamp,- Signet.Unstable.Extra.Http.hWebhookSignature,-- -- * Types- Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature (..),- Signet.Unstable.Type.Id.Id (..),- Signet.Unstable.parseId,- Signet.Unstable.Type.Message.Message (..),- Signet.Unstable.parseMessage,- Signet.Unstable.Type.Payload.Payload (..),- Signet.Unstable.Type.PublicKey.PublicKey (..),- Signet.Unstable.Type.Secret.Secret (..),- Signet.Unstable.Type.SecretKey.SecretKey (..),- Signet.Unstable.Type.Signature.Signature (Signet.Unstable.AsymmetricSignature, Signet.Unstable.SymmetricSignature),- Signet.Unstable.Type.Signatures.Signatures (..),- Signet.Unstable.parseSignatures,- Signet.Unstable.Type.Signer.Signer (Signet.Unstable.AsymmetricSigner, Signet.Unstable.SymmetricSigner),- Signet.Unstable.parseSigner,- Signet.Unstable.Type.SymmetricSignature.SymmetricSignature (..),- Signet.Unstable.Type.Timestamp.Timestamp (..),- Signet.Unstable.parseTimestamp,- Signet.Unstable.Type.Tolerance.Tolerance (..),- Signet.Unstable.typicalTolerance,- Signet.Unstable.Type.UnknownSignature.UnknownSignature (..),- Signet.Unstable.Type.Verifier.Verifier (Signet.Unstable.AsymmetricVerifier, Signet.Unstable.SymmetricVerifier),- Signet.Unstable.parseVerifier,-- -- * Exceptions- Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature (..),- Signet.Unstable.Exception.InvalidId.InvalidId (..),- Signet.Unstable.Exception.InvalidMessage.InvalidMessage (..),- Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey (..),- Signet.Unstable.Exception.InvalidSecret.InvalidSecret (..),- Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey (..),- Signet.Unstable.Exception.InvalidSignature.InvalidSignature (..),- Signet.Unstable.Exception.InvalidSigner.InvalidSigner (..),- Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature (..),- Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp (..),- Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier (..),- Signet.Unstable.Exception.SignetException.SignetException (..),- Signet.Unstable.Exception.ToleranceException.ToleranceException (..),- Signet.Unstable.Exception.VerificationException.VerificationException (..),- )-where--import qualified Signet.Unstable-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidId-import qualified Signet.Unstable.Exception.InvalidMessage-import qualified Signet.Unstable.Exception.InvalidPublicKey-import qualified Signet.Unstable.Exception.InvalidSecret-import qualified Signet.Unstable.Exception.InvalidSecretKey-import qualified Signet.Unstable.Exception.InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSigner-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature-import qualified Signet.Unstable.Exception.InvalidTimestamp-import qualified Signet.Unstable.Exception.InvalidVerifier-import qualified Signet.Unstable.Exception.SignetException-import qualified Signet.Unstable.Exception.ToleranceException-import qualified Signet.Unstable.Exception.VerificationException-import qualified Signet.Unstable.Extra.Http-import qualified Signet.Unstable.Type.AsymmetricSignature-import qualified Signet.Unstable.Type.Id-import qualified Signet.Unstable.Type.Message-import qualified Signet.Unstable.Type.Payload-import qualified Signet.Unstable.Type.PublicKey-import qualified Signet.Unstable.Type.Secret-import qualified Signet.Unstable.Type.SecretKey-import qualified Signet.Unstable.Type.Signature-import qualified Signet.Unstable.Type.Signatures-import qualified Signet.Unstable.Type.Signer-import qualified Signet.Unstable.Type.SymmetricSignature-import qualified Signet.Unstable.Type.Timestamp-import qualified Signet.Unstable.Type.Tolerance-import qualified Signet.Unstable.Type.UnknownSignature-import qualified Signet.Unstable.Type.Verifier
− source/libraries/test/Signet/Unstable/Exception/InvalidAsymmetricSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidAsymmetricSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidAsymmetricSignature" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidIdTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidIdTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidId" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidMessageTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidMessageTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidMessage" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidPublicKeyTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidPublicKeyTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidPublicKey" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSecretKeyTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSecretKeyTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSecretKey" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSecretTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSecretTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSecret" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSignature" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSignerTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSignerTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSigner" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidSymmetricSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidSymmetricSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidSymmetricSignature" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidTimestampTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidTimestampTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidTimestamp" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/InvalidVerifierTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.InvalidVerifierTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.InvalidVerifier" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/SignetExceptionTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.SignetExceptionTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.SignetException" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/ToleranceExceptionTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.ToleranceExceptionTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.ToleranceException" $ do- pure ()
− source/libraries/test/Signet/Unstable/Exception/VerificationExceptionTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Exception.VerificationExceptionTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Exception.VerificationException" $ do- pure ()
− source/libraries/test/Signet/Unstable/Extra/EitherTest.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Extra.EitherTest where--import qualified Control.Monad.Catch as Exception-import qualified Data.Void as Void-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Extra.Either" $ do- Tasty.describe "hush" $ do- Tasty.it "works with Left" $ do- Either.hush (Left () :: Either () Void.Void) @?= Nothing-- Tasty.it "works with Right" $ do- Either.hush (Right () :: Either Void.Void ()) @?= Just ()-- Tasty.describe "throw" $ do- Tasty.it "throws an exception for Left" $ do- result <- Exception.try . Either.throw $ Left MkTestException- result @?= (Left MkTestException :: Either TestException Void.Void)-- Tasty.it "returns the value for Right" $ do- value <- Either.throw (Right () :: Either Void.Void ())- value @?= ()--data TestException- = MkTestException- deriving (Eq, Show)--instance Exception.Exception TestException
− source/libraries/test/Signet/Unstable/Extra/HttpTest.hs
@@ -1,21 +0,0 @@-module Signet.Unstable.Extra.HttpTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.CaseInsensitive as CI-import qualified Signet.Unstable.Extra.Http as Http-import qualified Signet.Unstable.Extra.Tasty as Tasty-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Extra.Http" $ do- Tasty.describe "hWebhookId" $ do- Tasty.it "creates the correct header name" $ do- Http.hWebhookId @?= CI.mk (Ascii.pack "webhook-id")-- Tasty.describe "hWebhookSignature" $ do- Tasty.it "creates the correct header name" $ do- Http.hWebhookSignature @?= CI.mk (Ascii.pack "webhook-signature")-- Tasty.describe "hWebhookTimestamp" $ do- Tasty.it "creates the correct header name" $ do- Http.hWebhookTimestamp @?= CI.mk (Ascii.pack "webhook-timestamp")
− source/libraries/test/Signet/Unstable/Extra/MaybeTest.hs
@@ -1,15 +0,0 @@-module Signet.Unstable.Extra.MaybeTest where--import qualified Data.Void as Void-import qualified Signet.Unstable.Extra.Maybe as Maybe-import qualified Signet.Unstable.Extra.Tasty as Tasty-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Extra.Maybe" $ do- Tasty.describe "note" $ do- Tasty.it "works with nothing" $ do- Maybe.note () (Nothing :: Maybe Void.Void) @?= Left ()-- Tasty.it "works with just" $ do- Maybe.note () (Just True) @?= Right True
− source/libraries/test/Signet/Unstable/Extra/Tasty.hs
@@ -1,13 +0,0 @@-module Signet.Unstable.Extra.Tasty where--import qualified Control.Monad.Trans.Writer as Writer-import qualified Test.Tasty as Tasty-import qualified Test.Tasty.HUnit as Tasty--type Spec = Writer.Writer [Tasty.TestTree] ()--describe :: Tasty.TestName -> Spec -> Spec-describe testName = Writer.tell . pure . Tasty.testGroup testName . Writer.execWriter--it :: Tasty.TestName -> Tasty.Assertion -> Spec-it testName = Writer.tell . pure . Tasty.testCase testName
− source/libraries/test/Signet/Unstable/Type/AsymmetricSignatureTest.hs
@@ -1,27 +0,0 @@-module Signet.Unstable.Type.AsymmetricSignatureTest where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.AsymmetricSignature" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid input" $ do- let byteString = Ascii.pack "invalid"- let result = AsymmetricSignature.parse byteString- result @?= Left (InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString)-- Tasty.it "succeeds with valid input" $ do- let result = AsymmetricSignature.parse $ Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="- signature <- Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"- result @?= Right (AsymmetricSignature.MkAsymmetricSignature signature)-- Tasty.describe "render" $ do- Tasty.it "works" $ do- asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"- AsymmetricSignature.render asymmetricSignature @?= Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="
− source/libraries/test/Signet/Unstable/Type/IdTest.hs
@@ -1,26 +0,0 @@-module Signet.Unstable.Type.IdTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidId as InvalidId-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Id as Id-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Id" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with input containing separator" $ do- let byteString = Ascii.pack "invalid.id"- let result = Id.parse byteString- result @?= Left (InvalidId.MkInvalidId byteString)-- Tasty.it "succeeds with valid input" $ do- let byteString = Ascii.pack "valid-id"- let result = Id.parse byteString- result @?= Right (Id.MkId byteString)-- Tasty.describe "render" $ do- Tasty.it "returns the original ByteString" $ do- let byteString = Ascii.pack "valid-id"- let id_ = Id.MkId byteString- Id.render id_ @?= byteString
− source/libraries/test/Signet/Unstable/Type/MessageTest.hs
@@ -1,47 +0,0 @@-module Signet.Unstable.Type.MessageTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-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.Timestamp as Timestamp-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Message" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid timestamp" $ do- let timestamp = Ascii.pack "invalid"- let byteString = Ascii.pack "i." <> timestamp <> Ascii.pack ".p"- let result = Message.parse byteString- result @?= Left (InvalidMessage.InvalidTimestamp $ InvalidTimestamp.MkInvalidTimestamp timestamp)-- Tasty.it "succeeds with valid input" $ do- let result = Message.parse $ Ascii.pack "i.0.p"- id_ <- Either.throw . Id.parse $ Ascii.pack "i"- timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"- let payload = Payload.MkPayload $ Ascii.pack "p"- result- @?= Right- Message.MkMessage- { Message.id_ = id_,- Message.timestamp = timestamp,- Message.payload = payload- }-- Tasty.describe "render" $ do- Tasty.it "returns the correct ByteString representation" $ do- id_ <- Either.throw . Id.parse $ Ascii.pack "i"- timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"- let payload = Payload.MkPayload $ Ascii.pack "p"- let message =- Message.MkMessage- { Message.id_ = id_,- Message.timestamp = timestamp,- Message.payload = payload- }- Message.render message @?= Ascii.pack "i.0.p"
− source/libraries/test/Signet/Unstable/Type/PayloadTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Type.PayloadTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Payload" $ do- pure ()
− source/libraries/test/Signet/Unstable/Type/PublicKeyTest.hs
@@ -1,32 +0,0 @@-module Signet.Unstable.Type.PublicKeyTest where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.PublicKey" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid prefix" $ do- let byteString = Ascii.pack "invalid"- let result = PublicKey.parse byteString- result @?= Left (InvalidPublicKey.MkInvalidPublicKey byteString)-- Tasty.it "fails with invalid input" $ do- let byteString = Ascii.pack "whpk_invalid"- let result = PublicKey.parse byteString- result @?= Left (InvalidPublicKey.MkInvalidPublicKey byteString)-- Tasty.it "succeeds with valid input" $ do- let result = PublicKey.parse $ Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="- publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"- result @?= Right publicKey-- Tasty.describe "render" $ do- Tasty.it "works" $ do- publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"- PublicKey.render publicKey @?= Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
− source/libraries/test/Signet/Unstable/Type/SecretKeyTest.hs
@@ -1,32 +0,0 @@-module Signet.Unstable.Type.SecretKeyTest where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.SecretKey as SecretKey-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.SecretKey" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid prefix" $ do- let byteString = Ascii.pack "invalid"- let result = SecretKey.parse byteString- result @?= Left (InvalidSecretKey.MkInvalidSecretKey byteString)-- Tasty.it "fails with invalid input" $ do- let byteString = Ascii.pack "whsk_invalid"- let result = SecretKey.parse byteString- result @?= Left (InvalidSecretKey.MkInvalidSecretKey byteString)-- Tasty.it "succeeds with valid input" $ do- let result = SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="- secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"- result @?= Right secretKey-- Tasty.describe "render" $ do- Tasty.it "works" $ do- secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"- SecretKey.render secretKey @?= Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
− source/libraries/test/Signet/Unstable/Type/SecretTest.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Type.SecretTest where--import qualified Data.ByteArray as ByteArray-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Secret as Secret-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Secret" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid prefix" $ do- let byteString = Ascii.pack "invalid"- let result = Secret.parse byteString- result @?= Left (InvalidSecret.MkInvalidSecret byteString)-- Tasty.it "fails with invalid input" $ do- let byteString = Ascii.pack "whsec_invalid"- let result = Secret.parse byteString- result @?= Left (InvalidSecret.MkInvalidSecret byteString)-- Tasty.it "succeeds with valid input" $ do- let result = Secret.parse $ Ascii.pack "whsec_MDEyMzQ1Njc4OQ=="- let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"- result @?= Right secret-- Tasty.describe "render" $ do- Tasty.it "works" $ do- let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"- Secret.render secret @?= Ascii.pack "whsec_MDEyMzQ1Njc4OQ=="
− source/libraries/test/Signet/Unstable/Type/SignatureTest.hs
@@ -1,53 +0,0 @@-module Signet.Unstable.Type.SignatureTest where--import qualified Crypto.Error as Error-import qualified Crypto.Hash as Hash-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Signature" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid asymmetric signature" $ do- let byteString = Ascii.pack "invalid"- let result = Signature.parse $ Ascii.pack "v1a," <> byteString- result @?= Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString)-- Tasty.it "fails with invalid symmetric signature" $ do- let byteString = Ascii.pack "invalid"- let result = Signature.parse $ Ascii.pack "v1," <> byteString- result @?= Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString)-- Tasty.it "returns unknown signature with unrecognized prefix" $ do- let byteString = Ascii.pack "unknown"- let result = Signature.parse byteString- result @?= Right (Left $ UnknownSignature.MkUnknownSignature byteString)-- Tasty.it "succeeds with valid asymmetric signature" $ do- let byteString = Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="- signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"- Signature.parse byteString @?= Right (Right signature)-- Tasty.it "succeeds with valid symmetric signature" $ do- let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="- let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- Signature.parse byteString @?= Right (Right signature)-- Tasty.describe "render" $ do- Tasty.it "renders asymmetric signature correctly" $ do- signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"- Signature.render signature @?= Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="-- Tasty.it "renders symmetric signature correctly" $ do- let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- Signature.render signature @?= Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
− source/libraries/test/Signet/Unstable/Type/SignaturesTest.hs
@@ -1,72 +0,0 @@-module Signet.Unstable.Type.SignaturesTest where--import qualified Crypto.Error as Error-import qualified Crypto.Hash as Hash-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Signatures" $ do- Tasty.describe "parse" $ do- Tasty.it "succeeds with no signatures" $ do- Signatures.parse ByteString.empty @?= Right ([], Signatures.MkSignatures [])-- Tasty.it "succeeds with one signature" $ do- let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="- Signatures.parse byteString @?= Right ([], Signatures.MkSignatures [signature])-- Tasty.it "succeeds with many signatures" $ do- let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"- let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="- let signatures =- Signatures.MkSignatures- [ Signature.Symmetric symmetricSignature,- Signature.Asymmetric asymmetricSignature- ]- Signatures.parse byteString @?= Right ([], signatures)-- Tasty.it "fails with an invalid symmetric signature" $ do- let x = Ascii.pack "invalid"- let byteString = Ascii.pack "v1," <> x- Signatures.parse byteString @?= Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature x)-- Tasty.it "fails with an invalid asymmetric signature" $ do- let x = Ascii.pack "invalid"- let byteString = Ascii.pack "v1a," <> x- Signatures.parse byteString @?= Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature x)-- Tasty.it "succeeds with an unknown signature" $ do- let byteString = Ascii.pack "unknown"- Signatures.parse byteString @?= Right ([UnknownSignature.MkUnknownSignature byteString], Signatures.MkSignatures [])-- Tasty.describe "render" $ do- Tasty.it "renders no signatures" $ do- let signatures = Signatures.MkSignatures []- Signatures.render signatures @?= ByteString.empty-- Tasty.it "renders one signature" $ do- let signatures = Signatures.MkSignatures . pure . Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- Signatures.render signatures @?= Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="-- Tasty.it "renders many signatures" $ do- let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"- let signatures =- Signatures.MkSignatures- [ Signature.Symmetric symmetricSignature,- Signature.Asymmetric asymmetricSignature- ]- Signatures.render signatures @?= Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="
− source/libraries/test/Signet/Unstable/Type/SignerTest.hs
@@ -1,76 +0,0 @@-module Signet.Unstable.Type.SignerTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-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.Signer as Signer-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Signer" $ do- Tasty.describe "parse" $ do- Tasty.it "succeeds with a valid secret key" $ do- let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="- let actual = Signer.parse byteString- secretKey <- Either.throw $ SecretKey.parse byteString- actual @?= Right (Signer.Asymmetric secretKey)-- Tasty.it "succeeds with a valid secret" $ do- let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- let actual = Signer.parse byteString- secret <- Either.throw $ Secret.parse byteString- actual @?= Right (Signer.Symmetric secret)-- Tasty.it "fails with invalid input" $ do- let byteString = Ascii.pack "invalid"- let actual = Signer.parse byteString- actual @?= Left (InvalidSigner.MkInvalidSigner byteString)-- Tasty.describe "render" $ do- Tasty.it "works with a secret key" $ do- let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="- secretKey <- Either.throw . SecretKey.parse $ byteString- Signer.render (Signer.Asymmetric secretKey) @?= byteString-- Tasty.it "works with a secret" $ do- let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- secret <- Either.throw . Secret.parse $ byteString- Signer.render (Signer.Symmetric secret) @?= byteString-- Tasty.describe "sign" $ do- Tasty.it "works with asymmetric" $ do- signer <- Either.throw . Signer.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- let actual = Signer.sign signer message- Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="- actual @?= expected-- Tasty.it "works with symmetric" $ do- signer <- Either.throw . Signer.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- let actual = Signer.sign signer message- Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- actual @?= expected-- Tasty.describe "asymmetric" $ do- Tasty.it "creates correct asymmetric signature" $ do- secretKey <- Either.throw . SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- let actual = Signer.asymmetric secretKey message- expected <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="- actual @?= expected-- Tasty.describe "symmetric" $ do- Tasty.it "creates correct symmetric signature" $ do- secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- let actual = Signer.symmetric secret message- expected <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- actual @?= expected
− source/libraries/test/Signet/Unstable/Type/SymmetricSignatureTest.hs
@@ -1,27 +0,0 @@-module Signet.Unstable.Type.SymmetricSignatureTest where--import qualified Crypto.Hash as Hash-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.SymmetricSignature" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid symmetric signature" $ do- let byteString = Ascii.pack "invalid"- let result = SymmetricSignature.parse byteString- result @?= Left (InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString)-- Tasty.it "succeeds with valid symmetric signature" $ do- let byteString = Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="- let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- SymmetricSignature.parse byteString @?= Right signature-- Tasty.describe "render" $ do- Tasty.it "renders symmetric signature correctly" $ do- let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty- SymmetricSignature.render signature @?= Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
− source/libraries/test/Signet/Unstable/Type/TimestampTest.hs
@@ -1,33 +0,0 @@-module Signet.Unstable.Type.TimestampTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Timestamp as Timestamp-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Timestamp" $ do- Tasty.describe "parse" $ do- Tasty.it "fails with invalid timestamp format" $ do- let byteString = Ascii.pack "invalid-timestamp"- let result = Timestamp.parse byteString- result @?= Left (InvalidTimestamp.MkInvalidTimestamp byteString)-- Tasty.it "succeeds with valid timestamp format" $ do- let byteString = Ascii.pack "1617235200"- let result = Timestamp.parse byteString- case result of- Right timestamp -> do- let utcTime = Timestamp.unwrap timestamp- let expectedTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0- utcTime @?= expectedTime- Left _ -> fail "Expected Right but got Left"-- Tasty.describe "render" $ do- Tasty.it "returns the correct ByteString representation" $ do- let utcTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0- let timestamp = Timestamp.MkTimestamp utcTime- let expected = Ascii.pack "1617235200"- Timestamp.render timestamp @?= expected
− source/libraries/test/Signet/Unstable/Type/ToleranceTest.hs
@@ -1,34 +0,0 @@-module Signet.Unstable.Type.ToleranceTest where--import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Timestamp as Timestamp-import qualified Signet.Unstable.Type.Tolerance as Tolerance-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Tolerance" $ do- Tasty.describe "check" $ do- Tasty.it "succeeds when timestamp is within tolerance" $ do- let tolerance = Tolerance.MkTolerance 1- let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60- let timestamp = Timestamp.MkTimestamp utcTime- let result = Tolerance.check tolerance utcTime timestamp- result @?= Right ()-- Tasty.it "fails when timestamp is too old" $ do- let tolerance = Tolerance.MkTolerance 1- let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60- let timestamp = Timestamp.MkTimestamp utcTime- let now = Time.addUTCTime 2 utcTime- let result = Tolerance.check tolerance now timestamp- result @?= Left (ToleranceException.MkToleranceException timestamp)-- Tasty.it "fails when timestamp is in the future" $ do- let tolerance = Tolerance.MkTolerance 1- let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60- let timestamp = Timestamp.MkTimestamp utcTime- let now = Time.addUTCTime (-2) utcTime- let result = Tolerance.check tolerance now timestamp- result @?= Left (ToleranceException.MkToleranceException timestamp)
− source/libraries/test/Signet/Unstable/Type/UnknownSignatureTest.hs
@@ -1,7 +0,0 @@-module Signet.Unstable.Type.UnknownSignatureTest where--import qualified Signet.Unstable.Extra.Tasty as Tasty--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.UnknownSignature" $ do- pure ()
− source/libraries/test/Signet/Unstable/Type/VerifierTest.hs
@@ -1,110 +0,0 @@-module Signet.Unstable.Type.VerifierTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier-import qualified Signet.Unstable.Exception.VerificationException as VerificationException-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import qualified Signet.Unstable.Type.Secret as Secret-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.Verifier as Verifier-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable.Type.Verifier" $ do- Tasty.describe "parse" $ do- Tasty.it "succeeds with a valid public key" $ do- let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="- let actual = Verifier.parse byteString- publicKey <- Either.throw $ PublicKey.parse byteString- actual @?= Right (Verifier.Asymmetric publicKey)-- Tasty.it "succeeds with a valid secret" $ do- let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- let actual = Verifier.parse byteString- secret <- Either.throw $ Secret.parse byteString- actual @?= Right (Verifier.Symmetric secret)-- Tasty.it "fails with invalid input" $ do- let byteString = Ascii.pack "invalid"- let actual = Verifier.parse byteString- actual @?= Left (InvalidVerifier.MkInvalidVerifier byteString)-- Tasty.describe "render" $ do- Tasty.it "works with a public key" $ do- let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="- publicKey <- Either.throw . PublicKey.parse $ byteString- Verifier.render (Verifier.Asymmetric publicKey) @?= byteString-- Tasty.it "works with a secret" $ do- let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- secret <- Either.throw . Secret.parse $ byteString- Verifier.render (Verifier.Symmetric secret) @?= byteString-- Tasty.describe "verify" $ do- Tasty.it "succeeds with a valid asymmetric signature" $ do- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="- let actual = Verifier.verify verifier message signatures- Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="- actual @?= Right signature-- Tasty.it "fails with an invalid asymmetric signature" $ do- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="- let actual = Verifier.verify verifier message signatures- actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)-- Tasty.it "succeeds with a valid symmetric signature" $ do- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- let actual = Verifier.verify verifier message signatures- Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- actual @?= Right signature-- Tasty.it "fails with an invalid symmetric signature" $ do- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="- let actual = Verifier.verify verifier message signatures- actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)-- Tasty.describe "asymmetric" $ do- Tasty.it "succeeds with a valid signature" $ do- publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="- let actual = Verifier.asymmetric publicKey message signatures- asymmetricSignature <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="- actual @?= Right asymmetricSignature-- Tasty.it "fails with an invalid signature" $ do- publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="- let actual = Verifier.asymmetric publicKey message signatures- actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)-- Tasty.describe "symmetric" $ do- Tasty.it "succeeds with a valid signature" $ do- secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- let actual = Verifier.symmetric secret message signatures- symmetricSignature <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- actual @?= Right symmetricSignature-- Tasty.it "fails with an invalid signature" $ do- secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="- let actual = Verifier.symmetric secret message signatures- actual @?= Left (VerificationException.MkVerificationException $ Message.id_ message)
− source/libraries/test/Signet/UnstableTest.hs
@@ -1,57 +0,0 @@-module Signet.UnstableTest where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.Time as Time-import qualified Signet.Unstable as Signet-import qualified Signet.Unstable.Exception.SignetException as SignetException-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Exception.VerificationException as VerificationException-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Tasty as Tasty-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.Signatures as Signatures-import qualified Signet.Unstable.Type.Tolerance as Tolerance-import qualified Signet.Unstable.Type.Verifier as Verifier-import Test.Tasty.HUnit ((@?=))--spec :: Tasty.Spec-spec = Tasty.describe "Signet.Unstable" $ do- Tasty.describe "verifyWebhookText" $ do- pure ()-- Tasty.describe "verifyWebhookByteString" $ do- pure ()-- Tasty.describe "verifyWebhook" $ do- pure ()-- Tasty.describe "verifyWebhookWith" $ do- Tasty.it "succeeds with a valid symmetric signature" $ do- let tolerance = Tolerance.typical- let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- let byteString = Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- (_, signatures) <- Either.throw $ Signatures.parse byteString- let result = Signet.verifyWebhookWith tolerance now verifier message signatures- Right signature <- Either.throw $ Signature.parse byteString- result @?= Right signature-- Tasty.it "fails with an invalid timestamp" $ do- let tolerance = Tolerance.typical- let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.301.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="- let result = Signet.verifyWebhookWith tolerance now verifier message signatures- result @?= Left (SignetException.ToleranceException . ToleranceException.MkToleranceException $ Message.timestamp message)-- Tasty.it "fails with an invalid symmetric signature" $ do- let tolerance = Tolerance.typical- let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0- verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="- message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"- (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="- let result = Signet.verifyWebhookWith tolerance now verifier message signatures- result @?= Left (SignetException.VerificationException . VerificationException.MkVerificationException $ Message.id_ message)
− source/libraries/test/SignetTest.hs
@@ -1,73 +0,0 @@-module SignetTest where--import qualified Control.Monad.Trans.Writer as Writer-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignatureTest-import qualified Signet.Unstable.Exception.InvalidIdTest-import qualified Signet.Unstable.Exception.InvalidMessageTest-import qualified Signet.Unstable.Exception.InvalidPublicKeyTest-import qualified Signet.Unstable.Exception.InvalidSecretKeyTest-import qualified Signet.Unstable.Exception.InvalidSecretTest-import qualified Signet.Unstable.Exception.InvalidSignatureTest-import qualified Signet.Unstable.Exception.InvalidSignerTest-import qualified Signet.Unstable.Exception.InvalidSymmetricSignatureTest-import qualified Signet.Unstable.Exception.InvalidTimestampTest-import qualified Signet.Unstable.Exception.InvalidVerifierTest-import qualified Signet.Unstable.Exception.SignetExceptionTest-import qualified Signet.Unstable.Exception.ToleranceExceptionTest-import qualified Signet.Unstable.Exception.VerificationExceptionTest-import qualified Signet.Unstable.Extra.EitherTest-import qualified Signet.Unstable.Extra.HttpTest-import qualified Signet.Unstable.Extra.MaybeTest-import qualified Signet.Unstable.Type.AsymmetricSignatureTest-import qualified Signet.Unstable.Type.IdTest-import qualified Signet.Unstable.Type.MessageTest-import qualified Signet.Unstable.Type.PayloadTest-import qualified Signet.Unstable.Type.PublicKeyTest-import qualified Signet.Unstable.Type.SecretKeyTest-import qualified Signet.Unstable.Type.SecretTest-import qualified Signet.Unstable.Type.SignatureTest-import qualified Signet.Unstable.Type.SignaturesTest-import qualified Signet.Unstable.Type.SignerTest-import qualified Signet.Unstable.Type.SymmetricSignatureTest-import qualified Signet.Unstable.Type.TimestampTest-import qualified Signet.Unstable.Type.ToleranceTest-import qualified Signet.Unstable.Type.UnknownSignatureTest-import qualified Signet.Unstable.Type.VerifierTest-import qualified Signet.UnstableTest-import qualified Test.Tasty as Tasty--testTree :: Tasty.TestTree-testTree = Tasty.testGroup "signet" . Writer.execWriter $ do- Signet.Unstable.Exception.InvalidAsymmetricSignatureTest.spec- Signet.Unstable.Exception.InvalidIdTest.spec- Signet.Unstable.Exception.InvalidMessageTest.spec- Signet.Unstable.Exception.InvalidPublicKeyTest.spec- Signet.Unstable.Exception.InvalidSecretKeyTest.spec- Signet.Unstable.Exception.InvalidSecretTest.spec- Signet.Unstable.Exception.InvalidSignatureTest.spec- Signet.Unstable.Exception.InvalidSignerTest.spec- Signet.Unstable.Exception.InvalidSymmetricSignatureTest.spec- Signet.Unstable.Exception.InvalidTimestampTest.spec- Signet.Unstable.Exception.InvalidVerifierTest.spec- Signet.Unstable.Exception.SignetExceptionTest.spec- Signet.Unstable.Exception.ToleranceExceptionTest.spec- Signet.Unstable.Exception.VerificationExceptionTest.spec- Signet.Unstable.Extra.EitherTest.spec- Signet.Unstable.Extra.HttpTest.spec- Signet.Unstable.Extra.MaybeTest.spec- Signet.Unstable.Type.AsymmetricSignatureTest.spec- Signet.Unstable.Type.IdTest.spec- Signet.Unstable.Type.MessageTest.spec- Signet.Unstable.Type.PayloadTest.spec- Signet.Unstable.Type.PublicKeyTest.spec- Signet.Unstable.Type.SecretKeyTest.spec- Signet.Unstable.Type.SecretTest.spec- Signet.Unstable.Type.SignaturesTest.spec- Signet.Unstable.Type.SignatureTest.spec- Signet.Unstable.Type.SignerTest.spec- Signet.Unstable.Type.SymmetricSignatureTest.spec- Signet.Unstable.Type.TimestampTest.spec- Signet.Unstable.Type.ToleranceTest.spec- Signet.Unstable.Type.UnknownSignatureTest.spec- Signet.Unstable.Type.VerifierTest.spec- Signet.UnstableTest.spec
− source/libraries/unstable/Signet/Unstable.hs
@@ -1,196 +0,0 @@-{-# 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.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.UnknownSignature as UnknownSignature-import qualified Signet.Unstable.Type.Verifier as Verifier---- | Verifies a webhook with 'Text.Text' values. This is a wrapper around--- 'verifyWebhookByteString' that assumes all values are encoded as UTF-8.-verifyWebhookText ::- (MonadIO.MonadIO m, Exception.MonadThrow m) =>- -- | A 'Verifier.Verifier' for the webhook. Typically this will be- -- @"whsec_..."@ or @"whpk_..."@.- Text.Text ->- -- | The webhook's unique 'Id.Id'. Typically this will come from the- -- 'Signet.Unstable.Extra.Http.hWebhookId' header and look like @"msg_..."@.- Text.Text ->- -- | The webhook's 'Timestamp.Timestamp'. This is an integer number of- -- seconds since the Unix epoch. Typically this will come from the- -- 'Signet.Unstable.Extra.Http.hWebhookTimestamp' header. For example- -- @"981173106"@ for @2001-02-03T04:05:06Z@.- Text.Text ->- -- | The webhook's raw 'Payload.Payload'. Typically this will be a JSON- -- object like @{"event_type":"ping",...}@.- Text.Text ->- -- | The webhook's 'Signatures.Signatures'. Typically this will come from the- -- 'Signet.Unstable.Extra.Http.hWebhookSignature' header and look like- -- @"v1_..."@ or @"v1a_..."@.- Text.Text ->- m Signature.Signature-verifyWebhookText v i t p s =- verifyWebhookByteString- (Text.encodeUtf8 v)- (Text.encodeUtf8 i)- (Text.encodeUtf8 t)- (Text.encodeUtf8 p)- (Text.encodeUtf8 s)---- | Verifies a webhook with 'ByteString.ByteString' values. This is a--- wrapper around 'verifyWebhook'. See 'verifyWebhookText' for a description of--- the arguments.-verifyWebhookByteString ::- (MonadIO.MonadIO m, Exception.MonadThrow m) =>- -- | 'Verifier.Verifier'- ByteString.ByteString ->- -- | 'Id.Id'- ByteString.ByteString ->- -- | 'Timestamp.Timestamp'- ByteString.ByteString ->- -- | 'Payload.Payload'- ByteString.ByteString ->- -- | 'Signatures.Signatures'- ByteString.ByteString ->- m Signature.Signature-verifyWebhookByteString v i t p s = do- verifier <- Either.throw $ parseVerifier v- id_ <- Either.throw $ parseId i- timestamp <- Either.throw $ parseTimestamp t- let payload = Payload.MkPayload p- let message =- Message.MkMessage- { Message.id_ = id_,- Message.timestamp = timestamp,- Message.payload = payload- }- (_, signatures) <- Either.throw $ parseSignatures s- verifyWebhook verifier message signatures---- | Verifies a webhook. This is a wrapper around 'verifyWebhookWith' that uses--- 'typicalTolerance' and the current time.------ Throws an exception if the webhook is invalid.-verifyWebhook ::- (MonadIO.MonadIO m, Exception.MonadThrow m) =>- Verifier.Verifier ->- Message.Message ->- Signatures.Signatures ->- m Signature.Signature-verifyWebhook verifier message signatures = do- now <- MonadIO.liftIO Time.getCurrentTime- Either.throw $ verifyWebhookWith typicalTolerance now verifier message signatures---- | Verifies a webhook. This is the lowest-level function that gives you the--- most control. If you're looking for something that's easier to use and--- assumes some reasonable defaults, consider 'verifyWebhook'.-verifyWebhookWith ::- -- | Often 'typicalTolerance'.- Tolerance.Tolerance ->- -- | Usually 'Time.getCurrentTime'.- Time.UTCTime ->- -- | See 'parseVerifier'.- Verifier.Verifier ->- -- | See 'parseMessage'. Or 'Message.MkMessage' along with 'parseId',- -- 'parseTimestamp', and 'Payload.MkPayload'.- Message.Message ->- -- | See 'parseSignatures'.- Signatures.Signatures ->- Either SignetException.SignetException Signature.Signature-verifyWebhookWith tolerance now verifier message signatures = do- Bifunctor.first SignetException.ToleranceException- . Tolerance.check tolerance now- $ Message.timestamp message- Bifunctor.first SignetException.VerificationException $- Verifier.verify verifier message signatures---- | Alias for 'Tolerance.typical'.-typicalTolerance :: Tolerance.Tolerance-typicalTolerance = Tolerance.typical---- | Alias for 'Verifier.parse'.-parseVerifier :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier.Verifier-parseVerifier = Verifier.parse---- | Alias for 'Id.parse'.-parseId :: ByteString.ByteString -> Either InvalidId.InvalidId Id.Id-parseId = Id.parse---- | Alias for 'Timestamp.parse'.-parseTimestamp :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp.Timestamp-parseTimestamp = Timestamp.parse---- | Alias for 'Message.parse'.-parseMessage :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message.Message-parseMessage = Message.parse---- | Alias for 'Signatures.parse'.-parseSignatures ::- ByteString.ByteString ->- Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures.Signatures)-parseSignatures = Signatures.parse---- | Alias for 'Verifier.Asymmetric'.-pattern AsymmetricVerifier :: PublicKey.PublicKey -> Verifier.Verifier-pattern AsymmetricVerifier publicKey = Verifier.Asymmetric publicKey---- | Alias for 'Verifier.Symmetric'.-pattern SymmetricVerifier :: Secret.Secret -> Verifier.Verifier-pattern SymmetricVerifier secret = Verifier.Symmetric secret--{-# COMPLETE AsymmetricVerifier, SymmetricVerifier #-}---- | Alias for 'Signer.sign'.-signWebhook :: Signer.Signer -> Message.Message -> Signature.Signature-signWebhook = Signer.sign---- | Alias for 'Signer.parse'.-parseSigner :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer.Signer-parseSigner = Signer.parse---- | Alias for 'Signer.Asymmetric'.-pattern AsymmetricSigner :: SecretKey.SecretKey -> Signer.Signer-pattern AsymmetricSigner secretKey = Signer.Asymmetric secretKey---- | Alias for 'Signer.Symmetric'.-pattern SymmetricSigner :: Secret.Secret -> Signer.Signer-pattern SymmetricSigner secret = Signer.Symmetric secret--{-# COMPLETE AsymmetricSigner, SymmetricSigner #-}---- | Alias for 'Signature.Asymmetric'.-pattern AsymmetricSignature :: AsymmetricSignature.AsymmetricSignature -> Signature.Signature-pattern AsymmetricSignature asymmetricSignature = Signature.Asymmetric asymmetricSignature---- | Alias for 'Signature.Symmetric'.-pattern SymmetricSignature :: SymmetricSignature.SymmetricSignature -> Signature.Signature-pattern SymmetricSignature symmetricSignature = Signature.Symmetric symmetricSignature--{-# COMPLETE AsymmetricSignature, SymmetricSignature #-}
− source/libraries/unstable/Signet/Unstable/Exception/InvalidAsymmetricSignature.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidAsymmetricSignature where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidAsymmetricSignature- = MkInvalidAsymmetricSignature ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidAsymmetricSignature where- displayException = mappend "invalid asymmetric signature: " . show . unwrap--unwrap :: InvalidAsymmetricSignature -> ByteString.ByteString-unwrap (MkInvalidAsymmetricSignature byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidId.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidId where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidId- = MkInvalidId ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidId where- displayException = mappend "invalid ID: " . show . unwrap--unwrap :: InvalidId -> ByteString.ByteString-unwrap (MkInvalidId byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidMessage.hs
@@ -1,18 +0,0 @@-module Signet.Unstable.Exception.InvalidMessage where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Exception.InvalidId as InvalidId-import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp--data InvalidMessage- = InvalidId InvalidId.InvalidId- | InvalidTimestamp InvalidTimestamp.InvalidTimestamp- deriving (Eq, Show)--instance Exception.Exception InvalidMessage where- displayException invalidMessage =- "invalid message: " <> case invalidMessage of- InvalidId invalidId ->- Exception.displayException invalidId- InvalidTimestamp invalidTimestamp ->- Exception.displayException invalidTimestamp
− source/libraries/unstable/Signet/Unstable/Exception/InvalidPublicKey.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidPublicKey where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidPublicKey- = MkInvalidPublicKey ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidPublicKey where- displayException = mappend "invalid public key: " . show . unwrap--unwrap :: InvalidPublicKey -> ByteString.ByteString-unwrap (MkInvalidPublicKey byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSecret.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSecret where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSecret- = MkInvalidSecret ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidSecret where- displayException = mappend "invalid secret: " . show . unwrap--unwrap :: InvalidSecret -> ByteString.ByteString-unwrap (MkInvalidSecret byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSecretKey.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSecretKey where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSecretKey- = MkInvalidSecretKey ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidSecretKey where- displayException = mappend "invalid secret key: " . show . unwrap--unwrap :: InvalidSecretKey -> ByteString.ByteString-unwrap (MkInvalidSecretKey byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSignature.hs
@@ -1,18 +0,0 @@-module Signet.Unstable.Exception.InvalidSignature where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature--data InvalidSignature- = InvalidAsymmetricSignature InvalidAsymmetricSignature.InvalidAsymmetricSignature- | InvalidSymmetricSignature InvalidSymmetricSignature.InvalidSymmetricSignature- deriving (Eq, Show)--instance Exception.Exception InvalidSignature where- displayException invalidSignature =- "invalid signature: " <> case invalidSignature of- InvalidAsymmetricSignature invalidAsymmetricSignature ->- Exception.displayException invalidAsymmetricSignature- InvalidSymmetricSignature invalidSymmetricSignature ->- Exception.displayException invalidSymmetricSignature
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSigner.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSigner where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSigner- = MkInvalidSigner ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidSigner where- displayException = mappend "invalid signer: " . show . unwrap--unwrap :: InvalidSigner -> ByteString.ByteString-unwrap (MkInvalidSigner byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidSymmetricSignature.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidSymmetricSignature where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidSymmetricSignature- = MkInvalidSymmetricSignature ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidSymmetricSignature where- displayException = mappend "invalid symmetric signature: " . show . unwrap--unwrap :: InvalidSymmetricSignature -> ByteString.ByteString-unwrap (MkInvalidSymmetricSignature byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidTimestamp.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidTimestamp where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidTimestamp- = MkInvalidTimestamp ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidTimestamp where- displayException = mappend "invalid timestamp: " . show . unwrap--unwrap :: InvalidTimestamp -> ByteString.ByteString-unwrap (MkInvalidTimestamp byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/InvalidVerifier.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.InvalidVerifier where--import qualified Control.Monad.Catch as Exception-import qualified Data.ByteString as ByteString--newtype InvalidVerifier- = MkInvalidVerifier ByteString.ByteString- deriving (Eq, Show)--instance Exception.Exception InvalidVerifier where- displayException = mappend "invalid verifier: " . show . unwrap--unwrap :: InvalidVerifier -> ByteString.ByteString-unwrap (MkInvalidVerifier byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Exception/SignetException.hs
@@ -1,18 +0,0 @@-module Signet.Unstable.Exception.SignetException where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Exception.VerificationException as VerificationException--data SignetException- = ToleranceException ToleranceException.ToleranceException- | VerificationException VerificationException.VerificationException- deriving (Eq, Show)--instance Exception.Exception SignetException where- displayException signetException =- "failed to verify webhook: " <> case signetException of- ToleranceException toleranceException ->- Exception.displayException toleranceException- VerificationException verificationException ->- Exception.displayException verificationException
− source/libraries/unstable/Signet/Unstable/Exception/ToleranceException.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.ToleranceException where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Type.Timestamp as Timestamp--newtype ToleranceException- = MkToleranceException Timestamp.Timestamp- deriving (Eq, Show)--instance Exception.Exception ToleranceException where- displayException = mappend "timestamp out of tolerance: " . show . unwrap--unwrap :: ToleranceException -> Timestamp.Timestamp-unwrap (MkToleranceException timestamp) = timestamp
− source/libraries/unstable/Signet/Unstable/Exception/VerificationException.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Exception.VerificationException where--import qualified Control.Monad.Catch as Exception-import qualified Signet.Unstable.Type.Id as Id--newtype VerificationException- = MkVerificationException Id.Id- deriving (Eq, Show)--instance Exception.Exception VerificationException where- displayException = mappend "verification failed: " . show . unwrap--unwrap :: VerificationException -> Id.Id-unwrap (MkVerificationException id_) = id_
− source/libraries/unstable/Signet/Unstable/Extra/Either.hs
@@ -1,9 +0,0 @@-module Signet.Unstable.Extra.Either where--import qualified Control.Monad.Catch as Exception--hush :: Either x a -> Maybe a-hush = either (const Nothing) Just--throw :: (Exception.Exception e, Exception.MonadThrow m) => Either e a -> m a-throw = either Exception.throwM pure
− source/libraries/unstable/Signet/Unstable/Extra/Http.hs
@@ -1,14 +0,0 @@-module Signet.Unstable.Extra.Http where--import qualified Data.ByteString.Char8 as Ascii-import qualified Data.CaseInsensitive as CI-import qualified Network.HTTP.Types as Http--hWebhookId :: Http.HeaderName-hWebhookId = CI.mk $ Ascii.pack "webhook-id"--hWebhookSignature :: Http.HeaderName-hWebhookSignature = CI.mk $ Ascii.pack "webhook-signature"--hWebhookTimestamp :: Http.HeaderName-hWebhookTimestamp = CI.mk $ Ascii.pack "webhook-timestamp"
− source/libraries/unstable/Signet/Unstable/Extra/Maybe.hs
@@ -1,4 +0,0 @@-module Signet.Unstable.Extra.Maybe where--note :: e -> Maybe a -> Either e a-note = flip maybe Right . Left
− source/libraries/unstable/Signet/Unstable/Type/AsymmetricSignature.hs
@@ -1,28 +0,0 @@-module Signet.Unstable.Type.AsymmetricSignature where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype AsymmetricSignature- = MkAsymmetricSignature Ed25519.Signature- deriving (Eq, Show)--unwrap :: AsymmetricSignature -> Ed25519.Signature-unwrap (MkAsymmetricSignature signature) = signature--parse ::- ByteString.ByteString ->- Either InvalidAsymmetricSignature.InvalidAsymmetricSignature AsymmetricSignature-parse encoded = Maybe.note (InvalidAsymmetricSignature.MkInvalidAsymmetricSignature encoded) $ do- byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded- fmap MkAsymmetricSignature- . Error.maybeCryptoError- $ Ed25519.signature (byteString :: ByteString.ByteString)--render :: AsymmetricSignature -> ByteString.ByteString-render = Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Id.hs
@@ -1,26 +0,0 @@-module Signet.Unstable.Type.Id where--import qualified Control.Monad as Monad-import qualified Data.ByteString as ByteString-import qualified Data.Word as Word-import qualified Signet.Unstable.Exception.InvalidId as InvalidId--newtype Id- = MkId ByteString.ByteString- deriving (Eq, Show)--unwrap :: Id -> ByteString.ByteString-unwrap (MkId byteString) = byteString--separator :: Word.Word8-separator = 0x2e--parse :: ByteString.ByteString -> Either InvalidId.InvalidId Id-parse byteString = do- Monad.when (ByteString.any (== separator) byteString)- . Left- $ InvalidId.MkInvalidId byteString- Right $ MkId byteString--render :: Id -> ByteString.ByteString-render = unwrap
− source/libraries/unstable/Signet/Unstable/Type/Message.hs
@@ -1,36 +0,0 @@-module Signet.Unstable.Type.Message where--import qualified Data.Bifunctor as Bifunctor-import qualified Data.ByteString as ByteString-import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage-import qualified Signet.Unstable.Type.Id as Id-import qualified Signet.Unstable.Type.Payload as Payload-import qualified Signet.Unstable.Type.Timestamp as Timestamp--data Message = MkMessage- { id_ :: Id.Id,- timestamp :: Timestamp.Timestamp,- payload :: Payload.Payload- }- deriving (Eq, Show)--parse :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message-parse x = do- let (rawId, y) = ByteString.break (== Id.separator) x- theId <- Bifunctor.first InvalidMessage.InvalidId $ Id.parse rawId- let (rawTimestamp, z) =- ByteString.break (== Id.separator) $- ByteString.drop 1 y- theTimestamp <-- Bifunctor.first InvalidMessage.InvalidTimestamp $- Timestamp.parse rawTimestamp- let thePayload = Payload.MkPayload $ ByteString.drop 1 z- pure MkMessage {id_ = theId, timestamp = theTimestamp, payload = thePayload}--render :: Message -> ByteString.ByteString-render message =- Id.render (id_ message)- <> ByteString.singleton Id.separator- <> Timestamp.render (timestamp message)- <> ByteString.singleton Id.separator- <> Payload.unwrap (payload message)
− source/libraries/unstable/Signet/Unstable/Type/Payload.hs
@@ -1,10 +0,0 @@-module Signet.Unstable.Type.Payload where--import qualified Data.ByteString as ByteString--newtype Payload- = MkPayload ByteString.ByteString- deriving (Eq, Show)--unwrap :: Payload -> ByteString.ByteString-unwrap (MkPayload byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Type/PublicKey.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Type.PublicKey where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype PublicKey- = MkPublicKey Ed25519.PublicKey- deriving (Eq, Show)--unwrap :: PublicKey -> Ed25519.PublicKey-unwrap (MkPublicKey publicKey) = publicKey--prefix :: ByteString.ByteString-prefix = Ascii.pack "whpk_"--parse :: ByteString.ByteString -> Either InvalidPublicKey.InvalidPublicKey PublicKey-parse prefixed = Maybe.note (InvalidPublicKey.MkInvalidPublicKey prefixed) $ do- encoded <- ByteString.stripPrefix prefix prefixed- byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded- fmap MkPublicKey- . Error.maybeCryptoError- $ Ed25519.publicKey (byteString :: ByteString.ByteString)--render :: PublicKey -> ByteString.ByteString-render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Secret.hs
@@ -1,27 +0,0 @@-module Signet.Unstable.Type.Secret where--import qualified Data.ByteArray as ByteArray-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype Secret- = MkSecret ByteArray.ScrubbedBytes- deriving (Eq, Show)--unwrap :: Secret -> ByteArray.ScrubbedBytes-unwrap (MkSecret scrubbedBytes) = scrubbedBytes--prefix :: ByteString.ByteString-prefix = Ascii.pack "whsec_"--parse :: ByteString.ByteString -> Either InvalidSecret.InvalidSecret Secret-parse prefixed = Maybe.note (InvalidSecret.MkInvalidSecret prefixed) $ do- encoded <- ByteString.stripPrefix prefix prefixed- fmap MkSecret . Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded--render :: Secret -> ByteString.ByteString-render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/SecretKey.hs
@@ -1,31 +0,0 @@-module Signet.Unstable.Type.SecretKey where--import qualified Crypto.Error as Error-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype SecretKey- = MkSecretKey Ed25519.SecretKey- deriving (Eq, Show)--unwrap :: SecretKey -> Ed25519.SecretKey-unwrap (MkSecretKey secretKey) = secretKey--prefix :: ByteString.ByteString-prefix = Ascii.pack "whsk_"--parse :: ByteString.ByteString -> Either InvalidSecretKey.InvalidSecretKey SecretKey-parse prefixed = Maybe.note (InvalidSecretKey.MkInvalidSecretKey prefixed) $ do- encoded <- ByteString.stripPrefix prefix prefixed- byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded- fmap MkSecretKey- . Error.maybeCryptoError- $ Ed25519.secretKey (byteString :: ByteString.ByteString)--render :: SecretKey -> ByteString.ByteString-render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Signature.hs
@@ -1,49 +0,0 @@-module Signet.Unstable.Type.Signature where--import qualified Data.Bifunctor as Bifunctor-import qualified Data.ByteString as ByteString-import qualified Data.ByteString.Char8 as Ascii-import qualified Data.Word as Word-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature--data Signature- = Asymmetric AsymmetricSignature.AsymmetricSignature- | Symmetric SymmetricSignature.SymmetricSignature- deriving (Eq, Show)--separator :: Word.Word8-separator = 0x2c--asymmetricPrefix :: ByteString.ByteString-asymmetricPrefix = Ascii.pack "v1a"--symmetricPrefix :: ByteString.ByteString-symmetricPrefix = Ascii.pack "v1"--parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature (Either UnknownSignature.UnknownSignature Signature)-parse prefixed = do- let (prefix, rest) = ByteString.break (== separator) prefixed- case ByteString.drop 1 rest of- byteString- | prefix == asymmetricPrefix ->- Bifunctor.bimap InvalidSignature.InvalidAsymmetricSignature (Right . Asymmetric) $- AsymmetricSignature.parse byteString- | prefix == symmetricPrefix ->- Bifunctor.bimap InvalidSignature.InvalidSymmetricSignature (Right . Symmetric) $- SymmetricSignature.parse byteString- _ -> Right . Left $ UnknownSignature.MkUnknownSignature prefixed--render :: Signature -> ByteString.ByteString-render signature =- case signature of- Asymmetric asymmetricSignature ->- asymmetricPrefix- <> ByteString.singleton separator- <> AsymmetricSignature.render asymmetricSignature- Symmetric symmetricSignature ->- symmetricPrefix- <> ByteString.singleton separator- <> SymmetricSignature.render symmetricSignature
− source/libraries/unstable/Signet/Unstable/Type/Signatures.hs
@@ -1,30 +0,0 @@-module Signet.Unstable.Type.Signatures where--import qualified Data.ByteString as ByteString-import qualified Data.Either as Either-import qualified Data.Word as Word-import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature-import qualified Signet.Unstable.Type.Signature as Signature-import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature--newtype Signatures- = MkSignatures [Signature.Signature]- deriving (Eq, Show)--unwrap :: Signatures -> [Signature.Signature]-unwrap (MkSignatures signatures) = signatures--separator :: Word.Word8-separator = 0x20--parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures)-parse =- fmap (fmap MkSignatures . Either.partitionEithers)- . traverse Signature.parse- . ByteString.split separator--render :: Signatures -> ByteString.ByteString-render =- ByteString.intercalate (ByteString.singleton separator)- . fmap Signature.render- . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Signer.hs
@@ -1,49 +0,0 @@-module Signet.Unstable.Type.Signer where--import qualified Crypto.MAC.HMAC as Hmac-import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-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.SymmetricSignature as SymmetricSignature--data Signer- = Asymmetric SecretKey.SecretKey- | Symmetric Secret.Secret- deriving (Eq, Show)--parse :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer-parse byteString = case SecretKey.parse byteString of- Right secretKey -> Right $ Asymmetric secretKey- Left _ -> case Secret.parse byteString of- Right secret -> Right $ Symmetric secret- Left _ -> Left $ InvalidSigner.MkInvalidSigner byteString--render :: Signer -> ByteString.ByteString-render signer = case signer of- Asymmetric secretKey -> SecretKey.render secretKey- Symmetric secret -> Secret.render secret--sign :: Signer -> Message.Message -> Signature.Signature-sign signer = case signer of- Asymmetric secretKey -> Signature.Asymmetric . asymmetric secretKey- Symmetric secret -> Signature.Symmetric . symmetric secret--asymmetric :: SecretKey.SecretKey -> Message.Message -> AsymmetricSignature.AsymmetricSignature-asymmetric secretKey =- let sk = SecretKey.unwrap secretKey- pk = Ed25519.toPublic sk- in AsymmetricSignature.MkAsymmetricSignature- . Ed25519.sign sk pk- . Message.render--symmetric :: Secret.Secret -> Message.Message -> SymmetricSignature.SymmetricSignature-symmetric secret =- SymmetricSignature.MkSymmetricSignature- . Hmac.hmacGetDigest- . Hmac.hmac (Secret.unwrap secret)- . Message.render
− source/libraries/unstable/Signet/Unstable/Type/SymmetricSignature.hs
@@ -1,28 +0,0 @@-module Signet.Unstable.Type.SymmetricSignature where--import qualified Crypto.Hash as Hash-import qualified Data.ByteArray as ByteArray-import qualified Data.ByteArray.Encoding as Encoding-import qualified Data.ByteString as ByteString-import qualified Data.Function as Function-import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype SymmetricSignature- = MkSymmetricSignature (Hash.Digest Hash.SHA256)- deriving (Show)--instance Eq SymmetricSignature where- (==) = Function.on ByteArray.constEq unwrap--unwrap :: SymmetricSignature -> Hash.Digest Hash.SHA256-unwrap (MkSymmetricSignature digest) = digest--parse :: ByteString.ByteString -> Either InvalidSymmetricSignature.InvalidSymmetricSignature SymmetricSignature-parse encoded = Maybe.note (InvalidSymmetricSignature.MkInvalidSymmetricSignature encoded) $ do- byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded- MkSymmetricSignature <$> Hash.digestFromByteString (byteString :: ByteString.ByteString)--render :: SymmetricSignature -> ByteString.ByteString-render = Encoding.convertToBase Encoding.Base64 . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Timestamp.hs
@@ -1,33 +0,0 @@-module Signet.Unstable.Type.Timestamp where--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.InvalidTimestamp as InvalidTimestamp-import qualified Signet.Unstable.Extra.Either as Either-import qualified Signet.Unstable.Extra.Maybe as Maybe--newtype Timestamp- = MkTimestamp Time.UTCTime- deriving (Eq, Show)--unwrap :: Timestamp -> Time.UTCTime-unwrap (MkTimestamp utcTime) = utcTime--format :: String-format = "%s"--parse :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp-parse byteString = Maybe.note (InvalidTimestamp.MkInvalidTimestamp byteString) $ do- text <- Either.hush $ Text.decodeUtf8' byteString- fmap MkTimestamp- . Time.parseTimeM False Time.defaultTimeLocale format- $ Text.unpack text--render :: Timestamp -> ByteString.ByteString-render =- Text.encodeUtf8- . Text.pack- . Time.formatTime Time.defaultTimeLocale format- . unwrap
− source/libraries/unstable/Signet/Unstable/Type/Tolerance.hs
@@ -1,29 +0,0 @@-module Signet.Unstable.Type.Tolerance where--import qualified Control.Monad as Monad-import qualified Data.Time as Time-import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException-import qualified Signet.Unstable.Type.Timestamp as Timestamp--newtype Tolerance- = MkTolerance Time.NominalDiffTime- deriving (Eq, Show)--unwrap :: Tolerance -> Time.NominalDiffTime-unwrap (MkTolerance nominalDiffTime) = nominalDiffTime--typical :: Tolerance-typical = MkTolerance 300--check ::- Tolerance ->- Time.UTCTime ->- Timestamp.Timestamp ->- Either ToleranceException.ToleranceException ()-check tolerance utcTime timestamp = do- let diff = Time.diffUTCTime utcTime $ Timestamp.unwrap timestamp- let hi = unwrap tolerance- let lo = negate hi- Monad.when (lo > diff || diff > hi)- . Left- $ ToleranceException.MkToleranceException timestamp
− source/libraries/unstable/Signet/Unstable/Type/UnknownSignature.hs
@@ -1,10 +0,0 @@-module Signet.Unstable.Type.UnknownSignature where--import qualified Data.ByteString as ByteString--newtype UnknownSignature- = MkUnknownSignature ByteString.ByteString- deriving (Eq, Show)--unwrap :: UnknownSignature -> ByteString.ByteString-unwrap (MkUnknownSignature byteString) = byteString
− source/libraries/unstable/Signet/Unstable/Type/Verifier.hs
@@ -1,75 +0,0 @@-module Signet.Unstable.Type.Verifier where--import qualified Crypto.PubKey.Ed25519 as Ed25519-import qualified Data.ByteString as ByteString-import qualified Data.List as List-import qualified Data.Maybe as Maybe-import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier-import qualified Signet.Unstable.Exception.VerificationException as VerificationException-import qualified Signet.Unstable.Extra.Maybe as Maybe-import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature-import qualified Signet.Unstable.Type.Message as Message-import qualified Signet.Unstable.Type.PublicKey as PublicKey-import qualified Signet.Unstable.Type.Secret as Secret-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--data Verifier- = Asymmetric PublicKey.PublicKey- | Symmetric Secret.Secret- deriving (Eq, Show)--parse :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier-parse byteString = case PublicKey.parse byteString of- Right publicKey -> Right $ Asymmetric publicKey- Left _ -> case Secret.parse byteString of- Right secret -> Right $ Symmetric secret- Left _ -> Left $ InvalidVerifier.MkInvalidVerifier byteString--render :: Verifier -> ByteString.ByteString-render verifier = case verifier of- Asymmetric publicKey -> PublicKey.render publicKey- Symmetric secret -> Secret.render secret--verify ::- Verifier ->- Message.Message ->- Signatures.Signatures ->- Either VerificationException.VerificationException Signature.Signature-verify verifier message =- case verifier of- Asymmetric publicKey -> fmap Signature.Asymmetric . asymmetric publicKey message- Symmetric secret -> fmap Signature.Symmetric . symmetric secret message--asymmetric ::- PublicKey.PublicKey ->- Message.Message ->- Signatures.Signatures ->- Either VerificationException.VerificationException AsymmetricSignature.AsymmetricSignature-asymmetric publicKey message =- let toAsymmetric signature = case signature of- Signature.Asymmetric asymmetricSignature -> Just asymmetricSignature- Signature.Symmetric _ -> Nothing- pk = PublicKey.unwrap publicKey- bs = Message.render message- in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)- . List.find (Ed25519.verify pk bs . AsymmetricSignature.unwrap)- . Maybe.mapMaybe toAsymmetric- . Signatures.unwrap--symmetric ::- Secret.Secret ->- Message.Message ->- Signatures.Signatures ->- Either VerificationException.VerificationException SymmetricSignature.SymmetricSignature-symmetric secret message =- let toSymmetric signature = case signature of- Signature.Asymmetric _ -> Nothing- Signature.Symmetric symmetricSignature -> Just symmetricSignature- expected = Signer.symmetric secret message- in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)- . List.find (expected ==)- . Maybe.mapMaybe toSymmetric- . Signatures.unwrap
+ source/library/Signet.hs view
@@ -0,0 +1,88 @@+module Signet+ ( -- * Verification+ Signet.Unstable.verifyWebhookText,+ Signet.Unstable.verifyWebhookByteString,+ Signet.Unstable.verifyWebhook,+ Signet.Unstable.verifyWebhookWith,++ -- * Signing+ Signet.Unstable.signWebhook,++ -- * Headers+ Signet.Unstable.Extra.Http.hWebhookId,+ Signet.Unstable.Extra.Http.hWebhookTimestamp,+ Signet.Unstable.Extra.Http.hWebhookSignature,++ -- * Types+ Signet.Unstable.Type.AsymmetricSignature.AsymmetricSignature (..),+ Signet.Unstable.Type.Id.Id (..),+ Signet.Unstable.parseId,+ Signet.Unstable.Type.Message.Message (..),+ Signet.Unstable.parseMessage,+ Signet.Unstable.Type.Payload.Payload (..),+ Signet.Unstable.Type.PublicKey.PublicKey (..),+ Signet.Unstable.Type.Secret.Secret (..),+ Signet.Unstable.Type.SecretKey.SecretKey (..),+ Signet.Unstable.Type.Signature.Signature (Signet.Unstable.AsymmetricSignature, Signet.Unstable.SymmetricSignature),+ Signet.Unstable.Type.Signatures.Signatures (..),+ Signet.Unstable.parseSignatures,+ Signet.Unstable.Type.Signer.Signer (Signet.Unstable.AsymmetricSigner, Signet.Unstable.SymmetricSigner),+ Signet.Unstable.parseSigner,+ Signet.Unstable.Type.SymmetricSignature.SymmetricSignature (..),+ Signet.Unstable.Type.Timestamp.Timestamp (..),+ Signet.Unstable.parseTimestamp,+ Signet.Unstable.Type.Tolerance.Tolerance (..),+ Signet.Unstable.typicalTolerance,+ Signet.Unstable.Type.UnknownSignature.UnknownSignature (..),+ Signet.Unstable.Type.Verifier.Verifier (Signet.Unstable.AsymmetricVerifier, Signet.Unstable.SymmetricVerifier),+ Signet.Unstable.parseVerifier,++ -- * Exceptions+ Signet.Unstable.Exception.InvalidAsymmetricSignature.InvalidAsymmetricSignature (..),+ Signet.Unstable.Exception.InvalidId.InvalidId (..),+ Signet.Unstable.Exception.InvalidMessage.InvalidMessage (..),+ Signet.Unstable.Exception.InvalidPublicKey.InvalidPublicKey (..),+ Signet.Unstable.Exception.InvalidSecret.InvalidSecret (..),+ Signet.Unstable.Exception.InvalidSecretKey.InvalidSecretKey (..),+ Signet.Unstable.Exception.InvalidSignature.InvalidSignature (..),+ Signet.Unstable.Exception.InvalidSigner.InvalidSigner (..),+ Signet.Unstable.Exception.InvalidSymmetricSignature.InvalidSymmetricSignature (..),+ Signet.Unstable.Exception.InvalidTimestamp.InvalidTimestamp (..),+ Signet.Unstable.Exception.InvalidVerifier.InvalidVerifier (..),+ Signet.Unstable.Exception.SignetException.SignetException (..),+ Signet.Unstable.Exception.ToleranceException.ToleranceException (..),+ Signet.Unstable.Exception.VerificationException.VerificationException (..),+ )+where++import qualified Signet.Unstable+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidId+import qualified Signet.Unstable.Exception.InvalidMessage+import qualified Signet.Unstable.Exception.InvalidPublicKey+import qualified Signet.Unstable.Exception.InvalidSecret+import qualified Signet.Unstable.Exception.InvalidSecretKey+import qualified Signet.Unstable.Exception.InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSigner+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature+import qualified Signet.Unstable.Exception.InvalidTimestamp+import qualified Signet.Unstable.Exception.InvalidVerifier+import qualified Signet.Unstable.Exception.SignetException+import qualified Signet.Unstable.Exception.ToleranceException+import qualified Signet.Unstable.Exception.VerificationException+import qualified Signet.Unstable.Extra.Http+import qualified Signet.Unstable.Type.AsymmetricSignature+import qualified Signet.Unstable.Type.Id+import qualified Signet.Unstable.Type.Message+import qualified Signet.Unstable.Type.Payload+import qualified Signet.Unstable.Type.PublicKey+import qualified Signet.Unstable.Type.Secret+import qualified Signet.Unstable.Type.SecretKey+import qualified Signet.Unstable.Type.Signature+import qualified Signet.Unstable.Type.Signatures+import qualified Signet.Unstable.Type.Signer+import qualified Signet.Unstable.Type.SymmetricSignature+import qualified Signet.Unstable.Type.Timestamp+import qualified Signet.Unstable.Type.Tolerance+import qualified Signet.Unstable.Type.UnknownSignature+import qualified Signet.Unstable.Type.Verifier
+ source/library/Signet/Unstable.hs view
@@ -0,0 +1,196 @@+{-# 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.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.UnknownSignature as UnknownSignature+import qualified Signet.Unstable.Type.Verifier as Verifier++-- | Verifies a webhook with 'Text.Text' values. This is a wrapper around+-- 'verifyWebhookByteString' that assumes all values are encoded as UTF-8.+verifyWebhookText ::+ (MonadIO.MonadIO m, Exception.MonadThrow m) =>+ -- | A 'Verifier.Verifier' for the webhook. Typically this will be+ -- @"whsec_..."@ or @"whpk_..."@.+ Text.Text ->+ -- | The webhook's unique 'Id.Id'. Typically this will come from the+ -- 'Signet.Unstable.Extra.Http.hWebhookId' header and look like @"msg_..."@.+ Text.Text ->+ -- | The webhook's 'Timestamp.Timestamp'. This is an integer number of+ -- seconds since the Unix epoch. Typically this will come from the+ -- 'Signet.Unstable.Extra.Http.hWebhookTimestamp' header. For example+ -- @"981173106"@ for @2001-02-03T04:05:06Z@.+ Text.Text ->+ -- | The webhook's raw 'Payload.Payload'. Typically this will be a JSON+ -- object like @{"event_type":"ping",...}@.+ Text.Text ->+ -- | The webhook's 'Signatures.Signatures'. Typically this will come from the+ -- 'Signet.Unstable.Extra.Http.hWebhookSignature' header and look like+ -- @"v1_..."@ or @"v1a_..."@.+ Text.Text ->+ m Signature.Signature+verifyWebhookText v i t p s =+ verifyWebhookByteString+ (Text.encodeUtf8 v)+ (Text.encodeUtf8 i)+ (Text.encodeUtf8 t)+ (Text.encodeUtf8 p)+ (Text.encodeUtf8 s)++-- | Verifies a webhook with 'ByteString.ByteString' values. This is a+-- wrapper around 'verifyWebhook'. See 'verifyWebhookText' for a description of+-- the arguments.+verifyWebhookByteString ::+ (MonadIO.MonadIO m, Exception.MonadThrow m) =>+ -- | 'Verifier.Verifier'+ ByteString.ByteString ->+ -- | 'Id.Id'+ ByteString.ByteString ->+ -- | 'Timestamp.Timestamp'+ ByteString.ByteString ->+ -- | 'Payload.Payload'+ ByteString.ByteString ->+ -- | 'Signatures.Signatures'+ ByteString.ByteString ->+ m Signature.Signature+verifyWebhookByteString v i t p s = do+ verifier <- Either.throw $ parseVerifier v+ id_ <- Either.throw $ parseId i+ timestamp <- Either.throw $ parseTimestamp t+ let payload = Payload.MkPayload p+ let message =+ Message.MkMessage+ { Message.id_ = id_,+ Message.timestamp = timestamp,+ Message.payload = payload+ }+ (_, signatures) <- Either.throw $ parseSignatures s+ verifyWebhook verifier message signatures++-- | Verifies a webhook. This is a wrapper around 'verifyWebhookWith' that uses+-- 'typicalTolerance' and the current time.+--+-- Throws an exception if the webhook is invalid.+verifyWebhook ::+ (MonadIO.MonadIO m, Exception.MonadThrow m) =>+ Verifier.Verifier ->+ Message.Message ->+ Signatures.Signatures ->+ m Signature.Signature+verifyWebhook verifier message signatures = do+ now <- MonadIO.liftIO Time.getCurrentTime+ Either.throw $ verifyWebhookWith typicalTolerance now verifier message signatures++-- | Verifies a webhook. This is the lowest-level function that gives you the+-- most control. If you're looking for something that's easier to use and+-- assumes some reasonable defaults, consider 'verifyWebhook'.+verifyWebhookWith ::+ -- | Often 'typicalTolerance'.+ Tolerance.Tolerance ->+ -- | Usually 'Time.getCurrentTime'.+ Time.UTCTime ->+ -- | See 'parseVerifier'.+ Verifier.Verifier ->+ -- | See 'parseMessage'. Or 'Message.MkMessage' along with 'parseId',+ -- 'parseTimestamp', and 'Payload.MkPayload'.+ Message.Message ->+ -- | See 'parseSignatures'.+ Signatures.Signatures ->+ Either SignetException.SignetException Signature.Signature+verifyWebhookWith tolerance now verifier message signatures = do+ Bifunctor.first SignetException.ToleranceException+ . Tolerance.check tolerance now+ $ Message.timestamp message+ Bifunctor.first SignetException.VerificationException $+ Verifier.verify verifier message signatures++-- | Alias for 'Tolerance.typical'.+typicalTolerance :: Tolerance.Tolerance+typicalTolerance = Tolerance.typical++-- | Alias for 'Verifier.parse'.+parseVerifier :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier.Verifier+parseVerifier = Verifier.parse++-- | Alias for 'Id.parse'.+parseId :: ByteString.ByteString -> Either InvalidId.InvalidId Id.Id+parseId = Id.parse++-- | Alias for 'Timestamp.parse'.+parseTimestamp :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp.Timestamp+parseTimestamp = Timestamp.parse++-- | Alias for 'Message.parse'.+parseMessage :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message.Message+parseMessage = Message.parse++-- | Alias for 'Signatures.parse'.+parseSignatures ::+ ByteString.ByteString ->+ Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures.Signatures)+parseSignatures = Signatures.parse++-- | Alias for 'Verifier.Asymmetric'.+pattern AsymmetricVerifier :: PublicKey.PublicKey -> Verifier.Verifier+pattern AsymmetricVerifier publicKey = Verifier.Asymmetric publicKey++-- | Alias for 'Verifier.Symmetric'.+pattern SymmetricVerifier :: Secret.Secret -> Verifier.Verifier+pattern SymmetricVerifier secret = Verifier.Symmetric secret++{-# COMPLETE AsymmetricVerifier, SymmetricVerifier #-}++-- | Alias for 'Signer.sign'.+signWebhook :: Signer.Signer -> Message.Message -> Signature.Signature+signWebhook = Signer.sign++-- | Alias for 'Signer.parse'.+parseSigner :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer.Signer+parseSigner = Signer.parse++-- | Alias for 'Signer.Asymmetric'.+pattern AsymmetricSigner :: SecretKey.SecretKey -> Signer.Signer+pattern AsymmetricSigner secretKey = Signer.Asymmetric secretKey++-- | Alias for 'Signer.Symmetric'.+pattern SymmetricSigner :: Secret.Secret -> Signer.Signer+pattern SymmetricSigner secret = Signer.Symmetric secret++{-# COMPLETE AsymmetricSigner, SymmetricSigner #-}++-- | Alias for 'Signature.Asymmetric'.+pattern AsymmetricSignature :: AsymmetricSignature.AsymmetricSignature -> Signature.Signature+pattern AsymmetricSignature asymmetricSignature = Signature.Asymmetric asymmetricSignature++-- | Alias for 'Signature.Symmetric'.+pattern SymmetricSignature :: SymmetricSignature.SymmetricSignature -> Signature.Signature+pattern SymmetricSignature symmetricSignature = Signature.Symmetric symmetricSignature++{-# COMPLETE AsymmetricSignature, SymmetricSignature #-}
+ source/library/Signet/Unstable/Exception/InvalidAsymmetricSignature.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidAsymmetricSignature where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidAsymmetricSignature+ = MkInvalidAsymmetricSignature ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidAsymmetricSignature where+ displayException = mappend "invalid asymmetric signature: " . show . unwrap++unwrap :: InvalidAsymmetricSignature -> ByteString.ByteString+unwrap (MkInvalidAsymmetricSignature byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidAsymmetricSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidAsymmetricSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidAsymmetricSignature" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidId.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidId where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidId+ = MkInvalidId ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidId where+ displayException = mappend "invalid ID: " . show . unwrap++unwrap :: InvalidId -> ByteString.ByteString+unwrap (MkInvalidId byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidIdTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidIdTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidId" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidMessage.hs view
@@ -0,0 +1,18 @@+module Signet.Unstable.Exception.InvalidMessage where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Exception.InvalidId as InvalidId+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp++data InvalidMessage+ = InvalidId InvalidId.InvalidId+ | InvalidTimestamp InvalidTimestamp.InvalidTimestamp+ deriving (Eq, Show)++instance Exception.Exception InvalidMessage where+ displayException invalidMessage =+ "invalid message: " <> case invalidMessage of+ InvalidId invalidId ->+ Exception.displayException invalidId+ InvalidTimestamp invalidTimestamp ->+ Exception.displayException invalidTimestamp
+ source/library/Signet/Unstable/Exception/InvalidMessageTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidMessageTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidMessage" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidPublicKey.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidPublicKey where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidPublicKey+ = MkInvalidPublicKey ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidPublicKey where+ displayException = mappend "invalid public key: " . show . unwrap++unwrap :: InvalidPublicKey -> ByteString.ByteString+unwrap (MkInvalidPublicKey byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidPublicKeyTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidPublicKeyTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidPublicKey" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidSecret.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSecret where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSecret+ = MkInvalidSecret ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidSecret where+ displayException = mappend "invalid secret: " . show . unwrap++unwrap :: InvalidSecret -> ByteString.ByteString+unwrap (MkInvalidSecret byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSecretKey.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSecretKey where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSecretKey+ = MkInvalidSecretKey ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidSecretKey where+ displayException = mappend "invalid secret key: " . show . unwrap++unwrap :: InvalidSecretKey -> ByteString.ByteString+unwrap (MkInvalidSecretKey byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSecretKeyTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSecretKeyTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSecretKey" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidSecretTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSecretTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSecret" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidSignature.hs view
@@ -0,0 +1,18 @@+module Signet.Unstable.Exception.InvalidSignature where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature++data InvalidSignature+ = InvalidAsymmetricSignature InvalidAsymmetricSignature.InvalidAsymmetricSignature+ | InvalidSymmetricSignature InvalidSymmetricSignature.InvalidSymmetricSignature+ deriving (Eq, Show)++instance Exception.Exception InvalidSignature where+ displayException invalidSignature =+ "invalid signature: " <> case invalidSignature of+ InvalidAsymmetricSignature invalidAsymmetricSignature ->+ Exception.displayException invalidAsymmetricSignature+ InvalidSymmetricSignature invalidSymmetricSignature ->+ Exception.displayException invalidSymmetricSignature
+ source/library/Signet/Unstable/Exception/InvalidSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSignature" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidSigner.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSigner where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSigner+ = MkInvalidSigner ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidSigner where+ displayException = mappend "invalid signer: " . show . unwrap++unwrap :: InvalidSigner -> ByteString.ByteString+unwrap (MkInvalidSigner byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSignerTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSignerTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSigner" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidSymmetricSignature.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidSymmetricSignature where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidSymmetricSignature+ = MkInvalidSymmetricSignature ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidSymmetricSignature where+ displayException = mappend "invalid symmetric signature: " . show . unwrap++unwrap :: InvalidSymmetricSignature -> ByteString.ByteString+unwrap (MkInvalidSymmetricSignature byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidSymmetricSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidSymmetricSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidSymmetricSignature" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidTimestamp.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidTimestamp where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidTimestamp+ = MkInvalidTimestamp ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidTimestamp where+ displayException = mappend "invalid timestamp: " . show . unwrap++unwrap :: InvalidTimestamp -> ByteString.ByteString+unwrap (MkInvalidTimestamp byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidTimestampTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidTimestampTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidTimestamp" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/InvalidVerifier.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.InvalidVerifier where++import qualified Control.Monad.Catch as Exception+import qualified Data.ByteString as ByteString++newtype InvalidVerifier+ = MkInvalidVerifier ByteString.ByteString+ deriving (Eq, Show)++instance Exception.Exception InvalidVerifier where+ displayException = mappend "invalid verifier: " . show . unwrap++unwrap :: InvalidVerifier -> ByteString.ByteString+unwrap (MkInvalidVerifier byteString) = byteString
+ source/library/Signet/Unstable/Exception/InvalidVerifierTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.InvalidVerifierTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.InvalidVerifier" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/SignetException.hs view
@@ -0,0 +1,18 @@+module Signet.Unstable.Exception.SignetException where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Exception.VerificationException as VerificationException++data SignetException+ = ToleranceException ToleranceException.ToleranceException+ | VerificationException VerificationException.VerificationException+ deriving (Eq, Show)++instance Exception.Exception SignetException where+ displayException signetException =+ "failed to verify webhook: " <> case signetException of+ ToleranceException toleranceException ->+ Exception.displayException toleranceException+ VerificationException verificationException ->+ Exception.displayException verificationException
+ source/library/Signet/Unstable/Exception/SignetExceptionTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.SignetExceptionTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.SignetException" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/ToleranceException.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.ToleranceException where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Type.Timestamp as Timestamp++newtype ToleranceException+ = MkToleranceException Timestamp.Timestamp+ deriving (Eq, Show)++instance Exception.Exception ToleranceException where+ displayException = mappend "timestamp out of tolerance: " . show . unwrap++unwrap :: ToleranceException -> Timestamp.Timestamp+unwrap (MkToleranceException timestamp) = timestamp
+ source/library/Signet/Unstable/Exception/ToleranceExceptionTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.ToleranceExceptionTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.ToleranceException" $ do+ pure ()
+ source/library/Signet/Unstable/Exception/VerificationException.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Exception.VerificationException where++import qualified Control.Monad.Catch as Exception+import qualified Signet.Unstable.Type.Id as Id++newtype VerificationException+ = MkVerificationException Id.Id+ deriving (Eq, Show)++instance Exception.Exception VerificationException where+ displayException = mappend "verification failed: " . show . unwrap++unwrap :: VerificationException -> Id.Id+unwrap (MkVerificationException id_) = id_
+ source/library/Signet/Unstable/Exception/VerificationExceptionTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Exception.VerificationExceptionTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Exception.VerificationException" $ do+ pure ()
+ source/library/Signet/Unstable/Extra/Either.hs view
@@ -0,0 +1,9 @@+module Signet.Unstable.Extra.Either where++import qualified Control.Monad.Catch as Exception++hush :: Either x a -> Maybe a+hush = either (const Nothing) Just++throw :: (Exception.Exception e, Exception.MonadThrow m) => Either e a -> m a+throw = either Exception.throwM pure
+ source/library/Signet/Unstable/Extra/EitherTest.hs view
@@ -0,0 +1,30 @@+module Signet.Unstable.Extra.EitherTest where++import qualified Control.Monad.Catch as Exception+import qualified Data.Void as Void+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Extra.Either" $ do+ Test.describe test "hush" $ do+ Test.it test "works with Left" $ do+ Test.assertEq test (Either.hush (Left () :: Either () Void.Void)) Nothing++ Test.it test "works with Right" $ do+ Test.assertEq test (Either.hush (Right () :: Either Void.Void ())) (Just ())++ Test.describe test "throw" $ do+ Test.it test "throws an exception for Left" $ do+ result <- Exception.try . Either.throw $ Left MkTestException+ Test.assertEq test result (Left MkTestException :: Either TestException Void.Void)++ Test.it test "returns the value for Right" $ do+ value <- Either.throw (Right () :: Either Void.Void ())+ Test.assertEq test value ()++data TestException+ = MkTestException+ deriving (Eq, Show)++instance Exception.Exception TestException
+ source/library/Signet/Unstable/Extra/Http.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Extra.Http where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.CaseInsensitive as CI+import qualified Network.HTTP.Types as Http++hWebhookId :: Http.HeaderName+hWebhookId = CI.mk $ Ascii.pack "webhook-id"++hWebhookSignature :: Http.HeaderName+hWebhookSignature = CI.mk $ Ascii.pack "webhook-signature"++hWebhookTimestamp :: Http.HeaderName+hWebhookTimestamp = CI.mk $ Ascii.pack "webhook-timestamp"
+ source/library/Signet/Unstable/Extra/HttpTest.hs view
@@ -0,0 +1,20 @@+module Signet.Unstable.Extra.HttpTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.CaseInsensitive as CI+import qualified Signet.Unstable.Extra.Http as Http+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Extra.Http" $ do+ Test.describe test "hWebhookId" $ do+ Test.it test "creates the correct header name" $ do+ Test.assertEq test Http.hWebhookId (CI.mk (Ascii.pack "webhook-id"))++ Test.describe test "hWebhookSignature" $ do+ Test.it test "creates the correct header name" $ do+ Test.assertEq test Http.hWebhookSignature (CI.mk (Ascii.pack "webhook-signature"))++ Test.describe test "hWebhookTimestamp" $ do+ Test.it test "creates the correct header name" $ do+ Test.assertEq test Http.hWebhookTimestamp (CI.mk (Ascii.pack "webhook-timestamp"))
+ source/library/Signet/Unstable/Extra/Maybe.hs view
@@ -0,0 +1,4 @@+module Signet.Unstable.Extra.Maybe where++note :: e -> Maybe a -> Either e a+note = flip maybe Right . Left
+ source/library/Signet/Unstable/Extra/MaybeTest.hs view
@@ -0,0 +1,14 @@+module Signet.Unstable.Extra.MaybeTest where++import qualified Data.Void as Void+import qualified Signet.Unstable.Extra.Maybe as Maybe+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Extra.Maybe" $ do+ Test.describe test "note" $ do+ Test.it test "works with nothing" $ do+ Test.assertEq test (Maybe.note () (Nothing :: Maybe Void.Void)) (Left ())++ Test.it test "works with just" $ do+ Test.assertEq test (Maybe.note () (Just True)) (Right True)
+ source/library/Signet/Unstable/Type/AsymmetricSignature.hs view
@@ -0,0 +1,28 @@+module Signet.Unstable.Type.AsymmetricSignature where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype AsymmetricSignature+ = MkAsymmetricSignature Ed25519.Signature+ deriving (Eq, Show)++unwrap :: AsymmetricSignature -> Ed25519.Signature+unwrap (MkAsymmetricSignature signature) = signature++parse ::+ ByteString.ByteString ->+ Either InvalidAsymmetricSignature.InvalidAsymmetricSignature AsymmetricSignature+parse encoded = Maybe.note (InvalidAsymmetricSignature.MkInvalidAsymmetricSignature encoded) $ do+ byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+ fmap MkAsymmetricSignature+ . Error.maybeCryptoError+ $ Ed25519.signature (byteString :: ByteString.ByteString)++render :: AsymmetricSignature -> ByteString.ByteString+render = Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/AsymmetricSignatureTest.hs view
@@ -0,0 +1,26 @@+module Signet.Unstable.Type.AsymmetricSignatureTest where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.AsymmetricSignature" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid input" $ do+ let byteString = Ascii.pack "invalid"+ let result = AsymmetricSignature.parse byteString+ Test.assertEq test result (Left $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString)++ Test.it test "succeeds with valid input" $ do+ let result = AsymmetricSignature.parse $ Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="+ signature <- Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+ Test.assertEq test result (Right $ AsymmetricSignature.MkAsymmetricSignature signature)++ Test.describe test "render" $ do+ Test.it test "works" $ do+ asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+ Test.assertEq test (AsymmetricSignature.render asymmetricSignature) (Ascii.pack "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")
+ source/library/Signet/Unstable/Type/Id.hs view
@@ -0,0 +1,26 @@+module Signet.Unstable.Type.Id where++import qualified Control.Monad as Monad+import qualified Data.ByteString as ByteString+import qualified Data.Word as Word+import qualified Signet.Unstable.Exception.InvalidId as InvalidId++newtype Id+ = MkId ByteString.ByteString+ deriving (Eq, Show)++unwrap :: Id -> ByteString.ByteString+unwrap (MkId byteString) = byteString++separator :: Word.Word8+separator = 0x2e++parse :: ByteString.ByteString -> Either InvalidId.InvalidId Id+parse byteString = do+ Monad.when (ByteString.any (== separator) byteString)+ . Left+ $ InvalidId.MkInvalidId byteString+ Right $ MkId byteString++render :: Id -> ByteString.ByteString+render = unwrap
+ source/library/Signet/Unstable/Type/IdTest.hs view
@@ -0,0 +1,25 @@+module Signet.Unstable.Type.IdTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidId as InvalidId+import qualified Signet.Unstable.Type.Id as Id+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Id" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with input containing separator" $ do+ let byteString = Ascii.pack "invalid.id"+ let result = Id.parse byteString+ Test.assertEq test result (Left $ InvalidId.MkInvalidId byteString)++ Test.it test "succeeds with valid input" $ do+ let byteString = Ascii.pack "valid-id"+ let result = Id.parse byteString+ Test.assertEq test result (Right $ Id.MkId byteString)++ Test.describe test "render" $ do+ Test.it test "returns the original ByteString" $ do+ let byteString = Ascii.pack "valid-id"+ let id_ = Id.MkId byteString+ Test.assertEq test (Id.render id_) byteString
+ source/library/Signet/Unstable/Type/Message.hs view
@@ -0,0 +1,36 @@+module Signet.Unstable.Type.Message where++import qualified Data.Bifunctor as Bifunctor+import qualified Data.ByteString as ByteString+import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage+import qualified Signet.Unstable.Type.Id as Id+import qualified Signet.Unstable.Type.Payload as Payload+import qualified Signet.Unstable.Type.Timestamp as Timestamp++data Message = MkMessage+ { id_ :: Id.Id,+ timestamp :: Timestamp.Timestamp,+ payload :: Payload.Payload+ }+ deriving (Eq, Show)++parse :: ByteString.ByteString -> Either InvalidMessage.InvalidMessage Message+parse x = do+ let (rawId, y) = ByteString.break (== Id.separator) x+ theId <- Bifunctor.first InvalidMessage.InvalidId $ Id.parse rawId+ let (rawTimestamp, z) =+ ByteString.break (== Id.separator) $+ ByteString.drop 1 y+ theTimestamp <-+ Bifunctor.first InvalidMessage.InvalidTimestamp $+ Timestamp.parse rawTimestamp+ let thePayload = Payload.MkPayload $ ByteString.drop 1 z+ pure MkMessage {id_ = theId, timestamp = theTimestamp, payload = thePayload}++render :: Message -> ByteString.ByteString+render message =+ Id.render (id_ message)+ <> ByteString.singleton Id.separator+ <> Timestamp.render (timestamp message)+ <> ByteString.singleton Id.separator+ <> Payload.unwrap (payload message)
+ source/library/Signet/Unstable/Type/MessageTest.hs view
@@ -0,0 +1,49 @@+module Signet.Unstable.Type.MessageTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidMessage as InvalidMessage+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Extra.Either as Either+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.Test as Test+import qualified Signet.Unstable.Type.Timestamp as Timestamp++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Message" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid timestamp" $ do+ let timestamp = Ascii.pack "invalid"+ let byteString = Ascii.pack "i." <> timestamp <> Ascii.pack ".p"+ let result = Message.parse byteString+ Test.assertEq test result (Left (InvalidMessage.InvalidTimestamp $ InvalidTimestamp.MkInvalidTimestamp timestamp))++ Test.it test "succeeds with valid input" $ do+ let result = Message.parse $ Ascii.pack "i.0.p"+ id_ <- Either.throw . Id.parse $ Ascii.pack "i"+ timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"+ let payload = Payload.MkPayload $ Ascii.pack "p"+ Test.assertEq+ test+ result+ ( Right+ Message.MkMessage+ { Message.id_ = id_,+ Message.timestamp = timestamp,+ Message.payload = payload+ }+ )++ Test.describe test "render" $ do+ Test.it test "returns the correct ByteString representation" $ do+ id_ <- Either.throw . Id.parse $ Ascii.pack "i"+ timestamp <- Either.throw . Timestamp.parse $ Ascii.pack "0"+ let payload = Payload.MkPayload $ Ascii.pack "p"+ let message =+ Message.MkMessage+ { Message.id_ = id_,+ Message.timestamp = timestamp,+ Message.payload = payload+ }+ Test.assertEq test (Message.render message) (Ascii.pack "i.0.p")
+ source/library/Signet/Unstable/Type/Payload.hs view
@@ -0,0 +1,10 @@+module Signet.Unstable.Type.Payload where++import qualified Data.ByteString as ByteString++newtype Payload+ = MkPayload ByteString.ByteString+ deriving (Eq, Show)++unwrap :: Payload -> ByteString.ByteString+unwrap (MkPayload byteString) = byteString
+ source/library/Signet/Unstable/Type/PayloadTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Type.PayloadTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Payload" $ do+ pure ()
+ source/library/Signet/Unstable/Type/PublicKey.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.PublicKey where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype PublicKey+ = MkPublicKey Ed25519.PublicKey+ deriving (Eq, Show)++unwrap :: PublicKey -> Ed25519.PublicKey+unwrap (MkPublicKey publicKey) = publicKey++prefix :: ByteString.ByteString+prefix = Ascii.pack "whpk_"++parse :: ByteString.ByteString -> Either InvalidPublicKey.InvalidPublicKey PublicKey+parse prefixed = Maybe.note (InvalidPublicKey.MkInvalidPublicKey prefixed) $ do+ encoded <- ByteString.stripPrefix prefix prefixed+ byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+ fmap MkPublicKey+ . Error.maybeCryptoError+ $ Ed25519.publicKey (byteString :: ByteString.ByteString)++render :: PublicKey -> ByteString.ByteString+render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/PublicKeyTest.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.PublicKeyTest where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.PublicKey" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid prefix" $ do+ let byteString = Ascii.pack "invalid"+ let result = PublicKey.parse byteString+ Test.assertEq test result (Left (InvalidPublicKey.MkInvalidPublicKey byteString))++ Test.it test "fails with invalid input" $ do+ let byteString = Ascii.pack "whpk_invalid"+ let result = PublicKey.parse byteString+ Test.assertEq test result (Left (InvalidPublicKey.MkInvalidPublicKey byteString))++ Test.it test "succeeds with valid input" $ do+ let result = PublicKey.parse $ Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+ publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+ Test.assertEq test result (Right publicKey)++ Test.describe test "render" $ do+ Test.it test "works" $ do+ publicKey <- fmap PublicKey.MkPublicKey . Error.throwCryptoErrorIO . Ed25519.publicKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+ Test.assertEq test (PublicKey.render publicKey) (Ascii.pack "whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU=")
+ source/library/Signet/Unstable/Type/Secret.hs view
@@ -0,0 +1,27 @@+module Signet.Unstable.Type.Secret where++import qualified Data.ByteArray as ByteArray+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype Secret+ = MkSecret ByteArray.ScrubbedBytes+ deriving (Eq, Show)++unwrap :: Secret -> ByteArray.ScrubbedBytes+unwrap (MkSecret scrubbedBytes) = scrubbedBytes++prefix :: ByteString.ByteString+prefix = Ascii.pack "whsec_"++parse :: ByteString.ByteString -> Either InvalidSecret.InvalidSecret Secret+parse prefixed = Maybe.note (InvalidSecret.MkInvalidSecret prefixed) $ do+ encoded <- ByteString.stripPrefix prefix prefixed+ fmap MkSecret . Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded++render :: Secret -> ByteString.ByteString+render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/SecretKey.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.SecretKey where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype SecretKey+ = MkSecretKey Ed25519.SecretKey+ deriving (Eq, Show)++unwrap :: SecretKey -> Ed25519.SecretKey+unwrap (MkSecretKey secretKey) = secretKey++prefix :: ByteString.ByteString+prefix = Ascii.pack "whsk_"++parse :: ByteString.ByteString -> Either InvalidSecretKey.InvalidSecretKey SecretKey+parse prefixed = Maybe.note (InvalidSecretKey.MkInvalidSecretKey prefixed) $ do+ encoded <- ByteString.stripPrefix prefix prefixed+ byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+ fmap MkSecretKey+ . Error.maybeCryptoError+ $ Ed25519.secretKey (byteString :: ByteString.ByteString)++render :: SecretKey -> ByteString.ByteString+render = mappend prefix . Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/SecretKeyTest.hs view
@@ -0,0 +1,31 @@+module Signet.Unstable.Type.SecretKeyTest where++import qualified Crypto.Error as Error+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecretKey as InvalidSecretKey+import qualified Signet.Unstable.Type.SecretKey as SecretKey+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.SecretKey" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid prefix" $ do+ let byteString = Ascii.pack "invalid"+ let result = SecretKey.parse byteString+ Test.assertEq test result (Left (InvalidSecretKey.MkInvalidSecretKey byteString))++ Test.it test "fails with invalid input" $ do+ let byteString = Ascii.pack "whsk_invalid"+ let result = SecretKey.parse byteString+ Test.assertEq test result (Left (InvalidSecretKey.MkInvalidSecretKey byteString))++ Test.it test "succeeds with valid input" $ do+ let result = SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+ secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+ Test.assertEq test result (Right secretKey)++ Test.describe test "render" $ do+ Test.it test "works" $ do+ secretKey <- fmap SecretKey.MkSecretKey . Error.throwCryptoErrorIO . Ed25519.secretKey $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"+ Test.assertEq test (SecretKey.render secretKey) (Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU=")
+ source/library/Signet/Unstable/Type/SecretTest.hs view
@@ -0,0 +1,30 @@+module Signet.Unstable.Type.SecretTest where++import qualified Data.ByteArray as ByteArray+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSecret as InvalidSecret+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Secret" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid prefix" $ do+ let byteString = Ascii.pack "invalid"+ let result = Secret.parse byteString+ Test.assertEq test result (Left (InvalidSecret.MkInvalidSecret byteString))++ Test.it test "fails with invalid input" $ do+ let byteString = Ascii.pack "whsec_invalid"+ let result = Secret.parse byteString+ Test.assertEq test result (Left (InvalidSecret.MkInvalidSecret byteString))++ Test.it test "succeeds with valid input" $ do+ let result = Secret.parse $ Ascii.pack "whsec_MDEyMzQ1Njc4OQ=="+ let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"+ Test.assertEq test result (Right secret)++ Test.describe test "render" $ do+ Test.it test "works" $ do+ let secret = Secret.MkSecret . ByteArray.convert $ Ascii.pack "0123456789"+ Test.assertEq test (Secret.render secret) (Ascii.pack "whsec_MDEyMzQ1Njc4OQ==")
+ source/library/Signet/Unstable/Type/Signature.hs view
@@ -0,0 +1,49 @@+module Signet.Unstable.Type.Signature where++import qualified Data.Bifunctor as Bifunctor+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Data.Word as Word+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++data Signature+ = Asymmetric AsymmetricSignature.AsymmetricSignature+ | Symmetric SymmetricSignature.SymmetricSignature+ deriving (Eq, Show)++separator :: Word.Word8+separator = 0x2c++asymmetricPrefix :: ByteString.ByteString+asymmetricPrefix = Ascii.pack "v1a"++symmetricPrefix :: ByteString.ByteString+symmetricPrefix = Ascii.pack "v1"++parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature (Either UnknownSignature.UnknownSignature Signature)+parse prefixed = do+ let (prefix, rest) = ByteString.break (== separator) prefixed+ case ByteString.drop 1 rest of+ byteString+ | prefix == asymmetricPrefix ->+ Bifunctor.bimap InvalidSignature.InvalidAsymmetricSignature (Right . Asymmetric) $+ AsymmetricSignature.parse byteString+ | prefix == symmetricPrefix ->+ Bifunctor.bimap InvalidSignature.InvalidSymmetricSignature (Right . Symmetric) $+ SymmetricSignature.parse byteString+ _ -> Right . Left $ UnknownSignature.MkUnknownSignature prefixed++render :: Signature -> ByteString.ByteString+render signature =+ case signature of+ Asymmetric asymmetricSignature ->+ asymmetricPrefix+ <> ByteString.singleton separator+ <> AsymmetricSignature.render asymmetricSignature+ Symmetric symmetricSignature ->+ symmetricPrefix+ <> ByteString.singleton separator+ <> SymmetricSignature.render symmetricSignature
+ source/library/Signet/Unstable/Type/SignatureTest.hs view
@@ -0,0 +1,52 @@+module Signet.Unstable.Type.SignatureTest where++import qualified Crypto.Error as Error+import qualified Crypto.Hash as Hash+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Signature" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid asymmetric signature" $ do+ let byteString = Ascii.pack "invalid"+ let result = Signature.parse $ Ascii.pack "v1a," <> byteString+ Test.assertEq test result (Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature byteString))++ Test.it test "fails with invalid symmetric signature" $ do+ let byteString = Ascii.pack "invalid"+ let result = Signature.parse $ Ascii.pack "v1," <> byteString+ Test.assertEq test result (Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString))++ Test.it test "returns unknown signature with unrecognized prefix" $ do+ let byteString = Ascii.pack "unknown"+ let result = Signature.parse byteString+ Test.assertEq test result (Right (Left $ UnknownSignature.MkUnknownSignature byteString))++ Test.it test "succeeds with valid asymmetric signature" $ do+ let byteString = Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="+ signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+ Test.assertEq test (Signature.parse byteString) (Right (Right signature))++ Test.it test "succeeds with valid symmetric signature" $ do+ let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="+ let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ Test.assertEq test (Signature.parse byteString) (Right (Right signature))++ Test.describe test "render" $ do+ Test.it test "renders asymmetric signature correctly" $ do+ signature <- fmap (Signature.Asymmetric . AsymmetricSignature.MkAsymmetricSignature) . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+ Test.assertEq test (Signature.render signature) (Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")++ Test.it test "renders symmetric signature correctly" $ do+ let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ Test.assertEq test (Signature.render signature) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
+ source/library/Signet/Unstable/Type/Signatures.hs view
@@ -0,0 +1,30 @@+module Signet.Unstable.Type.Signatures where++import qualified Data.ByteString as ByteString+import qualified Data.Either as Either+import qualified Data.Word as Word+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++newtype Signatures+ = MkSignatures [Signature.Signature]+ deriving (Eq, Show)++unwrap :: Signatures -> [Signature.Signature]+unwrap (MkSignatures signatures) = signatures++separator :: Word.Word8+separator = 0x20++parse :: ByteString.ByteString -> Either InvalidSignature.InvalidSignature ([UnknownSignature.UnknownSignature], Signatures)+parse =+ fmap (fmap MkSignatures . Either.partitionEithers)+ . traverse Signature.parse+ . ByteString.split separator++render :: Signatures -> ByteString.ByteString+render =+ ByteString.intercalate (ByteString.singleton separator)+ . fmap Signature.render+ . unwrap
+ source/library/Signet/Unstable/Type/SignaturesTest.hs view
@@ -0,0 +1,71 @@+module Signet.Unstable.Type.SignaturesTest where++import qualified Crypto.Error as Error+import qualified Crypto.Hash as Hash+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature+import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Signatures" $ do+ Test.describe test "parse" $ do+ Test.it test "succeeds with no signatures" $ do+ Test.assertEq test (Signatures.parse ByteString.empty) (Right ([], Signatures.MkSignatures []))++ Test.it test "succeeds with one signature" $ do+ let signature = Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="+ Test.assertEq test (Signatures.parse byteString) (Right ([], Signatures.MkSignatures [signature]))++ Test.it test "succeeds with many signatures" $ do+ let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+ let byteString = Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg=="+ let signatures =+ Signatures.MkSignatures+ [ Signature.Symmetric symmetricSignature,+ Signature.Asymmetric asymmetricSignature+ ]+ Test.assertEq test (Signatures.parse byteString) (Right ([], signatures))++ Test.it test "fails with an invalid symmetric signature" $ do+ let x = Ascii.pack "invalid"+ let byteString = Ascii.pack "v1," <> x+ Test.assertEq test (Signatures.parse byteString) (Left (InvalidSignature.InvalidSymmetricSignature $ InvalidSymmetricSignature.MkInvalidSymmetricSignature x))++ Test.it test "fails with an invalid asymmetric signature" $ do+ let x = Ascii.pack "invalid"+ let byteString = Ascii.pack "v1a," <> x+ Test.assertEq test (Signatures.parse byteString) (Left (InvalidSignature.InvalidAsymmetricSignature $ InvalidAsymmetricSignature.MkInvalidAsymmetricSignature x))++ Test.it test "succeeds with an unknown signature" $ do+ let byteString = Ascii.pack "unknown"+ Test.assertEq test (Signatures.parse byteString) (Right ([UnknownSignature.MkUnknownSignature byteString], Signatures.MkSignatures []))++ Test.describe test "render" $ do+ Test.it test "renders no signatures" $ do+ let signatures = Signatures.MkSignatures []+ Test.assertEq test (Signatures.render signatures) ByteString.empty++ Test.it test "renders one signature" $ do+ let signatures = Signatures.MkSignatures . pure . Signature.Symmetric . SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ Test.assertEq test (Signatures.render signatures) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")++ Test.it test "renders many signatures" $ do+ let symmetricSignature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ asymmetricSignature <- fmap AsymmetricSignature.MkAsymmetricSignature . Error.throwCryptoErrorIO . Ed25519.signature $ Ascii.pack "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz"+ let signatures =+ Signatures.MkSignatures+ [ Signature.Symmetric symmetricSignature,+ Signature.Asymmetric asymmetricSignature+ ]+ Test.assertEq test (Signatures.render signatures) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")
+ source/library/Signet/Unstable/Type/Signer.hs view
@@ -0,0 +1,49 @@+module Signet.Unstable.Type.Signer where++import qualified Crypto.MAC.HMAC as Hmac+import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+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.SymmetricSignature as SymmetricSignature++data Signer+ = Asymmetric SecretKey.SecretKey+ | Symmetric Secret.Secret+ deriving (Eq, Show)++parse :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer+parse byteString = case SecretKey.parse byteString of+ Right secretKey -> Right $ Asymmetric secretKey+ Left _ -> case Secret.parse byteString of+ Right secret -> Right $ Symmetric secret+ Left _ -> Left $ InvalidSigner.MkInvalidSigner byteString++render :: Signer -> ByteString.ByteString+render signer = case signer of+ Asymmetric secretKey -> SecretKey.render secretKey+ Symmetric secret -> Secret.render secret++sign :: Signer -> Message.Message -> Signature.Signature+sign signer = case signer of+ Asymmetric secretKey -> Signature.Asymmetric . asymmetric secretKey+ Symmetric secret -> Signature.Symmetric . symmetric secret++asymmetric :: SecretKey.SecretKey -> Message.Message -> AsymmetricSignature.AsymmetricSignature+asymmetric secretKey =+ let sk = SecretKey.unwrap secretKey+ pk = Ed25519.toPublic sk+ in AsymmetricSignature.MkAsymmetricSignature+ . Ed25519.sign sk pk+ . Message.render++symmetric :: Secret.Secret -> Message.Message -> SymmetricSignature.SymmetricSignature+symmetric secret =+ SymmetricSignature.MkSymmetricSignature+ . Hmac.hmacGetDigest+ . Hmac.hmac (Secret.unwrap secret)+ . Message.render
+ source/library/Signet/Unstable/Type/SignerTest.hs view
@@ -0,0 +1,75 @@+module Signet.Unstable.Type.SignerTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+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.Signer as Signer+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Signer" $ do+ Test.describe test "parse" $ do+ Test.it test "succeeds with a valid secret key" $ do+ let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+ let actual = Signer.parse byteString+ secretKey <- Either.throw $ SecretKey.parse byteString+ Test.assertEq test actual (Right (Signer.Asymmetric secretKey))++ Test.it test "succeeds with a valid secret" $ do+ let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ let actual = Signer.parse byteString+ secret <- Either.throw $ Secret.parse byteString+ Test.assertEq test actual (Right (Signer.Symmetric secret))++ Test.it test "fails with invalid input" $ do+ let byteString = Ascii.pack "invalid"+ let actual = Signer.parse byteString+ Test.assertEq test actual (Left (InvalidSigner.MkInvalidSigner byteString))++ Test.describe test "render" $ do+ Test.it test "works with a secret key" $ do+ let byteString = Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+ secretKey <- Either.throw . SecretKey.parse $ byteString+ Test.assertEq test (Signer.render (Signer.Asymmetric secretKey)) byteString++ Test.it test "works with a secret" $ do+ let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ secret <- Either.throw . Secret.parse $ byteString+ Test.assertEq test (Signer.render (Signer.Symmetric secret)) byteString++ Test.describe test "sign" $ do+ Test.it test "works with asymmetric" $ do+ signer <- Either.throw . Signer.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ let actual = Signer.sign signer message+ Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+ Test.assertEq test actual expected++ Test.it test "works with symmetric" $ do+ signer <- Either.throw . Signer.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ let actual = Signer.sign signer message+ Right expected <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ Test.assertEq test actual expected++ Test.describe test "asymmetric" $ do+ Test.it test "creates correct asymmetric signature" $ do+ secretKey <- Either.throw . SecretKey.parse $ Ascii.pack "whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ let actual = Signer.asymmetric secretKey message+ expected <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+ Test.assertEq test actual expected++ Test.describe test "symmetric" $ do+ Test.it test "creates correct symmetric signature" $ do+ secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ let actual = Signer.symmetric secret message+ expected <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ Test.assertEq test actual expected
+ source/library/Signet/Unstable/Type/SymmetricSignature.hs view
@@ -0,0 +1,28 @@+module Signet.Unstable.Type.SymmetricSignature where++import qualified Crypto.Hash as Hash+import qualified Data.ByteArray as ByteArray+import qualified Data.ByteArray.Encoding as Encoding+import qualified Data.ByteString as ByteString+import qualified Data.Function as Function+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype SymmetricSignature+ = MkSymmetricSignature (Hash.Digest Hash.SHA256)+ deriving (Show)++instance Eq SymmetricSignature where+ (==) = Function.on ByteArray.constEq unwrap++unwrap :: SymmetricSignature -> Hash.Digest Hash.SHA256+unwrap (MkSymmetricSignature digest) = digest++parse :: ByteString.ByteString -> Either InvalidSymmetricSignature.InvalidSymmetricSignature SymmetricSignature+parse encoded = Maybe.note (InvalidSymmetricSignature.MkInvalidSymmetricSignature encoded) $ do+ byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded+ MkSymmetricSignature <$> Hash.digestFromByteString (byteString :: ByteString.ByteString)++render :: SymmetricSignature -> ByteString.ByteString+render = Encoding.convertToBase Encoding.Base64 . unwrap
+ source/library/Signet/Unstable/Type/SymmetricSignatureTest.hs view
@@ -0,0 +1,26 @@+module Signet.Unstable.Type.SymmetricSignatureTest where++import qualified Crypto.Hash as Hash+import qualified Data.ByteString as ByteString+import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.SymmetricSignature" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid symmetric signature" $ do+ let byteString = Ascii.pack "invalid"+ let result = SymmetricSignature.parse byteString+ Test.assertEq test result (Left (InvalidSymmetricSignature.MkInvalidSymmetricSignature byteString))++ Test.it test "succeeds with valid symmetric signature" $ do+ let byteString = Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="+ let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ Test.assertEq test (SymmetricSignature.parse byteString) (Right signature)++ Test.describe test "render" $ do+ Test.it test "renders symmetric signature correctly" $ do+ let signature = SymmetricSignature.MkSymmetricSignature $ Hash.hash ByteString.empty+ Test.assertEq test (SymmetricSignature.render signature) (Ascii.pack "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
+ source/library/Signet/Unstable/Type/Test.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE RankNTypes #-}++module Signet.Unstable.Type.Test where++import qualified Control.Monad as Monad+import qualified Data.Void as Void+import qualified GHC.Stack as Stack++data Test spec = MkTest+ { assertFailure :: (Stack.HasCallStack) => String -> IO Void.Void,+ describe :: String -> spec () -> spec (),+ it :: String -> IO () -> spec ()+ }++assertEq :: (Stack.HasCallStack, Eq a, Show a) => Test tree -> a -> a -> IO ()+assertEq test expected actual =+ Monad.when (expected /= actual)+ . Monad.void+ . assertFailure test+ $ "expected " <> show expected <> " but got " <> show actual
+ source/library/Signet/Unstable/Type/Timestamp.hs view
@@ -0,0 +1,33 @@+module Signet.Unstable.Type.Timestamp where++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.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Extra.Maybe as Maybe++newtype Timestamp+ = MkTimestamp Time.UTCTime+ deriving (Eq, Show)++unwrap :: Timestamp -> Time.UTCTime+unwrap (MkTimestamp utcTime) = utcTime++format :: String+format = "%s"++parse :: ByteString.ByteString -> Either InvalidTimestamp.InvalidTimestamp Timestamp+parse byteString = Maybe.note (InvalidTimestamp.MkInvalidTimestamp byteString) $ do+ text <- Either.hush $ Text.decodeUtf8' byteString+ fmap MkTimestamp+ . Time.parseTimeM False Time.defaultTimeLocale format+ $ Text.unpack text++render :: Timestamp -> ByteString.ByteString+render =+ Text.encodeUtf8+ . Text.pack+ . Time.formatTime Time.defaultTimeLocale format+ . unwrap
+ source/library/Signet/Unstable/Type/TimestampTest.hs view
@@ -0,0 +1,32 @@+module Signet.Unstable.Type.TimestampTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.InvalidTimestamp as InvalidTimestamp+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Timestamp as Timestamp++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Timestamp" $ do+ Test.describe test "parse" $ do+ Test.it test "fails with invalid timestamp format" $ do+ let byteString = Ascii.pack "invalid-timestamp"+ let result = Timestamp.parse byteString+ Test.assertEq test result (Left (InvalidTimestamp.MkInvalidTimestamp byteString))++ Test.it test "succeeds with valid timestamp format" $ do+ let byteString = Ascii.pack "1617235200"+ let result = Timestamp.parse byteString+ case result of+ Right timestamp -> do+ let utcTime = Timestamp.unwrap timestamp+ let expectedTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0+ Test.assertEq test utcTime expectedTime+ Left _ -> fail "Expected Right but got Left"++ Test.describe test "render" $ do+ Test.it test "returns the correct ByteString representation" $ do+ let utcTime = Time.UTCTime (Time.fromGregorian 2021 4 1) 0+ let timestamp = Timestamp.MkTimestamp utcTime+ let expected = Ascii.pack "1617235200"+ Test.assertEq test (Timestamp.render timestamp) expected
+ source/library/Signet/Unstable/Type/Tolerance.hs view
@@ -0,0 +1,29 @@+module Signet.Unstable.Type.Tolerance where++import qualified Control.Monad as Monad+import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Type.Timestamp as Timestamp++newtype Tolerance+ = MkTolerance Time.NominalDiffTime+ deriving (Eq, Show)++unwrap :: Tolerance -> Time.NominalDiffTime+unwrap (MkTolerance nominalDiffTime) = nominalDiffTime++typical :: Tolerance+typical = MkTolerance 300++check ::+ Tolerance ->+ Time.UTCTime ->+ Timestamp.Timestamp ->+ Either ToleranceException.ToleranceException ()+check tolerance utcTime timestamp = do+ let diff = Time.diffUTCTime utcTime $ Timestamp.unwrap timestamp+ let hi = unwrap tolerance+ let lo = negate hi+ Monad.when (lo > diff || diff > hi)+ . Left+ $ ToleranceException.MkToleranceException timestamp
+ source/library/Signet/Unstable/Type/ToleranceTest.hs view
@@ -0,0 +1,33 @@+module Signet.Unstable.Type.ToleranceTest where++import qualified Data.Time as Time+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Timestamp as Timestamp+import qualified Signet.Unstable.Type.Tolerance as Tolerance++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Tolerance" $ do+ Test.describe test "check" $ do+ Test.it test "succeeds when timestamp is within tolerance" $ do+ let tolerance = Tolerance.MkTolerance 1+ let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60+ let timestamp = Timestamp.MkTimestamp utcTime+ let result = Tolerance.check tolerance utcTime timestamp+ Test.assertEq test result (Right ())++ Test.it test "fails when timestamp is too old" $ do+ let tolerance = Tolerance.MkTolerance 1+ let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60+ let timestamp = Timestamp.MkTimestamp utcTime+ let now = Time.addUTCTime 2 utcTime+ let result = Tolerance.check tolerance now timestamp+ Test.assertEq test result (Left (ToleranceException.MkToleranceException timestamp))++ Test.it test "fails when timestamp is in the future" $ do+ let tolerance = Tolerance.MkTolerance 1+ let utcTime = Time.UTCTime (Time.fromGregorian 2001 1 1) 60+ let timestamp = Timestamp.MkTimestamp utcTime+ let now = Time.addUTCTime (-2) utcTime+ let result = Tolerance.check tolerance now timestamp+ Test.assertEq test result (Left (ToleranceException.MkToleranceException timestamp))
+ source/library/Signet/Unstable/Type/UnknownSignature.hs view
@@ -0,0 +1,10 @@+module Signet.Unstable.Type.UnknownSignature where++import qualified Data.ByteString as ByteString++newtype UnknownSignature+ = MkUnknownSignature ByteString.ByteString+ deriving (Eq, Show)++unwrap :: UnknownSignature -> ByteString.ByteString+unwrap (MkUnknownSignature byteString) = byteString
+ source/library/Signet/Unstable/Type/UnknownSignatureTest.hs view
@@ -0,0 +1,7 @@+module Signet.Unstable.Type.UnknownSignatureTest where++import qualified Signet.Unstable.Type.Test as Test++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.UnknownSignature" $ do+ pure ()
+ source/library/Signet/Unstable/Type/Verifier.hs view
@@ -0,0 +1,75 @@+module Signet.Unstable.Type.Verifier where++import qualified Crypto.PubKey.Ed25519 as Ed25519+import qualified Data.ByteString as ByteString+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier+import qualified Signet.Unstable.Exception.VerificationException as VerificationException+import qualified Signet.Unstable.Extra.Maybe as Maybe+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Secret as Secret+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++data Verifier+ = Asymmetric PublicKey.PublicKey+ | Symmetric Secret.Secret+ deriving (Eq, Show)++parse :: ByteString.ByteString -> Either InvalidVerifier.InvalidVerifier Verifier+parse byteString = case PublicKey.parse byteString of+ Right publicKey -> Right $ Asymmetric publicKey+ Left _ -> case Secret.parse byteString of+ Right secret -> Right $ Symmetric secret+ Left _ -> Left $ InvalidVerifier.MkInvalidVerifier byteString++render :: Verifier -> ByteString.ByteString+render verifier = case verifier of+ Asymmetric publicKey -> PublicKey.render publicKey+ Symmetric secret -> Secret.render secret++verify ::+ Verifier ->+ Message.Message ->+ Signatures.Signatures ->+ Either VerificationException.VerificationException Signature.Signature+verify verifier message =+ case verifier of+ Asymmetric publicKey -> fmap Signature.Asymmetric . asymmetric publicKey message+ Symmetric secret -> fmap Signature.Symmetric . symmetric secret message++asymmetric ::+ PublicKey.PublicKey ->+ Message.Message ->+ Signatures.Signatures ->+ Either VerificationException.VerificationException AsymmetricSignature.AsymmetricSignature+asymmetric publicKey message =+ let toAsymmetric signature = case signature of+ Signature.Asymmetric asymmetricSignature -> Just asymmetricSignature+ Signature.Symmetric _ -> Nothing+ pk = PublicKey.unwrap publicKey+ bs = Message.render message+ in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)+ . List.find (Ed25519.verify pk bs . AsymmetricSignature.unwrap)+ . Maybe.mapMaybe toAsymmetric+ . Signatures.unwrap++symmetric ::+ Secret.Secret ->+ Message.Message ->+ Signatures.Signatures ->+ Either VerificationException.VerificationException SymmetricSignature.SymmetricSignature+symmetric secret message =+ let toSymmetric signature = case signature of+ Signature.Asymmetric _ -> Nothing+ Signature.Symmetric symmetricSignature -> Just symmetricSignature+ expected = Signer.symmetric secret message+ in Maybe.note (VerificationException.MkVerificationException $ Message.id_ message)+ . List.find (expected ==)+ . Maybe.mapMaybe toSymmetric+ . Signatures.unwrap
+ source/library/Signet/Unstable/Type/VerifierTest.hs view
@@ -0,0 +1,109 @@+module Signet.Unstable.Type.VerifierTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier+import qualified Signet.Unstable.Exception.VerificationException as VerificationException+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.PublicKey as PublicKey+import qualified Signet.Unstable.Type.Secret as Secret+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Verifier as Verifier++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable.Type.Verifier" $ do+ Test.describe test "parse" $ do+ Test.it test "succeeds with a valid public key" $ do+ let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+ let actual = Verifier.parse byteString+ publicKey <- Either.throw $ PublicKey.parse byteString+ Test.assertEq test actual (Right (Verifier.Asymmetric publicKey))++ Test.it test "succeeds with a valid secret" $ do+ let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ let actual = Verifier.parse byteString+ secret <- Either.throw $ Secret.parse byteString+ Test.assertEq test actual (Right (Verifier.Symmetric secret))++ Test.it test "fails with invalid input" $ do+ let byteString = Ascii.pack "invalid"+ let actual = Verifier.parse byteString+ Test.assertEq test actual (Left (InvalidVerifier.MkInvalidVerifier byteString))++ Test.describe test "render" $ do+ Test.it test "works with a public key" $ do+ let byteString = Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+ publicKey <- Either.throw . PublicKey.parse $ byteString+ Test.assertEq test (Verifier.render (Verifier.Asymmetric publicKey)) byteString++ Test.it test "works with a secret" $ do+ let byteString = Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ secret <- Either.throw . Secret.parse $ byteString+ Test.assertEq test (Verifier.render (Verifier.Symmetric secret)) byteString++ Test.describe test "verify" $ do+ Test.it test "succeeds with a valid asymmetric signature" $ do+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+ let actual = Verifier.verify verifier message signatures+ Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+ Test.assertEq test actual (Right signature)++ Test.it test "fails with an invalid asymmetric signature" $ do+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="+ let actual = Verifier.verify verifier message signatures+ Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))++ Test.it test "succeeds with a valid symmetric signature" $ do+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ let actual = Verifier.verify verifier message signatures+ Right signature <- Either.throw . Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ Test.assertEq test actual (Right signature)++ Test.it test "fails with an invalid symmetric signature" $ do+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="+ let actual = Verifier.verify verifier message signatures+ Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))++ Test.describe test "asymmetric" $ do+ Test.it test "succeeds with a valid signature" $ do+ publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+ let actual = Verifier.asymmetric publicKey message signatures+ asymmetricSignature <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="+ Test.assertEq test actual (Right asymmetricSignature)++ Test.it test "fails with an invalid signature" $ do+ publicKey <- Either.throw . PublicKey.parse $ Ascii.pack "whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="+ let actual = Verifier.asymmetric publicKey message signatures+ Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))++ Test.describe test "symmetric" $ do+ Test.it test "succeeds with a valid signature" $ do+ secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ let actual = Verifier.symmetric secret message signatures+ symmetricSignature <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ Test.assertEq test actual (Right symmetricSignature)++ Test.it test "fails with an invalid signature" $ do+ secret <- Either.throw . Secret.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="+ let actual = Verifier.symmetric secret message signatures+ Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))
+ source/library/Signet/UnstableTest.hs view
@@ -0,0 +1,56 @@+module Signet.UnstableTest where++import qualified Data.ByteString.Char8 as Ascii+import qualified Data.Time as Time+import qualified Signet.Unstable as Signet+import qualified Signet.Unstable.Exception.SignetException as SignetException+import qualified Signet.Unstable.Exception.ToleranceException as ToleranceException+import qualified Signet.Unstable.Exception.VerificationException as VerificationException+import qualified Signet.Unstable.Extra.Either as Either+import qualified Signet.Unstable.Type.Message as Message+import qualified Signet.Unstable.Type.Signature as Signature+import qualified Signet.Unstable.Type.Signatures as Signatures+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.Tolerance as Tolerance+import qualified Signet.Unstable.Type.Verifier as Verifier++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = Test.describe test "Signet.Unstable" $ do+ Test.describe test "verifyWebhookText" $ do+ pure ()++ Test.describe test "verifyWebhookByteString" $ do+ pure ()++ Test.describe test "verifyWebhook" $ do+ pure ()++ Test.describe test "verifyWebhookWith" $ do+ Test.it test "succeeds with a valid symmetric signature" $ do+ let tolerance = Tolerance.typical+ let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ let byteString = Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ (_, signatures) <- Either.throw $ Signatures.parse byteString+ let result = Signet.verifyWebhookWith tolerance now verifier message signatures+ Right signature <- Either.throw $ Signature.parse byteString+ Test.assertEq test result (Right signature)++ Test.it test "fails with an invalid timestamp" $ do+ let tolerance = Tolerance.typical+ let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.301.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="+ let result = Signet.verifyWebhookWith tolerance now verifier message signatures+ Test.assertEq test result (Left (SignetException.ToleranceException . ToleranceException.MkToleranceException $ Message.timestamp message))++ Test.it test "fails with an invalid symmetric signature" $ do+ let tolerance = Tolerance.typical+ let now = Time.UTCTime (Time.fromGregorian 1970 1 1) 0+ verifier <- Either.throw . Verifier.parse $ Ascii.pack "whsec_bXlzZWNyZXRrZXkxMjM0NQ=="+ message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"+ (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="+ let result = Signet.verifyWebhookWith tolerance now verifier message signatures+ Test.assertEq test result (Left (SignetException.VerificationException . VerificationException.MkVerificationException $ Message.id_ message))
+ source/library/SignetTest.hs view
@@ -0,0 +1,72 @@+module SignetTest where++import qualified Signet.Unstable.Exception.InvalidAsymmetricSignatureTest+import qualified Signet.Unstable.Exception.InvalidIdTest+import qualified Signet.Unstable.Exception.InvalidMessageTest+import qualified Signet.Unstable.Exception.InvalidPublicKeyTest+import qualified Signet.Unstable.Exception.InvalidSecretKeyTest+import qualified Signet.Unstable.Exception.InvalidSecretTest+import qualified Signet.Unstable.Exception.InvalidSignatureTest+import qualified Signet.Unstable.Exception.InvalidSignerTest+import qualified Signet.Unstable.Exception.InvalidSymmetricSignatureTest+import qualified Signet.Unstable.Exception.InvalidTimestampTest+import qualified Signet.Unstable.Exception.InvalidVerifierTest+import qualified Signet.Unstable.Exception.SignetExceptionTest+import qualified Signet.Unstable.Exception.ToleranceExceptionTest+import qualified Signet.Unstable.Exception.VerificationExceptionTest+import qualified Signet.Unstable.Extra.EitherTest+import qualified Signet.Unstable.Extra.HttpTest+import qualified Signet.Unstable.Extra.MaybeTest+import qualified Signet.Unstable.Type.AsymmetricSignatureTest+import qualified Signet.Unstable.Type.IdTest+import qualified Signet.Unstable.Type.MessageTest+import qualified Signet.Unstable.Type.PayloadTest+import qualified Signet.Unstable.Type.PublicKeyTest+import qualified Signet.Unstable.Type.SecretKeyTest+import qualified Signet.Unstable.Type.SecretTest+import qualified Signet.Unstable.Type.SignatureTest+import qualified Signet.Unstable.Type.SignaturesTest+import qualified Signet.Unstable.Type.SignerTest+import qualified Signet.Unstable.Type.SymmetricSignatureTest+import qualified Signet.Unstable.Type.Test as Test+import qualified Signet.Unstable.Type.TimestampTest+import qualified Signet.Unstable.Type.ToleranceTest+import qualified Signet.Unstable.Type.UnknownSignatureTest+import qualified Signet.Unstable.Type.VerifierTest+import qualified Signet.UnstableTest++spec :: (Monad tree) => Test.Test tree -> tree ()+spec test = do+ Signet.Unstable.Exception.InvalidAsymmetricSignatureTest.spec test+ Signet.Unstable.Exception.InvalidIdTest.spec test+ Signet.Unstable.Exception.InvalidMessageTest.spec test+ Signet.Unstable.Exception.InvalidPublicKeyTest.spec test+ Signet.Unstable.Exception.InvalidSecretKeyTest.spec test+ Signet.Unstable.Exception.InvalidSecretTest.spec test+ Signet.Unstable.Exception.InvalidSignatureTest.spec test+ Signet.Unstable.Exception.InvalidSignerTest.spec test+ Signet.Unstable.Exception.InvalidSymmetricSignatureTest.spec test+ Signet.Unstable.Exception.InvalidTimestampTest.spec test+ Signet.Unstable.Exception.InvalidVerifierTest.spec test+ Signet.Unstable.Exception.SignetExceptionTest.spec test+ Signet.Unstable.Exception.ToleranceExceptionTest.spec test+ Signet.Unstable.Exception.VerificationExceptionTest.spec test+ Signet.Unstable.Extra.EitherTest.spec test+ Signet.Unstable.Extra.HttpTest.spec test+ Signet.Unstable.Extra.MaybeTest.spec test+ Signet.Unstable.Type.AsymmetricSignatureTest.spec test+ Signet.Unstable.Type.IdTest.spec test+ Signet.Unstable.Type.MessageTest.spec test+ Signet.Unstable.Type.PayloadTest.spec test+ Signet.Unstable.Type.PublicKeyTest.spec test+ Signet.Unstable.Type.SecretKeyTest.spec test+ Signet.Unstable.Type.SecretTest.spec test+ Signet.Unstable.Type.SignaturesTest.spec test+ Signet.Unstable.Type.SignatureTest.spec test+ Signet.Unstable.Type.SignerTest.spec test+ Signet.Unstable.Type.SymmetricSignatureTest.spec test+ Signet.Unstable.Type.TimestampTest.spec test+ Signet.Unstable.Type.ToleranceTest.spec test+ Signet.Unstable.Type.UnknownSignatureTest.spec test+ Signet.Unstable.Type.VerifierTest.spec test+ Signet.UnstableTest.spec test
source/test-suite/Main.hs view
@@ -1,5 +1,19 @@+import qualified Control.Monad.Trans.Writer as Writer+import qualified Signet.Unstable.Type.Test as Test import qualified SignetTest import qualified Test.Tasty as Tasty+import qualified Test.Tasty.HUnit as Unit main :: IO ()-main = Tasty.defaultMain SignetTest.testTree+main = Tasty.defaultMain testTree++testTree :: Tasty.TestTree+testTree = Tasty.testGroup "signet" . Writer.execWriter $ SignetTest.spec tasty++tasty :: Test.Test (Writer.Writer [Tasty.TestTree])+tasty =+ Test.MkTest+ { Test.assertFailure = Unit.assertFailure,+ Test.describe = \x -> Writer.tell . pure . Tasty.testGroup x . Writer.execWriter,+ Test.it = \x -> Writer.tell . pure . Unit.testCase x+ }