module Network.Wai.Auth.Config
( AuthConfig(..)
, SecretKey(..)
, Service(..)
, FileServer(..)
, ReverseProxy(..)
, encodeKey
, decodeKey
) where
import Data.Aeson
import Data.Aeson.TH (defaultOptions, deriveJSON,
fieldLabelModifier)
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Network.Wai.Auth.Tools (decodeKey, encodeKey,
toLowerUnderscore)
import Web.ClientSession (Key)
data SecretKey
= SecretKeyFile FilePath
| SecretKey Key
data FileServer = FileServer
{ fsRootFolder :: FilePath
, fsRedirectToIndex :: Bool
, fsAddTrailingSlash :: Bool
}
data ReverseProxy = ReverseProxy
{ rpHost :: T.Text
, rpPort :: Int
}
data Service = ServiceFiles FileServer
| ServiceProxy ReverseProxy
data AuthConfig = AuthConfig
{ configAppRoot :: Maybe T.Text
, configAppPort :: Int
, configRequireTls :: Bool
, configSkipAuth :: Bool
, configCookieAge :: Int
, configSecretKey :: SecretKey
, configService :: Service
, configProviders :: Object
}
instance FromJSON AuthConfig where
parseJSON =
withObject "Auth Config Object" $ \obj -> do
configAppRoot <- obj .:? "app_root"
configAppPort <- obj .:? "app_port" .!= 3000
configRequireTls <- (obj .:? "require_tls" .!= False)
configSkipAuth <- obj .:? "skip_auth" .!= False
configCookieAge <- obj .:? "cookie_age" .!= 3600
mSecretKeyB64T <- obj .:? "secret_key"
configSecretKey <-
case mSecretKeyB64T of
Just secretKeyB64T ->
either fail (return . SecretKey) $ decodeKey (encodeUtf8 secretKeyB64T)
Nothing -> SecretKeyFile <$> (obj .:? "secret_key_file" .!= "")
mFileServer <- obj .:? "file_server"
mReverseProxy <- obj .:? "reverse_proxy"
let sErrMsg =
"Either 'file_server' or 'reverse_proxy' is required, but not both."
configService <-
case (mFileServer, mReverseProxy) of
(Just fileServer, Nothing) -> ServiceFiles <$> parseJSON fileServer
(Nothing, Just reverseProxy) ->
ServiceProxy <$> parseJSON reverseProxy
(Just _, Just _) -> fail $ "Too many services. " ++ sErrMsg
(Nothing, Nothing) -> fail $ "No service is supplied. " ++ sErrMsg
configProviders <- obj .: "providers"
return AuthConfig {..}
$(deriveJSON defaultOptions { fieldLabelModifier = toLowerUnderscore . drop 2} ''FileServer)
$(deriveJSON defaultOptions { fieldLabelModifier = toLowerUnderscore . drop 2} ''ReverseProxy)