{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
module Crypto.WebAuthn.Metadata.Service.Types
( MetadataServiceRegistry (..),
MetadataPayload (..),
MetadataEntry (..),
SomeMetadataEntry (..),
StatusReport (..),
ClaimSetSubtype (..),
)
where
import qualified Crypto.JWT as JWT
import qualified Crypto.WebAuthn.Metadata.Service.WebIDL as ServiceIDL
import Crypto.WebAuthn.Metadata.Statement.Types (MetadataStatement)
import qualified Crypto.WebAuthn.Model as M
import Crypto.WebAuthn.Model.Identifier (AAGUID, AuthenticatorIdentifier, SubjectKeyIdentifier)
import qualified Data.Aeson as Aeson
import Data.HashMap.Strict (HashMap)
import Data.Hourglass (Date)
import Data.List.NonEmpty (NonEmpty)
import Data.Singletons (SingI)
import Data.Text (Text)
import Data.Word (Word32)
import qualified Data.X509 as X509
import GHC.Generics (Generic)
data MetadataServiceRegistry = MetadataServiceRegistry
{ MetadataServiceRegistry -> HashMap AAGUID (MetadataEntry 'Fido2)
fido2Entries :: HashMap AAGUID (MetadataEntry 'M.Fido2),
MetadataServiceRegistry
-> HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
fidoU2FEntries :: HashMap SubjectKeyIdentifier (MetadataEntry 'M.FidoU2F)
}
instance Semigroup MetadataServiceRegistry where
MetadataServiceRegistry HashMap AAGUID (MetadataEntry 'Fido2)
l2 HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
lu2f <> :: MetadataServiceRegistry
-> MetadataServiceRegistry -> MetadataServiceRegistry
<> MetadataServiceRegistry HashMap AAGUID (MetadataEntry 'Fido2)
r2 HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
ru2f =
HashMap AAGUID (MetadataEntry 'Fido2)
-> HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
-> MetadataServiceRegistry
MetadataServiceRegistry (HashMap AAGUID (MetadataEntry 'Fido2)
l2 HashMap AAGUID (MetadataEntry 'Fido2)
-> HashMap AAGUID (MetadataEntry 'Fido2)
-> HashMap AAGUID (MetadataEntry 'Fido2)
forall a. Semigroup a => a -> a -> a
<> HashMap AAGUID (MetadataEntry 'Fido2)
r2) (HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
lu2f HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
-> HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
-> HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
forall a. Semigroup a => a -> a -> a
<> HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
ru2f)
instance Monoid MetadataServiceRegistry where
mempty :: MetadataServiceRegistry
mempty = HashMap AAGUID (MetadataEntry 'Fido2)
-> HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
-> MetadataServiceRegistry
MetadataServiceRegistry HashMap AAGUID (MetadataEntry 'Fido2)
forall a. Monoid a => a
mempty HashMap SubjectKeyIdentifier (MetadataEntry 'FidoU2F)
forall a. Monoid a => a
mempty
data MetadataPayload = MetadataPayload
{
:: Maybe Text,
MetadataPayload -> Int
mpNo :: Int,
MetadataPayload -> Date
mpNextUpdate :: Date,
MetadataPayload -> [SomeMetadataEntry]
mpEntries :: [SomeMetadataEntry]
}
data MetadataEntry (p :: M.ProtocolKind) = MetadataEntry
{
forall (p :: ProtocolKind).
MetadataEntry p -> AuthenticatorIdentifier p
meIdentifier :: AuthenticatorIdentifier p,
forall (p :: ProtocolKind).
MetadataEntry p -> Maybe MetadataStatement
meMetadataStatement :: Maybe MetadataStatement,
forall (p :: ProtocolKind).
MetadataEntry p -> NonEmpty StatusReport
meStatusReports :: NonEmpty StatusReport,
forall (p :: ProtocolKind). MetadataEntry p -> Date
meTimeOfLastStatusChange :: Date
}
deriving (MetadataEntry p -> MetadataEntry p -> Bool
(MetadataEntry p -> MetadataEntry p -> Bool)
-> (MetadataEntry p -> MetadataEntry p -> Bool)
-> Eq (MetadataEntry p)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (p :: ProtocolKind).
MetadataEntry p -> MetadataEntry p -> Bool
$c== :: forall (p :: ProtocolKind).
MetadataEntry p -> MetadataEntry p -> Bool
== :: MetadataEntry p -> MetadataEntry p -> Bool
$c/= :: forall (p :: ProtocolKind).
MetadataEntry p -> MetadataEntry p -> Bool
/= :: MetadataEntry p -> MetadataEntry p -> Bool
Eq, Int -> MetadataEntry p -> ShowS
[MetadataEntry p] -> ShowS
MetadataEntry p -> String
(Int -> MetadataEntry p -> ShowS)
-> (MetadataEntry p -> String)
-> ([MetadataEntry p] -> ShowS)
-> Show (MetadataEntry p)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (p :: ProtocolKind). Int -> MetadataEntry p -> ShowS
forall (p :: ProtocolKind). [MetadataEntry p] -> ShowS
forall (p :: ProtocolKind). MetadataEntry p -> String
$cshowsPrec :: forall (p :: ProtocolKind). Int -> MetadataEntry p -> ShowS
showsPrec :: Int -> MetadataEntry p -> ShowS
$cshow :: forall (p :: ProtocolKind). MetadataEntry p -> String
show :: MetadataEntry p -> String
$cshowList :: forall (p :: ProtocolKind). [MetadataEntry p] -> ShowS
showList :: [MetadataEntry p] -> ShowS
Show, (forall x. MetadataEntry p -> Rep (MetadataEntry p) x)
-> (forall x. Rep (MetadataEntry p) x -> MetadataEntry p)
-> Generic (MetadataEntry p)
forall x. Rep (MetadataEntry p) x -> MetadataEntry p
forall x. MetadataEntry p -> Rep (MetadataEntry p) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (p :: ProtocolKind) x.
Rep (MetadataEntry p) x -> MetadataEntry p
forall (p :: ProtocolKind) x.
MetadataEntry p -> Rep (MetadataEntry p) x
$cfrom :: forall (p :: ProtocolKind) x.
MetadataEntry p -> Rep (MetadataEntry p) x
from :: forall x. MetadataEntry p -> Rep (MetadataEntry p) x
$cto :: forall (p :: ProtocolKind) x.
Rep (MetadataEntry p) x -> MetadataEntry p
to :: forall x. Rep (MetadataEntry p) x -> MetadataEntry p
Generic)
deriving instance Aeson.ToJSON (MetadataEntry p)
data SomeMetadataEntry = forall p. (SingI p) => SomeMetadataEntry (MetadataEntry p)
data StatusReport = StatusReport
{
StatusReport -> AuthenticatorStatus
srStatus :: ServiceIDL.AuthenticatorStatus,
StatusReport -> Maybe Date
srEffectiveDate :: Maybe Date,
StatusReport -> Maybe Word32
srAuthenticatorVersion :: Maybe Word32,
StatusReport -> Maybe SignedCertificate
srCertificate :: Maybe X509.SignedCertificate,
StatusReport -> Maybe Text
srUrl :: Maybe Text,
StatusReport -> Maybe Text
srCertificationDescriptor :: Maybe Text,
StatusReport -> Maybe Text
srCertificateNumber :: Maybe Text,
StatusReport -> Maybe Text
srCertificationPolicyVersion :: Maybe Text,
StatusReport -> Maybe Text
srCertificationRequirementsVersion :: Maybe Text
}
deriving (StatusReport -> StatusReport -> Bool
(StatusReport -> StatusReport -> Bool)
-> (StatusReport -> StatusReport -> Bool) -> Eq StatusReport
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StatusReport -> StatusReport -> Bool
== :: StatusReport -> StatusReport -> Bool
$c/= :: StatusReport -> StatusReport -> Bool
/= :: StatusReport -> StatusReport -> Bool
Eq, Int -> StatusReport -> ShowS
[StatusReport] -> ShowS
StatusReport -> String
(Int -> StatusReport -> ShowS)
-> (StatusReport -> String)
-> ([StatusReport] -> ShowS)
-> Show StatusReport
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StatusReport -> ShowS
showsPrec :: Int -> StatusReport -> ShowS
$cshow :: StatusReport -> String
show :: StatusReport -> String
$cshowList :: [StatusReport] -> ShowS
showList :: [StatusReport] -> ShowS
Show, (forall x. StatusReport -> Rep StatusReport x)
-> (forall x. Rep StatusReport x -> StatusReport)
-> Generic StatusReport
forall x. Rep StatusReport x -> StatusReport
forall x. StatusReport -> Rep StatusReport x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. StatusReport -> Rep StatusReport x
from :: forall x. StatusReport -> Rep StatusReport x
$cto :: forall x. Rep StatusReport x -> StatusReport
to :: forall x. Rep StatusReport x -> StatusReport
Generic)
deriving instance Aeson.ToJSON StatusReport
data ClaimSetSubtype addData = ClaimSetSubtype
{ forall addData. ClaimSetSubtype addData -> addData
additionalData :: addData,
forall addData. ClaimSetSubtype addData -> ClaimsSet
claimSet :: JWT.ClaimsSet
}
instance (Aeson.FromJSON addData) => Aeson.FromJSON (ClaimSetSubtype addData) where
parseJSON :: Value -> Parser (ClaimSetSubtype addData)
parseJSON = String
-> (Object -> Parser (ClaimSetSubtype addData))
-> Value
-> Parser (ClaimSetSubtype addData)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"ClaimSetSubtype" ((Object -> Parser (ClaimSetSubtype addData))
-> Value -> Parser (ClaimSetSubtype addData))
-> (Object -> Parser (ClaimSetSubtype addData))
-> Value
-> Parser (ClaimSetSubtype addData)
forall a b. (a -> b) -> a -> b
$ \Object
o ->
addData -> ClaimsSet -> ClaimSetSubtype addData
forall addData. addData -> ClaimsSet -> ClaimSetSubtype addData
ClaimSetSubtype
(addData -> ClaimsSet -> ClaimSetSubtype addData)
-> Parser addData -> Parser (ClaimsSet -> ClaimSetSubtype addData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser addData
forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
o)
Parser (ClaimsSet -> ClaimSetSubtype addData)
-> Parser ClaimsSet -> Parser (ClaimSetSubtype addData)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Value -> Parser ClaimsSet
forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Object -> Value
Aeson.Object Object
o)
instance JWT.HasClaimsSet (ClaimSetSubtype a) where
claimsSet :: Lens' (ClaimSetSubtype a) ClaimsSet
claimsSet ClaimsSet -> f ClaimsSet
f ClaimSetSubtype a
s = (ClaimsSet -> ClaimSetSubtype a)
-> f ClaimsSet -> f (ClaimSetSubtype a)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ClaimsSet
cs -> ClaimSetSubtype a
s {claimSet :: ClaimsSet
claimSet = ClaimsSet
cs}) (ClaimsSet -> f ClaimsSet
f (ClaimSetSubtype a -> ClaimsSet
forall addData. ClaimSetSubtype addData -> ClaimsSet
claimSet ClaimSetSubtype a
s))