{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
module Crypto.JOSE.Error
(
runJOSE
, unwrapJOSE
, JOSE(..)
, Error(..)
, AsError(..)
, InvalidNumberOfParts(..), expectedParts, actualParts
, CompactTextError(..)
, CompactDecodeError(..)
, _CompactInvalidNumberOfParts
, _CompactInvalidText
) where
import Numeric.Natural
import Control.Monad.Except (MonadError(..), ExceptT, runExceptT)
import Control.Monad.Trans (MonadIO(liftIO), MonadTrans(lift))
import qualified Crypto.PubKey.RSA as RSA
import Crypto.Error (CryptoError)
import Crypto.Random (MonadRandom(..))
import Control.Lens (Getter, to)
import Control.Lens.TH (makeClassyPrisms, makePrisms)
import qualified Data.Text as T
import qualified Data.Text.Encoding.Error as T
data InvalidNumberOfParts =
InvalidNumberOfParts Natural Natural
deriving (InvalidNumberOfParts -> InvalidNumberOfParts -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InvalidNumberOfParts -> InvalidNumberOfParts -> Bool
$c/= :: InvalidNumberOfParts -> InvalidNumberOfParts -> Bool
== :: InvalidNumberOfParts -> InvalidNumberOfParts -> Bool
$c== :: InvalidNumberOfParts -> InvalidNumberOfParts -> Bool
Eq)
instance Show InvalidNumberOfParts where
show :: InvalidNumberOfParts -> String
show (InvalidNumberOfParts Natural
n Natural
m) =
String
"Expected " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Natural
n forall a. Semigroup a => a -> a -> a
<> String
" parts; got " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Natural
m
expectedParts, actualParts :: Getter InvalidNumberOfParts Natural
expectedParts :: Getter InvalidNumberOfParts Natural
expectedParts = forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to forall a b. (a -> b) -> a -> b
$ \(InvalidNumberOfParts Natural
n Natural
_) -> Natural
n
actualParts :: Getter InvalidNumberOfParts Natural
actualParts = forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to forall a b. (a -> b) -> a -> b
$ \(InvalidNumberOfParts Natural
_ Natural
n) -> Natural
n
data CompactTextError = CompactTextError
Natural
T.UnicodeException
deriving (CompactTextError -> CompactTextError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CompactTextError -> CompactTextError -> Bool
$c/= :: CompactTextError -> CompactTextError -> Bool
== :: CompactTextError -> CompactTextError -> Bool
$c== :: CompactTextError -> CompactTextError -> Bool
Eq)
instance Show CompactTextError where
show :: CompactTextError -> String
show (CompactTextError Natural
n UnicodeException
s) =
String
"Invalid text at part " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Natural
n forall a. Semigroup a => a -> a -> a
<> String
": " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show UnicodeException
s
data CompactDecodeError
= CompactInvalidNumberOfParts InvalidNumberOfParts
| CompactInvalidText CompactTextError
deriving (CompactDecodeError -> CompactDecodeError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CompactDecodeError -> CompactDecodeError -> Bool
$c/= :: CompactDecodeError -> CompactDecodeError -> Bool
== :: CompactDecodeError -> CompactDecodeError -> Bool
$c== :: CompactDecodeError -> CompactDecodeError -> Bool
Eq)
makePrisms ''CompactDecodeError
instance Show CompactDecodeError where
show :: CompactDecodeError -> String
show (CompactInvalidNumberOfParts InvalidNumberOfParts
e) = String
"Invalid number of parts: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show InvalidNumberOfParts
e
show (CompactInvalidText CompactTextError
e) = String
"Invalid text: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show CompactTextError
e
data Error
= AlgorithmNotImplemented
| AlgorithmMismatch String
| KeyMismatch T.Text
| KeySizeTooSmall
| OtherPrimesNotSupported
| RSAError RSA.Error
| CryptoError CryptoError
| CompactDecodeError CompactDecodeError
| JSONDecodeError String
| NoUsableKeys
| JWSCritUnprotected
| JWSNoValidSignatures
| JWSInvalidSignature
| JWSNoSignatures
deriving (Error -> Error -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Error -> Error -> Bool
$c/= :: Error -> Error -> Bool
== :: Error -> Error -> Bool
$c== :: Error -> Error -> Bool
Eq, Int -> Error -> ShowS
[Error] -> ShowS
Error -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Error] -> ShowS
$cshowList :: [Error] -> ShowS
show :: Error -> String
$cshow :: Error -> String
showsPrec :: Int -> Error -> ShowS
$cshowsPrec :: Int -> Error -> ShowS
Show)
makeClassyPrisms ''Error
newtype JOSE e m a = JOSE (ExceptT e m a)
runJOSE :: JOSE e m a -> m (Either e a)
runJOSE :: forall e (m :: * -> *) a. JOSE e m a -> m (Either e a)
runJOSE = forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\(JOSE ExceptT e m a
m) -> ExceptT e m a
m)
unwrapJOSE :: JOSE e m a -> ExceptT e m a
unwrapJOSE :: forall e (m :: * -> *) a. JOSE e m a -> ExceptT e m a
unwrapJOSE (JOSE ExceptT e m a
m) = ExceptT e m a
m
instance (Functor m) => Functor (JOSE e m) where
fmap :: forall a b. (a -> b) -> JOSE e m a -> JOSE e m b
fmap a -> b
f (JOSE ExceptT e m a
ma) = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f ExceptT e m a
ma)
instance (Monad m) => Applicative (JOSE e m) where
pure :: forall a. a -> JOSE e m a
pure = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure
JOSE ExceptT e m (a -> b)
mf <*> :: forall a b. JOSE e m (a -> b) -> JOSE e m a -> JOSE e m b
<*> JOSE ExceptT e m a
ma = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE (ExceptT e m (a -> b)
mf forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ExceptT e m a
ma)
instance (Monad m) => Monad (JOSE e m) where
JOSE ExceptT e m a
ma >>= :: forall a b. JOSE e m a -> (a -> JOSE e m b) -> JOSE e m b
>>= a -> JOSE e m b
f = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE (ExceptT e m a
ma forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e (m :: * -> *) a. JOSE e m a -> ExceptT e m a
unwrapJOSE forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> JOSE e m b
f)
instance MonadTrans (JOSE e) where
lift :: forall (m :: * -> *) a. Monad m => m a -> JOSE e m a
lift = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
instance (Monad m) => MonadError e (JOSE e m) where
throwError :: forall a. e -> JOSE e m a
throwError = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: forall a. JOSE e m a -> (e -> JOSE e m a) -> JOSE e m a
catchError (JOSE ExceptT e m a
m) e -> JOSE e m a
handle = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE (forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError ExceptT e m a
m (forall e (m :: * -> *) a. JOSE e m a -> ExceptT e m a
unwrapJOSE forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> JOSE e m a
handle))
instance (MonadIO m) => MonadIO (JOSE e m) where
liftIO :: forall a. IO a -> JOSE e m a
liftIO = forall e (m :: * -> *) a. ExceptT e m a -> JOSE e m a
JOSE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
instance (MonadRandom m) => MonadRandom (JOSE e m) where
getRandomBytes :: forall byteArray. ByteArray byteArray => Int -> JOSE e m byteArray
getRandomBytes = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) byteArray.
(MonadRandom m, ByteArray byteArray) =>
Int -> m byteArray
getRandomBytes