{-| This module defines the Breve configuration parser and application settings. -} module Breve.Settings ( AppSettings(..) , createEmptyIfMissing , settings ) where import Control.Monad (when) import System.Environment (lookupEnv) import System.Directory (doesFileExist, getXdgDirectory, XdgDirectory(..)) import Data.Text (Text, pack) import Data.Configurator import Data.Monoid import Network.Wai.Handler.WarpTLS (TLSSettings (..), tlsSettingsChain) import Network.TLS (Version (..)) import Network.TLS.Extra (ciphersuite_strong) -- | Breve settings data AppSettings = AppSettings { bindHost :: Text -- ^ the host to bind to , bindPort :: Int -- ^ the port to bind to , bindUrl :: Text -- ^ the url used to reach breve , urlTable :: FilePath -- ^ path where to save the url table , tlsSettings :: TLSSettings -- ^ warp TLS settings } -- | Initialises a file if it doesn't exist createEmptyIfMissing :: FilePath -> IO () createEmptyIfMissing file = do exists <- doesFileExist file when (not exists) (writeFile file "") -- | Configuration file parser settings :: Maybe FilePath -> IO AppSettings settings path = do configPath <- case path of Just path -> return path Nothing -> getXdgDirectory XdgConfig "breve" urlsPath <- getXdgDirectory XdgData "breve" config <- load [Required configPath] host <- lookupDefault "localhost" config "hostname" portnum <- lookupDefault 3000 config "port" urls <- lookupDefault urlsPath config "urltable" cert <- lookupDefault "/usr/share/tls/breve.crt" config "tls.cert" key <- lookupDefault "/usr/share/tls/breve.key" config "tls.key" chain <- lookupDefault [] config "tls.chain" let port = if portnum == 443 then "" else ":" <> pack (show portnum) url = "https://" <> host <> port <> "/" baseURL <- lookupDefault url config "baseurl" createEmptyIfMissing urls return AppSettings { bindHost = host , bindPort = portnum , bindUrl = baseURL , urlTable = urls , tlsSettings = (tlsSettingsChain cert chain key) { tlsAllowedVersions = [TLS12, TLS11] , tlsCiphers = ciphersuite_strong } }