diff --git a/postgrest.cabal b/postgrest.cabal index bfe278c4a..af08f499e 100644 --- a/postgrest.cabal +++ b/postgrest.cabal @@ -94,6 +94,7 @@ library , errors , bifunctors + Other-Modules: Paths_postgrest Exposed-Modules: PostgREST.App , PostgREST.Types , PostgREST.Parsers @@ -130,6 +131,7 @@ Test-Suite spec , PostgREST.RangeQuery , Spec , SpecHelper + , Paths_postgrest Build-Depends: base, hspec == 2.1.*, QuickCheck , hspec-wai, hspec-wai-json , hasql, hasql-backend diff --git a/src/PostgREST/Config.hs b/src/PostgREST/Config.hs index 4e2448149..8c762c4f3 100644 --- a/src/PostgREST/Config.hs +++ b/src/PostgREST/Config.hs @@ -1,16 +1,36 @@ -module PostgREST.Config where +{-| +Module : PostgREST.Config +Description : Manages PostgREST configuration options. + +This module provides a helper function to read the command line arguments using the optparse-applicative +and the AppConfig type to store them. +It also can be used to define other middleware configuration that may be delegated to some sort of +external configuration. + +It currently includes a hardcoded CORS policy but this could easly be turned in configurable behaviour if needed. +-} +module PostgREST.Config ( prettyVersion + , readOptions + , corsPolicy + , AppConfig (..) + ) + where import Control.Applicative import qualified Data.ByteString.Char8 as BS import qualified Data.CaseInsensitive as CI +import Data.List (intercalate) import Data.String.Conversions (cs) import Data.Text (strip) +import Data.Version (versionBranch) import Network.Wai import Network.Wai.Middleware.Cors (CorsResourcePolicy (..)) import Options.Applicative hiding (columns) +import Paths_postgrest (version) import Prelude +-- | Data type to store all command line options data AppConfig = AppConfig { configDbName :: String , configDbPort :: Int @@ -23,7 +43,6 @@ data AppConfig = AppConfig { , configSecure :: Bool , configPool :: Int , configV1Schema :: String - , configJwtSecret :: String } @@ -32,7 +51,7 @@ argParser = AppConfig <$> strOption (long "db-name" <> short 'd' <> metavar "NAME" <> help "name of database") <*> option auto (long "db-port" <> short 'P' <> metavar "PORT" <> value 5432 <> help "postgres server port" <> showDefault) <*> strOption (long "db-user" <> short 'U' <> metavar "ROLE" <> help "postgres authenticator role") - <*> strOption (long "db-pass" <> metavar "PASS" <> help "password for authenticator role") + <*> strOption (long "db-pass" <> metavar "PASS" <> value "" <> help "password for authenticator role") <*> strOption (long "db-host" <> metavar "HOST" <> value "localhost" <> help "postgres server hostname" <> showDefault) <*> option auto (long "port" <> short 'p' <> metavar "PORT" <> value 3000 <> help "port number on which to run HTTP server" <> showDefault) @@ -47,6 +66,7 @@ defaultCorsPolicy = CorsResourcePolicy Nothing ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] ["Authorization"] Nothing (Just $ 60*60*24) False False True +-- | CORS policy to be used in by Wai Cors middleware corsPolicy :: Request -> Maybe CorsResourcePolicy corsPolicy req = case lookup "origin" headers of Just origin -> Just defaultCorsPolicy { @@ -63,3 +83,20 @@ corsPolicy req = case lookup "origin" headers of accHeaders = case lookup "access-control-request-headers" headers of Just hdrs -> map (CI.mk . cs . strip . cs) $ BS.split ',' hdrs Nothing -> [] + +-- | User friendly version number +prettyVersion :: String +prettyVersion = intercalate "." $ map show $ versionBranch version + +-- | Function to read and parse options from the command line +readOptions :: IO AppConfig +readOptions = customExecParser parserPrefs opts + where + opts = info (helper <*> argParser) $ + fullDesc + <> progDesc ( + "PostgREST " + <> prettyVersion + <> " / create a REST API to an existing Postgres database" + ) + parserPrefs = prefs showHelpOnError diff --git a/src/PostgREST/Main.hs b/src/PostgREST/Main.hs index bf756e14d..a2787f842 100644 --- a/src/PostgREST/Main.hs +++ b/src/PostgREST/Main.hs @@ -1,7 +1,6 @@ module Main where -import Paths_postgrest (version) import PostgREST.PgStructure import PostgREST.Types import Network.Wai @@ -13,22 +12,21 @@ import PostgREST.Middleware import Control.Monad (unless) import Control.Monad.IO.Class (liftIO) import Data.Functor.Identity -import Data.List (intercalate) +import Data.Monoid ((<>)) import Data.String.Conversions (cs) import Data.Text (Text) -import Data.Version (versionBranch) import qualified Hasql as H import qualified Hasql.Postgres as P import Network.Wai.Handler.Warp hiding (Connection) import Network.Wai.Middleware.RequestLogger (logStdout) -import Options.Applicative hiding (columns) import System.IO (BufferMode (..), hSetBuffering, stderr, stdin, stdout) import PostgREST.Config (AppConfig (..), - argParser) + prettyVersion, + readOptions) isServerVersionSupported :: H.Session P.Postgres IO Bool isServerVersionSupported = do @@ -41,15 +39,7 @@ main = do hSetBuffering stdin LineBuffering hSetBuffering stderr NoBuffering - let opts = info (helper <*> argParser) $ - fullDesc - <> progDesc ( - "PostgREST " - <> prettyVersion - <> " / create a REST API to an existing Postgres database" - ) - parserPrefs = prefs showHelpOnError - conf <- customExecParser parserPrefs opts + conf <- readOptions let port = configPort conf unless (configSecure conf) $ @@ -104,6 +94,3 @@ main = do resOrError <- liftIO $ H.session pool $ H.tx txSettings $ authenticated conf (app dbstructure conf body) req either (respond . errResponse) respond resOrError - - where - prettyVersion = intercalate "." $ map show $ versionBranch version