module Signet.Unstable.Type.SignatureTest where import qualified Control.Monad.Catch as Exception 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 Heck as Test 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.Exception.UnknownSignature as UnknownSignature import qualified Signet.Unstable.Extra.Either as Either import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature import qualified Signet.Unstable.Type.Signature as Signature import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature spec :: (Exception.MonadThrow io, Monad tree) => Test.Test io tree -> tree () spec :: forall (io :: * -> *) (tree :: * -> *). (MonadThrow io, Monad tree) => Test io tree -> tree () spec Test io tree test = Test io tree -> String -> tree () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> n () -> n () Test.describe Test io tree test String "Signet.Unstable.Type.Signature" (tree () -> tree ()) -> tree () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> String -> tree () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> n () -> n () Test.describe Test io tree test String "parse" (tree () -> tree ()) -> tree () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "fails with invalid asymmetric signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "invalid" let result :: Either InvalidSignature (Either UnknownSignature Signature) result = ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse (ByteString -> Either InvalidSignature (Either UnknownSignature Signature)) -> ByteString -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. (a -> b) -> a -> b $ String -> ByteString Ascii.pack String "v1a," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString byteString Test io tree -> Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test Either InvalidSignature (Either UnknownSignature Signature) result (InvalidSignature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. a -> Either a b Left (InvalidAsymmetricSignature -> InvalidSignature InvalidSignature.InvalidAsymmetricSignature (InvalidAsymmetricSignature -> InvalidSignature) -> InvalidAsymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidAsymmetricSignature InvalidAsymmetricSignature.MkInvalidAsymmetricSignature ByteString byteString)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "fails with invalid symmetric signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "invalid" let result :: Either InvalidSignature (Either UnknownSignature Signature) result = ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse (ByteString -> Either InvalidSignature (Either UnknownSignature Signature)) -> ByteString -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. (a -> b) -> a -> b $ String -> ByteString Ascii.pack String "v1," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString byteString Test io tree -> Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test Either InvalidSignature (Either UnknownSignature Signature) result (InvalidSignature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. a -> Either a b Left (InvalidSymmetricSignature -> InvalidSignature InvalidSignature.InvalidSymmetricSignature (InvalidSymmetricSignature -> InvalidSignature) -> InvalidSymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidSymmetricSignature InvalidSymmetricSignature.MkInvalidSymmetricSignature ByteString byteString)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "returns unknown signature with unrecognized prefix" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "unknown" let result :: Either InvalidSignature (Either UnknownSignature Signature) result = ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse ByteString byteString Test io tree -> Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test Either InvalidSignature (Either UnknownSignature Signature) result (Either UnknownSignature Signature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. b -> Either a b Right (UnknownSignature -> Either UnknownSignature Signature forall a b. a -> Either a b Left (UnknownSignature -> Either UnknownSignature Signature) -> UnknownSignature -> Either UnknownSignature Signature forall a b. (a -> b) -> a -> b $ ByteString -> UnknownSignature UnknownSignature.MkUnknownSignature ByteString byteString)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "succeeds with valid asymmetric signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==" signature <- Either CryptoError Signature -> io Signature forall e (m :: * -> *) a. (Exception e, MonadThrow m) => Either e a -> m a Either.throw (Either CryptoError Signature -> io Signature) -> (ByteString -> Either CryptoError Signature) -> ByteString -> io Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . (Signature -> Signature) -> Either CryptoError Signature -> Either CryptoError Signature forall a b. (a -> b) -> Either CryptoError a -> Either CryptoError b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (AsymmetricSignature -> Signature Signature.Asymmetric (AsymmetricSignature -> Signature) -> (Signature -> AsymmetricSignature) -> Signature -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature) (Either CryptoError Signature -> Either CryptoError Signature) -> (ByteString -> Either CryptoError Signature) -> ByteString -> Either CryptoError Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> Either CryptoError Signature forall a. CryptoFailable a -> Either CryptoError a Error.eitherCryptoError (CryptoFailable Signature -> Either CryptoError Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> Either CryptoError Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> io Signature) -> ByteString -> io Signature forall a b. (a -> b) -> a -> b $ String -> ByteString Ascii.pack String "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" Test.assertEq test (Signature.parse byteString) (Right (Right signature)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "succeeds with valid symmetric signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" let signature :: Signature signature = SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signature) -> Digest SHA256 -> Signature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty Test io tree -> Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse ByteString byteString) (Either UnknownSignature Signature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. b -> Either a b Right (Signature -> Either UnknownSignature Signature forall a b. b -> Either a b Right Signature signature)) Test io tree -> String -> tree () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> n () -> n () Test.describe Test io tree test String "render" (tree () -> tree ()) -> tree () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "renders asymmetric signature correctly" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do signature <- Either CryptoError Signature -> io Signature forall e (m :: * -> *) a. (Exception e, MonadThrow m) => Either e a -> m a Either.throw (Either CryptoError Signature -> io Signature) -> (ByteString -> Either CryptoError Signature) -> ByteString -> io Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . (Signature -> Signature) -> Either CryptoError Signature -> Either CryptoError Signature forall a b. (a -> b) -> Either CryptoError a -> Either CryptoError b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (AsymmetricSignature -> Signature Signature.Asymmetric (AsymmetricSignature -> Signature) -> (Signature -> AsymmetricSignature) -> Signature -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature) (Either CryptoError Signature -> Either CryptoError Signature) -> (ByteString -> Either CryptoError Signature) -> ByteString -> Either CryptoError Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> Either CryptoError Signature forall a. CryptoFailable a -> Either CryptoError a Error.eitherCryptoError (CryptoFailable Signature -> Either CryptoError Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> Either CryptoError Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> io Signature) -> ByteString -> io Signature forall a b. (a -> b) -> a -> b $ String -> ByteString Ascii.pack String "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" Test.assertEq test (Signature.render signature) (Ascii.pack "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==") Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "renders symmetric signature correctly" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let signature :: Signature signature = SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signature) -> Digest SHA256 -> Signature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty Test io tree -> ByteString -> ByteString -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (Signature -> ByteString Signature.render Signature signature) (String -> ByteString Ascii.pack String "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")