content: {-# LANGUAGE OverloadedStrings #-}
  
  -- | Miscellaneous end-to-end examples.
  module Examples
    ( spec
    ) where
  
  import Control.Lens (_Right, (&), (?~), (.~))
  import Control.Lens.Extras (is)
  import qualified Data.ByteString.Char8 as BC8
  import qualified Data.PEM as PEM
  import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
  import qualified Data.X509 as X509
  
  import Crypto.JOSE.JWK
  import Crypto.JWT
  
  import Test.Hspec
  
  spec :: Spec
  spec = do
    fromX509VerifySpec
  
  fromX509VerifySpec :: Spec
  fromX509VerifySpec =
    describe "Decode PEM-encoded X509 EC certificate and verify" $ do
      let certs = do
            pems <- PEM.pemParseBS pemEncodedX509
            mapM (X509.decodeSignedCertificate . PEM.pemContent) pems
  
      it "successfully parses the single X509 certificate" $ do
        certs `shouldSatisfy` \case Right [_] -> True; _ -> False
  
      case certs of
        Right [x509] -> do
          let errorOrJWK = fromX509Certificate x509 :: Either JWTError JWK
          it "successfully converts the X509 certificate to a JWK" $
            errorOrJWK `shouldSatisfy` is _Right
  
          it "verifies a token signed using ES256 and matches expected claims" $
            (do
              es256jwk <- errorOrJWK
              jwt <- decodeCompact es256token
              verifyClaimsAt valSettings es256jwk now (jwt :: SignedJWT)) `shouldBe`
            Right expectedClaims
  
        _ -> pure ()
    where
  
    es256token = "eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJFUzI1NiJ9.eyJuYmYiOiAxNDQ0NDc4NDAwLCAiaXNzIjogInh4eCJ9.lArczfN-pIL8oUU-7PU83u-zfXougXBZj6drFeKFsPEoVhy9WAyiZlRshYqjTSXdaw8yw2L-ovt4zTUZb2PWMg"
  
    pemEncodedX509 = BC8.unlines
      [ "-----BEGIN CERTIFICATE-----"
      , "MIIBcDCCARagAwIBAgIJAMZmuGSIfvgzMAoGCCqGSM49BAMCMBMxETAPBgNVBAMM"
      , "CHdoYXRldmVyMB4XDTE4MDgxMDE0Mjg1NFoXDTE4MDkwOTE0Mjg1NFowEzERMA8G"
      , "A1UEAwwId2hhdGV2ZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATPwn3WCEXL"
      , "mjp/bFniDwuwsfu7bASlPae2PyWhqGeWwe23Xlyx+tSqxlkXYe4pZ23BkAAscpGj"
      , "yn5gXHExyDlKo1MwUTAdBgNVHQ4EFgQUElRjSoVgKjUqY5AXz2o74cLzzS8wHwYD"
      , "VR0jBBgwFoAUElRjSoVgKjUqY5AXz2o74cLzzS8wDwYDVR0TAQH/BAUwAwEB/zAK"
      , "BggqhkjOPQQDAgNIADBFAiEA4yQ/88ZrUX68c6kOe9G11u8NUaUzd8pLOtkKhniN"
      , "OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm"
      , "-----END CERTIFICATE-----"
      ]
  
    now = posixSecondsToUTCTime 1588512349
  
    expectedClaims = emptyClaimsSet
      & claimIss ?~ "xxx"
      & claimNbf ?~ NumericDate (posixSecondsToUTCTime 1444478400)
  
    valSettings = defaultJWTValidationSettings (const True)
      & jwtValidationSettingsIssuerPredicate .~ (== "xxx")
  