oidc-client-0.4.0.0: src/Web/OIDC/Client/Discovery.hs
{-# LANGUAGE OverloadedStrings #-}
{-|
Module: Web.OIDC.Client.Discovery
Maintainer: krdlab@gmail.com
Stability: experimental
-}
module Web.OIDC.Client.Discovery
(
discover
-- * OpenID Provider Issuers
, google
-- * OpenID Provider Configuration Information
, Provider(..)
, Configuration(..)
) where
import Control.Monad.Catch (catch, throwM)
import Data.Aeson (decode)
import Data.Text (append)
import qualified Jose.Jwk as Jwk
import Network.HTTP.Client (Manager, httpLbs,
responseBody)
import Web.OIDC.Client.Discovery.Issuers (google)
import Web.OIDC.Client.Discovery.Provider (Configuration (..),
Provider (..))
import Web.OIDC.Client.Internal (parseUrl, rethrow)
import Web.OIDC.Client.Types (IssuerLocation,
OpenIdException (..))
-- | This function obtains OpenID Provider configuration and JWK set.
discover
:: IssuerLocation -- ^ OpenID Provider's Issuer location
-> Manager
-> IO Provider
discover location manager = do
conf <- getConfiguration `catch` rethrow
case conf of
Just c -> Provider c . jwks <$> getJwkSetJson (jwksUri c) `catch` rethrow
Nothing -> throwM $ DiscoveryException "failed to decode configuration"
where
getConfiguration = do
req <- parseUrl (location `append` "/.well-known/openid-configuration")
res <- httpLbs req manager
return $ decode $ responseBody res
getJwkSetJson url = do
req <- parseUrl url
res <- httpLbs req manager
return $ responseBody res
jwks j = maybe single Jwk.keys (decode j)
where
single = case decode j of
Just k -> return k
Nothing -> mempty