ServerConfig.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Aftok.ServerConfig where
import Aftok.Config
import Aftok.Currency.Zcash (ZcashdConfig (..))
import Aftok.Snaplet.Users (CaptchaConfig (..))
import Control.Lens
( (^.),
makeLenses,
)
import qualified Data.ByteString.Char8 as C8
import qualified Data.Configurator as C
import qualified Data.Configurator.Types as CT
import qualified Data.List as L
import Filesystem.Path.CurrentOS
( encodeString,
fromText,
)
import qualified Filesystem.Path.CurrentOS as P
import Snap.Core
import qualified Snap.Http.Server.Config as SC
import Snap.Snaplet.PostgresqlSimple
import System.Environment (getEnvironment)
data ServerConfig
= ServerConfig
{ _hostname :: C8.ByteString,
_port :: Int,
_authSiteKey :: P.FilePath,
_cookieTimeout :: Maybe Int,
_pgsConfig :: PGSConfig,
_smtpConfig :: SmtpConfig,
_billingConfig :: BillingConfig,
_templatePath :: P.FilePath,
_staticAssetPath :: P.FilePath,
_recaptchaSecret :: CaptchaConfig,
_zcashdConfig :: ZcashdConfig
}
makeLenses ''ServerConfig
loadServerConfig :: P.FilePath -> IO ServerConfig
loadServerConfig cfgFile = do
env <- getEnvironment
cfg <- C.load [C.Required $ encodeString cfgFile]
let dbEnvCfg = pgsDefaultConfig . C8.pack <$> L.lookup "DATABASE_URL" env
readServerConfig cfg dbEnvCfg
readServerConfig :: CT.Config -> Maybe PGSConfig -> IO ServerConfig
readServerConfig cfg pc =
ServerConfig
<$> C.lookupDefault "localhost" cfg "hostname"
<*> C.lookupDefault 8000 cfg "port"
<*> (fromText <$> C.require cfg "siteKey")
<*> C.lookup cfg "cookieTimeout"
<*> maybe (mkPGSConfig $ C.subconfig "db" cfg) pure pc
<*> readSmtpConfig cfg
<*> (readBillingConfig $ C.subconfig "billing" cfg)
<*> ( fromText
<$> C.lookupDefault
"/opt/aftok/server/templates/"
cfg
"templatePath"
)
<*> ( fromText
<$> C.lookupDefault
"/opt/aftok/server/static/"
cfg
"staticAssetPath"
)
<*> (CaptchaConfig <$> C.require cfg "recaptchaSecret")
<*> (readZcashdConfig $ C.subconfig "zcashd" cfg)
readZcashdConfig :: CT.Config -> IO ZcashdConfig
readZcashdConfig cfg =
ZcashdConfig <$> C.require cfg "rpcHost"
<*> C.require cfg "rpcPort"
<*> C.require cfg "rpcUser"
<*> C.require cfg "rpcPassword"
baseSnapConfig :: ServerConfig -> SC.Config m a -> SC.Config m a
baseSnapConfig qc = SC.setHostname (qc ^. hostname) . SC.setPort (qc ^. port)
-- configuration specific to Snap, commandLineConfig arguments override
-- config file.
snapConfig :: ServerConfig -> IO (SC.Config Snap a)
snapConfig qc = SC.commandLineConfig $ baseSnapConfig qc SC.emptyConfig