From ed58511de3ab964035401f8329b6e06ac99ef36b Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sat, 5 Dec 2020 12:52:52 +0100 Subject: [PATCH] feat: renamed config options with prefixes; added aliases for old names * secret-is-base64 -> jwt-secret-is-base64 * role-claim-key -> jwt-role-claim-key * max-rows -> db-max-rows * pre-request -> db-pre-request * root-spec -> db-root-spec * db-schema -> db-schemas This is not a breaking change, because aliases are added as well. refactor: sorted all config keys alphabetically where applicable --- main/Main.hs | 16 +- src/PostgREST/App.hs | 20 +- src/PostgREST/Config.hs | 208 +++++++++--------- src/PostgREST/Middleware.hs | 8 +- test/Main.hs | 4 +- test/SpecHelper.hs | 74 +++---- test/io-tests.sh | 8 +- test/io-tests/configs/aliases.config | 9 + test/io-tests/configs/app-settings.config | 2 +- .../configs/base64-secret-from-file.config | 4 +- test/io-tests/configs/dburi-from-file.config | 2 +- test/io-tests/configs/defaults.config | 2 +- test/io-tests/configs/expected/aliases.config | 24 ++ .../io-tests/configs/expected/defaults.config | 32 +-- .../configs/expected/no-defaults.config | 32 +-- test/io-tests/configs/no-defaults.config | 32 +-- test/io-tests/configs/role-claim-key.config | 4 +- test/io-tests/configs/secret-from-file.config | 4 +- test/io-tests/configs/sigusr2-settings.config | 2 +- test/io-tests/configs/simple.config | 2 +- test/io-tests/configs/unix-socket.config | 2 +- 21 files changed, 268 insertions(+), 223 deletions(-) create mode 100644 test/io-tests/configs/aliases.config create mode 100644 test/io-tests/configs/expected/aliases.config diff --git a/main/Main.hs b/main/Main.hs index 122b158bec..4194c444ce 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -28,7 +28,7 @@ import System.IO (BufferMode (..), hSetBuffering) import PostgREST.App (postgrest) import PostgREST.Config (AppConfig (..), CLI (..), Command (..), - configPoolTimeout', dumpAppConfig, + configDbPoolTimeout', dumpAppConfig, prettyVersion, readCLIShowHelp, readValidateConfig) import PostgREST.DbStructure (getDbStructure, getPgVersion) @@ -68,11 +68,11 @@ main = do -- These are config values that can't be reloaded at runtime. Reloading some of them would imply restarting the web server. let - host = configHost conf - port = configPort conf - maybeSocketAddr = configSocket conf + host = configServerHost conf + port = configServerPort conf + maybeSocketAddr = configServerUnixSocket conf #ifndef mingw32_HOST_OS - socketFileMode = configSocketMode conf + socketFileMode = configServerUnixSocketMode conf #endif dbUri = toS (configDbUri conf) (dbChannelEnabled, dbChannel) = (configDbChannelEnabled conf, toS $ configDbChannel conf) @@ -81,8 +81,8 @@ main = do . setPort port . setServerName (toS $ "postgrest/" <> prettyVersion) $ defaultSettings - poolSize = configPoolSize conf - poolTimeout = configPoolTimeout' conf + poolSize = configDbPoolSize conf + poolTimeout = configDbPoolTimeout' conf logLevel = configLogLevel conf -- create connection pool with the provided settings, returns either a 'Connection' or a 'ConnectionError'. Does not throw. @@ -248,7 +248,7 @@ connectionStatus pool = fillSchemaCache :: P.Pool -> PgVersion -> IORef AppConfig -> IORef (Maybe DbStructure) -> IO () fillSchemaCache pool actualPgVersion refConf refDbStructure = do conf <- readIORef refConf - result <- P.use pool $ HT.transaction HT.ReadCommitted HT.Read $ getDbStructure (toList $ configSchemas conf) (configExtraSearchPath conf) actualPgVersion (configDbPrepared conf) + result <- P.use pool $ HT.transaction HT.ReadCommitted HT.Read $ getDbStructure (toList $ configDbSchemas conf) (configDbExtraSearchPath conf) actualPgVersion (configDbPreparedStatements conf) case result of Left e -> do -- If this error happens it would mean the connection is down again. Improbable because connectionStatus ensured the connection. diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index 9d8bf9197e..ddc50db4e7 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -75,25 +75,25 @@ postgrest logLev refConf refDbStructure pool getTime connWorker = Nothing -> respond . errorResponseFor $ ConnectionLostError Just dbStructure -> do response <- do - let apiReq = userApiRequest (configSchemas conf) (configRootSpec conf) dbStructure req body + let apiReq = userApiRequest (configDbSchemas conf) (configDbRootSpec conf) dbStructure req body case apiReq of Left err -> return . errorResponseFor $ err Right apiRequest -> do -- The jwt must be checked before touching the db. - attempt <- attemptJwtClaims (configJWKS conf) (configJwtAudience conf) (toS $ iJWT apiRequest) time (rightToMaybe $ configRoleClaimKey conf) + attempt <- attemptJwtClaims (configJWKS conf) (configJwtAudience conf) (toS $ iJWT apiRequest) time (rightToMaybe $ configJwtRoleClaimKey conf) case jwtClaims attempt of Left errJwt -> return . errorResponseFor $ errJwt Right claims -> do let authed = containsRole claims - shouldCommit = configTxAllowOverride conf && iPreferTransaction apiRequest == Just Commit - shouldRollback = configTxAllowOverride conf && iPreferTransaction apiRequest == Just Rollback + shouldCommit = configDbTxAllowOverride conf && iPreferTransaction apiRequest == Just Commit + shouldRollback = configDbTxAllowOverride conf && iPreferTransaction apiRequest == Just Rollback preferenceApplied | shouldCommit = addHeadersIfNotIncluded [(hPreferenceApplied, BS.pack (show Commit))] | shouldRollback = addHeadersIfNotIncluded [(hPreferenceApplied, BS.pack (show Rollback))] | otherwise = identity handleReq = do - when (shouldRollback || (configTxRollbackAll conf && not shouldCommit)) HT.condemn + when (shouldRollback || (configDbTxRollbackAll conf && not shouldCommit)) HT.condemn mapResponseHeaders preferenceApplied <$> runPgLocals conf claims (app dbStructure conf) apiRequest dbResp <- P.use pool $ HT.transaction HT.ReadCommitted (txMode apiRequest) handleReq return $ either (errorResponseFor . PgError authed) identity dbResp @@ -320,9 +320,9 @@ app dbStructure conf apiRequest = return $ responseLBS status headers rBody (ActionInspect headersOnly, TargetDefaultSpec tSchema) -> do - let host = configHost conf - port = toInteger $ configPort conf - proxy = pickProxy $ toS <$> configOpenAPIProxyUri conf + let host = configServerHost conf + port = toInteger $ configServerPort conf + proxy = pickProxy $ toS <$> configOpenApiServerProxyUri conf uri Nothing = ("http", host, port, "/") uri (Just Proxy { proxyScheme = s, proxyHost = h, proxyPort = p, proxyPath = b }) = (s, h, p, b) uri' = uri proxy @@ -340,8 +340,8 @@ app dbStructure conf apiRequest = where notFound = responseLBS status404 [] "" - maxRows = configMaxRows conf - prepared = configDbPrepared conf + maxRows = configDbMaxRows conf + prepared = configDbPreparedStatements conf exactCount = iPreferCount apiRequest == Just ExactCount estimatedCount = iPreferCount apiRequest == Just EstimatedCount plannedCount = iPreferCount apiRequest == Just PlannedCount diff --git a/src/PostgREST/Config.hs b/src/PostgREST/Config.hs index bee9d7d06d..066486bc26 100644 --- a/src/PostgREST/Config.hs +++ b/src/PostgREST/Config.hs @@ -22,7 +22,7 @@ module PostgREST.Config ( prettyVersion , CLI (..) , Command (..) , AppConfig (..) - , configPoolTimeout' + , configDbPoolTimeout' , dumpAppConfig , readCLIShowHelp , readValidateConfig @@ -78,46 +78,39 @@ data Command = CmdRun | CmdDumpConfig deriving (Eq) -- | Config file settings for the server data AppConfig = AppConfig { - configDbUri :: Text - , configAnonRole :: Text - , configOpenAPIProxyUri :: Maybe Text - , configSchemas :: NonEmpty Text - , configHost :: Text - , configPort :: Int - , configSocket :: Maybe FilePath - , configSocketMode :: Either Text FileMode - , configDbChannel :: Text - , configDbChannelEnabled :: Bool - - , configJwtSecret :: Maybe B.ByteString - , configJwtSecretIsBase64 :: Bool - , configJwtAudience :: Maybe StringOrURI - - , configPoolSize :: Int - , configPoolTimeout :: Int - , configMaxRows :: Maybe Integer - , configPreReq :: Maybe Text - , configSettings :: [(Text, Text)] - , configRoleClaimKey :: Either Text JSPath - , configExtraSearchPath :: [Text] - - , configRootSpec :: Maybe Text - , configRawMediaTypes :: [B.ByteString] - - , configJWKS :: Maybe JWKSet - - , configLogLevel :: LogLevel - - , configTxRollbackAll :: Bool - , configTxAllowOverride :: Bool - - , configDbPrepared :: Bool + configAppSettings :: [(Text, Text)] + , configDbAnonRole :: Text + , configDbChannel :: Text + , configDbChannelEnabled :: Bool + , configDbExtraSearchPath :: [Text] + , configDbMaxRows :: Maybe Integer + , configDbPoolSize :: Int + , configDbPoolTimeout :: Int + , configDbPreRequest :: Maybe Text + , configDbPreparedStatements :: Bool + , configDbRootSpec :: Maybe Text + , configDbSchemas :: NonEmpty Text + , configDbTxAllowOverride :: Bool + , configDbTxRollbackAll :: Bool + , configDbUri :: Text + , configJWKS :: Maybe JWKSet + , configJwtAudience :: Maybe StringOrURI + , configJwtRoleClaimKey :: Either Text JSPath + , configJwtSecret :: Maybe B.ByteString + , configJwtSecretIsBase64 :: Bool + , configLogLevel :: LogLevel + , configOpenApiServerProxyUri :: Maybe Text + , configRawMediaTypes :: [B.ByteString] + , configServerHost :: Text + , configServerPort :: Int + , configServerUnixSocket :: Maybe FilePath + , configServerUnixSocketMode :: Either Text FileMode } deriving (Show) -configPoolTimeout' :: (Fractional a) => AppConfig -> a -configPoolTimeout' = - fromRational . toRational . configPoolTimeout +configDbPoolTimeout' :: (Fractional a) => AppConfig -> a +configDbPoolTimeout' = + fromRational . toRational . configDbPoolTimeout -- | User friendly version number prettyVersion :: Text @@ -179,6 +172,16 @@ readCLIShowHelp = customExecParser parserPrefs opts |## extra schemas to add to the search_path of every request |db-extra-search-path = "public" | + |## limit rows in response + |# db-max-rows = 1000 + | + |## stored proc to exec immediately after auth + |# db-pre-request = "stored_proc_name" + | + |## stored proc that overrides the root "/" spec + |## it must be inside the db-schema + |# db-root-spec = "stored_proc_name" + | |## Notification channel for reloading the schema cache |db-channel = "pgrst" | @@ -219,20 +222,10 @@ readCLIShowHelp = customExecParser parserPrefs opts |## (use "@filename" to load from separate file) |# jwt-secret = "secret_with_at_least_32_characters" |# jwt-aud = "your_audience_claim" - |secret-is-base64 = false + |jwt-secret-is-base64 = false | |## jspath to the role claim key - |role-claim-key = ".role" - | - |## limit rows in response - |# max-rows = 1000 - | - |## stored proc to exec immediately after auth - |# pre-request = "stored_proc_name" - | - |## stored proc that overrides the root "/" spec - |## it must be inside the db-schema - |# root-spec = "stored_proc_name" + |jwt-role-claim-key = ".role" | |## content types to produce raw output |# raw-media-types="image/png, image/jpg" @@ -253,49 +246,49 @@ dumpAppConfig conf = do -- apply conf to all pgrst settings pgrstSettings = (\(k, v) -> (k, v conf)) <$> - [("db-uri", q . configDbUri) - ,("db-schema", q . intercalate "," . toList . configSchemas) - ,("db-anon-role", q . configAnonRole) - ,("db-pool", show . configPoolSize) - ,("db-pool-timeout", show . configPoolTimeout) - ,("db-extra-search-path", q . intercalate "," . configExtraSearchPath) + [("db-anon-role", q . configDbAnonRole) ,("db-channel", q . configDbChannel) ,("db-channel-enabled", toLower . show . configDbChannelEnabled) + ,("db-extra-search-path", q . intercalate "," . configDbExtraSearchPath) + ,("db-max-rows", maybe "\"\"" show . configDbMaxRows) + ,("db-pool", show . configDbPoolSize) + ,("db-pool-timeout", show . configDbPoolTimeout) + ,("db-pre-request", q . fromMaybe mempty . configDbPreRequest) + ,("db-prepared-statements", toLower . show . configDbPreparedStatements) + ,("db-root-spec", q . fromMaybe mempty . configDbRootSpec) + ,("db-schemas", q . intercalate "," . toList . configDbSchemas) ,("db-tx-end", q . showTxEnd) - ,("db-prepared-statements", toLower . show . configDbPrepared) - ,("server-host", q . configHost) - ,("server-port", show . configPort) - ,("server-unix-socket", q . maybe mempty pack . configSocket) - ,("server-unix-socket-mode", q . pack . showSocketMode) - ,("openapi-server-proxy-uri", q . fromMaybe mempty . configOpenAPIProxyUri) - ,("jwt-secret", q . toS . showJwtSecret) + ,("db-uri", q . configDbUri) ,("jwt-aud", toS . encode . maybe "" toJSON . configJwtAudience) - ,("secret-is-base64", toLower . show . configJwtSecretIsBase64) - ,("role-claim-key", q . intercalate mempty . fmap show . fromRight' . configRoleClaimKey) - ,("max-rows", maybe "\"\"" show . configMaxRows) - ,("pre-request", q . fromMaybe mempty . configPreReq) - ,("root-spec", q . fromMaybe mempty . configRootSpec) - ,("raw-media-types", q . toS . B.intercalate "," . configRawMediaTypes) + ,("jwt-role-claim-key", q . intercalate mempty . fmap show . fromRight' . configJwtRoleClaimKey) + ,("jwt-secret", q . toS . showJwtSecret) + ,("jwt-secret-is-base64", toLower . show . configJwtSecretIsBase64) ,("log-level", q . show . configLogLevel) + ,("openapi-server-proxy-uri", q . fromMaybe mempty . configOpenApiServerProxyUri) + ,("raw-media-types", q . toS . B.intercalate "," . configRawMediaTypes) + ,("server-host", q . configServerHost) + ,("server-port", show . configServerPort) + ,("server-unix-socket", q . maybe mempty pack . configServerUnixSocket) + ,("server-unix-socket-mode", q . pack . showSocketMode) ] -- quote all app.settings - appSettings = second q <$> configSettings conf + appSettings = second q <$> configAppSettings conf -- quote strings and replace " with \" q s = "\"" <> replace "\"" "\\\"" s <> "\"" - showTxEnd c = case (configTxRollbackAll c, configTxAllowOverride c) of + showTxEnd c = case (configDbTxRollbackAll c, configDbTxAllowOverride c) of ( False, False ) -> "commit" ( False, True ) -> "commit-allow-override" ( True , False ) -> "rollback" ( True , True ) -> "rollback-allow-override" - showSocketMode c = showOct (fromRight' $ configSocketMode c) "" showJwtSecret c | configJwtSecretIsBase64 c = B64.encode secret | otherwise = toS secret where secret = fromMaybe mempty $ configJwtSecret c + showSocketMode c = showOct (fromRight' $ configServerUnixSocketMode c) "" -- | Parse the config file readAppConfig :: FilePath -> IO AppConfig @@ -315,33 +308,40 @@ readAppConfig cfgPath = do where parseConfig = AppConfig - <$> reqString "db-uri" + <$> (fmap (fmap coerceText) <$> C.subassocs "app.settings" C.value) <*> reqString "db-anon-role" - <*> optString "openapi-server-proxy-uri" - <*> (fromList . splitOnCommas <$> reqValue "db-schema") - <*> (fromMaybe "!4" <$> optString "server-host") - <*> (fromMaybe 3000 <$> optInt "server-port") - <*> (fmap unpack <$> optString "server-unix-socket") - <*> parseSocketFileMode "server-unix-socket-mode" <*> (fromMaybe "pgrst" <$> optString "db-channel") <*> (fromMaybe False <$> optBool "db-channel-enabled") - <*> (fmap encodeUtf8 <$> optString "jwt-secret") - <*> (fromMaybe False <$> optBool "secret-is-base64") - <*> parseJwtAudience "jwt-aud" + <*> (maybe ["public"] splitOnCommas <$> optValue "db-extra-search-path") + <*> optWithAlias (optInt "db-max-rows") + (optInt "max-rows") <*> (fromMaybe 10 <$> optInt "db-pool") <*> (fromMaybe 10 <$> optInt "db-pool-timeout") - <*> optInt "max-rows" - <*> optString "pre-request" - <*> (fmap (fmap coerceText) <$> C.subassocs "app.settings" C.value) - <*> (maybe (Right [JSPKey "role"]) parseRoleClaimKey <$> optValue "role-claim-key") - <*> (maybe ["public"] splitOnCommas <$> optValue "db-extra-search-path") - <*> optString "root-spec" - <*> (maybe [] (fmap encodeUtf8 . splitOnCommas) <$> optValue "raw-media-types") + <*> optWithAlias (optString "db-pre-request") + (optString "pre-request") + <*> (fromMaybe True <$> optBool "db-prepared-statements") + <*> optWithAlias (optString "db-root-spec") + (optString "root-spec") + <*> (fromList . splitOnCommas <$> reqWithAlias (optValue "db-schemas") + (optValue "db-schema") + "missing key: either db-schemas or db-schema must be set") + <*> parseTxEnd "db-tx-end" snd + <*> parseTxEnd "db-tx-end" fst + <*> reqString "db-uri" <*> pure Nothing + <*> parseJwtAudience "jwt-aud" + <*> (maybe (Right [JSPKey "role"]) parseRoleClaimKey <$> optWithAlias (optValue "jwt-role-claim-key") + (optValue "role-claim-key")) + <*> (fmap encodeUtf8 <$> optString "jwt-secret") + <*> (fromMaybe False <$> optWithAlias (optBool "jwt-secret-is-base64") + (optBool "secret-is-base64")) <*> parseLogLevel "log-level" - <*> parseTxEnd "db-tx-end" fst - <*> parseTxEnd "db-tx-end" snd - <*> (fromMaybe True <$> optBool "db-prepared-statements") + <*> optString "openapi-server-proxy-uri" + <*> (maybe [] (fmap encodeUtf8 . splitOnCommas) <$> optValue "raw-media-types") + <*> (fromMaybe "!4" <$> optString "server-host") + <*> (fromMaybe 3000 <$> optInt "server-port") + <*> (fmap unpack <$> optString "server-unix-socket") + <*> parseSocketFileMode "server-unix-socket-mode" parseSocketFileMode :: C.Key -> C.Parser C.Config (Either Text FileMode) parseSocketFileMode k = @@ -388,12 +388,24 @@ readAppConfig cfgPath = do Just "rollback-allow-override" -> pure $ f (True, True) Just _ -> fail "Invalid transaction termination. Check your configuration." + reqWithAlias :: C.Parser C.Config (Maybe a) -> C.Parser C.Config (Maybe a) -> [Char] -> C.Parser C.Config a + reqWithAlias orig alias err = + orig >>= \case + Just v -> pure v + Nothing -> + alias >>= \case + Just v -> pure v + Nothing -> fail err + + optWithAlias :: C.Parser C.Config (Maybe a) -> C.Parser C.Config (Maybe a) -> C.Parser C.Config (Maybe a) + optWithAlias orig alias = + orig >>= \case + Just v -> pure $ Just v + Nothing -> alias + reqString :: C.Key -> C.Parser C.Config Text reqString k = C.required k C.string - reqValue :: C.Key -> C.Parser C.Config C.Value - reqValue k = C.required k C.value - optString :: C.Key -> C.Parser C.Config (Maybe Text) optString k = mfilter (/= "") <$> C.optional k C.string @@ -438,13 +450,13 @@ readValidateConfig :: FilePath -> IO AppConfig readValidateConfig path = do conf <- loadDbUriFile =<< loadSecretFile =<< readAppConfig path -- Checks that the provided proxy uri is formated correctly - when (isMalformedProxyUri $ toS <$> configOpenAPIProxyUri conf) $ + when (isMalformedProxyUri $ toS <$> configOpenApiServerProxyUri conf) $ panic "Malformed proxy uri, a correct example: https://example.com:8443/basePath" -- Checks that the provided jspath is valid - whenLeft (configRoleClaimKey conf) panic + whenLeft (configJwtRoleClaimKey conf) panic -- Check the file mode is valid - whenLeft (configSocketMode conf) panic + whenLeft (configServerUnixSocketMode conf) panic return $ conf { configJWKS = parseSecret <$> configJwtSecret conf} {-| diff --git a/src/PostgREST/Middleware.hs b/src/PostgREST/Middleware.hs index 5e9fc56997..f0c48423e8 100644 --- a/src/PostgREST/Middleware.hs +++ b/src/PostgREST/Middleware.hs @@ -53,14 +53,14 @@ runPgLocals conf claims app req = do headersSql = setLocalQuery "request.header." <$> iHeaders req cookiesSql = setLocalQuery "request.cookie." <$> iCookies req claimsSql = setLocalQuery "request.jwt.claim." <$> [(c,unquoted v) | (c,v) <- M.toList claimsWithRole] - appSettingsSql = setLocalQuery mempty <$> configSettings conf + appSettingsSql = setLocalQuery mempty <$> configAppSettings conf setRoleSql = maybeToList $ (\x -> setLocalQuery mempty ("role", unquoted x)) <$> M.lookup "role" claimsWithRole - setSearchPathSql = setLocalSearchPathQuery (iSchema req : configExtraSearchPath conf) + setSearchPathSql = setLocalSearchPathQuery (iSchema req : configDbExtraSearchPath conf) -- role claim defaults to anon if not specified in jwt claimsWithRole = M.union claims (M.singleton "role" anon) - anon = JSON.String . toS $ configAnonRole conf - preReq = (\f -> "select " <> toS f <> "();") <$> configPreReq conf + anon = JSON.String . toS $ configDbAnonRole conf + preReq = (\f -> "select " <> toS f <> "();") <$> configDbPreRequest conf -- | Log in apache format. Only requests that have a status greater than minStatus are logged. -- | There's no way to filter logs in the apache format on wai-extra: https://hackage.haskell.org/package/wai-extra-3.0.29.2/docs/Network-Wai-Middleware-RequestLogger.html#t:OutputFormat. diff --git a/test/Main.hs b/test/Main.hs index 5bbbdbf230..53bffa3e16 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -63,7 +63,7 @@ main = do actualPgVersion <- either (panic.show) id <$> P.use pool getPgVersion - refDbStructure <- (newIORef . Just) =<< setupDbStructure pool (configSchemas $ testCfg testDbConn) (configExtraSearchPath $ testCfg testDbConn) actualPgVersion + refDbStructure <- (newIORef . Just) =<< setupDbStructure pool (configDbSchemas $ testCfg testDbConn) (configDbExtraSearchPath $ testCfg testDbConn) actualPgVersion let -- For tests that run with the same refDbStructure @@ -73,7 +73,7 @@ main = do -- For tests that run with a different DbStructure(depends on configSchemas) appDbs cfg = do - dbs <- (newIORef . Just) =<< setupDbStructure pool (configSchemas $ cfg testDbConn) (configExtraSearchPath $ cfg testDbConn) actualPgVersion + dbs <- (newIORef . Just) =<< setupDbStructure pool (configDbSchemas $ cfg testDbConn) (configDbExtraSearchPath $ cfg testDbConn) actualPgVersion refConf <- newIORef $ cfg testDbConn return ((), postgrest LogCrit refConf dbs pool getTime $ pure ()) diff --git a/test/SpecHelper.hs b/test/SpecHelper.hs index 4515990d71..e6d24f49fd 100644 --- a/test/SpecHelper.hs +++ b/test/SpecHelper.hs @@ -66,55 +66,55 @@ getEnvVarWithDefault var def = toS <$> _baseCfg :: AppConfig _baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in AppConfig { - configDbUri = mempty - , configAnonRole = "postgrest_test_anonymous" - , configOpenAPIProxyUri = Nothing - , configSchemas = fromList ["test"] - , configHost = "localhost" - , configPort = 3000 - , configSocket = Nothing - , configSocketMode = Right 432 - , configDbChannel = mempty - , configDbChannelEnabled = False - , configJwtSecret = secret - , configJwtSecretIsBase64 = False - , configJwtAudience = Nothing - , configPoolSize = 10 - , configPoolTimeout = 10 - , configMaxRows = Nothing - , configPreReq = Just "test.switch_role" - , configSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ] - , configRoleClaimKey = Right [JSPKey "role"] - , configExtraSearchPath = [] - , configRootSpec = Nothing - , configRawMediaTypes = [] - , configJWKS = parseSecret <$> secret - , configLogLevel = LogCrit - , configTxRollbackAll = True - , configTxAllowOverride = True - , configDbPrepared = True + configAppSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ] + , configDbAnonRole = "postgrest_test_anonymous" + , configDbChannel = mempty + , configDbChannelEnabled = False + , configDbExtraSearchPath = [] + , configDbMaxRows = Nothing + , configDbPoolSize = 10 + , configDbPoolTimeout = 10 + , configDbPreRequest = Just "test.switch_role" + , configDbPreparedStatements = True + , configDbRootSpec = Nothing + , configDbSchemas = fromList ["test"] + , configDbUri = mempty + , configJWKS = parseSecret <$> secret + , configJwtAudience = Nothing + , configJwtRoleClaimKey = Right [JSPKey "role"] + , configJwtSecret = secret + , configJwtSecretIsBase64 = False + , configLogLevel = LogCrit + , configOpenApiServerProxyUri = Nothing + , configRawMediaTypes = [] + , configServerHost = "localhost" + , configServerPort = 3000 + , configServerUnixSocket = Nothing + , configServerUnixSocketMode = Right 432 + , configDbTxAllowOverride = True + , configDbTxRollbackAll = True } testCfg :: Text -> AppConfig testCfg testDbConn = _baseCfg { configDbUri = testDbConn } testCfgDisallowRollback :: Text -> AppConfig -testCfgDisallowRollback testDbConn = (testCfg testDbConn) { configTxRollbackAll = False, configTxAllowOverride = False } +testCfgDisallowRollback testDbConn = (testCfg testDbConn) { configDbTxAllowOverride = False, configDbTxRollbackAll = False } testCfgForceRollback :: Text -> AppConfig -testCfgForceRollback testDbConn = (testCfg testDbConn) { configTxRollbackAll = True, configTxAllowOverride = False } +testCfgForceRollback testDbConn = (testCfg testDbConn) { configDbTxAllowOverride = False, configDbTxRollbackAll = True } testCfgNoJWT :: Text -> AppConfig testCfgNoJWT testDbConn = (testCfg testDbConn) { configJwtSecret = Nothing, configJWKS = Nothing } testUnicodeCfg :: Text -> AppConfig -testUnicodeCfg testDbConn = (testCfg testDbConn) { configSchemas = fromList ["تست"] } +testUnicodeCfg testDbConn = (testCfg testDbConn) { configDbSchemas = fromList ["تست"] } testMaxRowsCfg :: Text -> AppConfig -testMaxRowsCfg testDbConn = (testCfg testDbConn) { configMaxRows = Just 2 } +testMaxRowsCfg testDbConn = (testCfg testDbConn) { configDbMaxRows = Just 2 } testProxyCfg :: Text -> AppConfig -testProxyCfg testDbConn = (testCfg testDbConn) { configOpenAPIProxyUri = Just "https://postgrest.com/openapi.json" } +testProxyCfg testDbConn = (testCfg testDbConn) { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" } testCfgBinaryJWT :: Text -> AppConfig testCfgBinaryJWT testDbConn = @@ -150,22 +150,22 @@ testCfgAsymJWKSet testDbConn = } testNonexistentSchemaCfg :: Text -> AppConfig -testNonexistentSchemaCfg testDbConn = (testCfg testDbConn) { configSchemas = fromList ["nonexistent"] } +testNonexistentSchemaCfg testDbConn = (testCfg testDbConn) { configDbSchemas = fromList ["nonexistent"] } testCfgExtraSearchPath :: Text -> AppConfig -testCfgExtraSearchPath testDbConn = (testCfg testDbConn) { configExtraSearchPath = ["public", "extensions"] } +testCfgExtraSearchPath testDbConn = (testCfg testDbConn) { configDbExtraSearchPath = ["public", "extensions"] } testCfgRootSpec :: Text -> AppConfig -testCfgRootSpec testDbConn = (testCfg testDbConn) { configRootSpec = Just "root"} +testCfgRootSpec testDbConn = (testCfg testDbConn) { configDbRootSpec = Just "root"} testCfgHtmlRawOutput :: Text -> AppConfig testCfgHtmlRawOutput testDbConn = (testCfg testDbConn) { configRawMediaTypes = ["text/html"] } testCfgResponseHeaders :: Text -> AppConfig -testCfgResponseHeaders testDbConn = (testCfg testDbConn) { configPreReq = Just "custom_headers" } +testCfgResponseHeaders testDbConn = (testCfg testDbConn) { configDbPreRequest = Just "custom_headers" } testMultipleSchemaCfg :: Text -> AppConfig -testMultipleSchemaCfg testDbConn = (testCfg testDbConn) { configSchemas = fromList ["v1", "v2"] } +testMultipleSchemaCfg testDbConn = (testCfg testDbConn) { configDbSchemas = fromList ["v1", "v2"] } resetDb :: Text -> IO () resetDb dbConn = loadFixture dbConn "data" diff --git a/test/io-tests.sh b/test/io-tests.sh index 04369191a7..5ff60430e0 100755 --- a/test/io-tests.sh +++ b/test/io-tests.sh @@ -316,17 +316,17 @@ checkDbSchemaReload(){ # wait for the server to start sleep 0.1 done - # add v1 schema to db-schema - replaceConfigValue "db-schema" "test, v1" "$configFile" + # add v1 schema to db-schemas + replaceConfigValue "db-schemas" "test, v1" "$configFile" # reload kill -s SIGUSR2 $pgrPID kill -s SIGUSR1 $pgrPID httpStatus="$(v1SchemaParentsStatus)" if test "$httpStatus" -eq 200 then - ok "db-schema config reloaded with SIGUSR2" + ok "db-schemas config reloaded with SIGUSR2" else - ko "db-schema config not reloaded with SIGUSR2. Got: $httpStatus" + ko "db-schemas config not reloaded with SIGUSR2. Got: $httpStatus" fi pgrStop } diff --git a/test/io-tests/configs/aliases.config b/test/io-tests/configs/aliases.config new file mode 100644 index 0000000000..6a858f333d --- /dev/null +++ b/test/io-tests/configs/aliases.config @@ -0,0 +1,9 @@ +db-anon-role = "required" +db-uri = "required" + +db-schema = "provided_through_alias" +max-rows = 1000 +pre-request = "check_alias" +role-claim-key = ".aliased" +root-spec = "open_alias" +secret-is-base64 = true diff --git a/test/io-tests/configs/app-settings.config b/test/io-tests/configs/app-settings.config index 74965527fc..5556abf84d 100644 --- a/test/io-tests/configs/app-settings.config +++ b/test/io-tests/configs/app-settings.config @@ -1,5 +1,5 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 db-pool-timeout = 1 diff --git a/test/io-tests/configs/base64-secret-from-file.config b/test/io-tests/configs/base64-secret-from-file.config index 00734c573c..ee98162ffa 100644 --- a/test/io-tests/configs/base64-secret-from-file.config +++ b/test/io-tests/configs/base64-secret-from-file.config @@ -1,5 +1,5 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1" @@ -7,4 +7,4 @@ server-port = 49421 # Read secret from a file: /dev/stdin (alias for standard input) jwt-secret = "@/dev/stdin" -secret-is-base64 = true +jwt-secret-is-base64 = true diff --git a/test/io-tests/configs/dburi-from-file.config b/test/io-tests/configs/dburi-from-file.config index fd384e0177..e66b60f0e9 100644 --- a/test/io-tests/configs/dburi-from-file.config +++ b/test/io-tests/configs/dburi-from-file.config @@ -1,5 +1,5 @@ db-uri = "@/dev/stdin" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1" diff --git a/test/io-tests/configs/defaults.config b/test/io-tests/configs/defaults.config index c02668beb7..7936cc34a1 100644 --- a/test/io-tests/configs/defaults.config +++ b/test/io-tests/configs/defaults.config @@ -1,3 +1,3 @@ db-uri = "required" -db-schema = "required" +db-schemas = "required" db-anon-role = "required" diff --git a/test/io-tests/configs/expected/aliases.config b/test/io-tests/configs/expected/aliases.config new file mode 100644 index 0000000000..ee3747d312 --- /dev/null +++ b/test/io-tests/configs/expected/aliases.config @@ -0,0 +1,24 @@ +db-anon-role = "required" +db-channel = "pgrst" +db-channel-enabled = false +db-extra-search-path = "public" +db-max-rows = 1000 +db-pool = 10 +db-pool-timeout = 10 +db-pre-request = "check_alias" +db-prepared-statements = true +db-root-spec = "open_alias" +db-schemas = "provided_through_alias" +db-tx-end = "commit" +db-uri = "required" +jwt-aud = "" +jwt-role-claim-key = ".\"aliased\"" +jwt-secret = "" +jwt-secret-is-base64 = true +log-level = "error" +openapi-server-proxy-uri = "" +raw-media-types = "" +server-host = "!4" +server-port = 3000 +server-unix-socket = "" +server-unix-socket-mode = "660" diff --git a/test/io-tests/configs/expected/defaults.config b/test/io-tests/configs/expected/defaults.config index 6fac248069..80e5b937e9 100644 --- a/test/io-tests/configs/expected/defaults.config +++ b/test/io-tests/configs/expected/defaults.config @@ -1,24 +1,24 @@ -db-uri = "required" -db-schema = "required" db-anon-role = "required" -db-pool = 10 -db-pool-timeout = 10 -db-extra-search-path = "public" db-channel = "pgrst" db-channel-enabled = false -db-tx-end = "commit" +db-extra-search-path = "public" +db-max-rows = "" +db-pool = 10 +db-pool-timeout = 10 +db-pre-request = "" db-prepared-statements = true +db-root-spec = "" +db-schemas = "required" +db-tx-end = "commit" +db-uri = "required" +jwt-aud = "" +jwt-role-claim-key = ".\"role\"" +jwt-secret = "" +jwt-secret-is-base64 = false +log-level = "error" +openapi-server-proxy-uri = "" +raw-media-types = "" server-host = "!4" server-port = 3000 server-unix-socket = "" server-unix-socket-mode = "660" -openapi-server-proxy-uri = "" -jwt-secret = "" -jwt-aud = "" -secret-is-base64 = false -role-claim-key = ".\"role\"" -max-rows = "" -pre-request = "" -root-spec = "" -raw-media-types = "" -log-level = "error" diff --git a/test/io-tests/configs/expected/no-defaults.config b/test/io-tests/configs/expected/no-defaults.config index b8b64f306b..1850156b3c 100644 --- a/test/io-tests/configs/expected/no-defaults.config +++ b/test/io-tests/configs/expected/no-defaults.config @@ -1,26 +1,26 @@ -db-uri = "tmp_db" -db-schema = "multi,tenant,setup" db-anon-role = "root" -db-pool = 1 -db-pool-timeout = 100 -db-extra-search-path = "public,test" db-channel = "postgrest" db-channel-enabled = true -db-tx-end = "rollback-allow-override" +db-extra-search-path = "public,test" +db-max-rows = 1000 +db-pool = 1 +db-pool-timeout = 100 +db-pre-request = "please_run_fast" db-prepared-statements = false +db-root-spec = "openapi_v3" +db-schemas = "multi,tenant,setup" +db-tx-end = "rollback-allow-override" +db-uri = "tmp_db" +jwt-aud = "https://postgrest.org" +jwt-role-claim-key = ".\"user\"[0].\"real-role\"" +jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5" +jwt-secret-is-base64 = true +log-level = "info" +openapi-server-proxy-uri = "https://postgrest.org" +raw-media-types = "application/vnd.pgrst.config" server-host = "0.0.0.0" server-port = 80 server-unix-socket = "/tmp/pgrst_io_test.sock" server-unix-socket-mode = "777" -openapi-server-proxy-uri = "https://postgrest.org" -jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5" -jwt-aud = "https://postgrest.org" -secret-is-base64 = true -role-claim-key = ".\"user\"[0].\"real-role\"" -max-rows = 1000 -pre-request = "please_run_fast" -root-spec = "openapi_v3" -raw-media-types = "application/vnd.pgrst.config" -log-level = "info" app.settings.test = "test" app.settings.test2 = "test" diff --git a/test/io-tests/configs/no-defaults.config b/test/io-tests/configs/no-defaults.config index d02bba036b..5e592d5dc6 100644 --- a/test/io-tests/configs/no-defaults.config +++ b/test/io-tests/configs/no-defaults.config @@ -1,26 +1,26 @@ -db-uri = "tmp_db" -db-schema = "multi, tenant,setup" db-anon-role = "root" -db-pool = 1 -db-pool-timeout = 100 -db-extra-search-path = "public, test" db-channel = "postgrest" db-channel-enabled = true -db-tx-end = "rollback-allow-override" +db-extra-search-path = "public, test" +db-max-rows = 1000 +db-pool = 1 +db-pool-timeout = 100 +db-pre-request = "please_run_fast" db-prepared-statements = false +db-root-spec = "openapi_v3" +db-schemas = "multi, tenant,setup" +db-tx-end = "rollback-allow-override" +db-uri = "tmp_db" +jwt-aud = "https://postgrest.org" +jwt-role-claim-key = ".user[0].\"real-role\"" +jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5" +jwt-secret-is-base64 = true +log-level = "info" +openapi-server-proxy-uri = "https://postgrest.org" +raw-media-types = "application/vnd.pgrst.config" server-host = "0.0.0.0" server-port = 80 server-unix-socket = "/tmp/pgrst_io_test.sock" server-unix-socket-mode = "777" -openapi-server-proxy-uri = "https://postgrest.org" -jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5" -jwt-aud = "https://postgrest.org" -secret-is-base64 = true -role-claim-key = ".user[0].\"real-role\"" -max-rows = 1000 -pre-request = "please_run_fast" -root-spec = "openapi_v3" -raw-media-types = "application/vnd.pgrst.config" -log-level = "info" app.settings.test = "test" app.settings.test2 = "test" diff --git a/test/io-tests/configs/role-claim-key.config b/test/io-tests/configs/role-claim-key.config index fdd2382918..49e20b8c72 100644 --- a/test/io-tests/configs/role-claim-key.config +++ b/test/io-tests/configs/role-claim-key.config @@ -1,8 +1,8 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1" server-port = 49421 -role-claim-key = "$(ROLE_CLAIM_KEY)" +jwt-role-claim-key = "$(ROLE_CLAIM_KEY)" jwt-secret = "reallyreallyreallyreallyverysafe" diff --git a/test/io-tests/configs/secret-from-file.config b/test/io-tests/configs/secret-from-file.config index 241e4fd07d..9c3124fb08 100644 --- a/test/io-tests/configs/secret-from-file.config +++ b/test/io-tests/configs/secret-from-file.config @@ -1,5 +1,5 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1" @@ -7,4 +7,4 @@ server-port = 49421 # Read secret from a file: /dev/stdin (alias for standard input) jwt-secret = "@/dev/stdin" -secret-is-base64 = false +jwt-secret-is-base64 = false diff --git a/test/io-tests/configs/sigusr2-settings.config b/test/io-tests/configs/sigusr2-settings.config index 9cb7797d94..7a14ec7254 100644 --- a/test/io-tests/configs/sigusr2-settings.config +++ b/test/io-tests/configs/sigusr2-settings.config @@ -1,5 +1,5 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1" diff --git a/test/io-tests/configs/simple.config b/test/io-tests/configs/simple.config index b3e6dfbd7f..96ff04df7f 100644 --- a/test/io-tests/configs/simple.config +++ b/test/io-tests/configs/simple.config @@ -1,5 +1,5 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1" diff --git a/test/io-tests/configs/unix-socket.config b/test/io-tests/configs/unix-socket.config index 048f632c6c..48dfb981d9 100644 --- a/test/io-tests/configs/unix-socket.config +++ b/test/io-tests/configs/unix-socket.config @@ -1,5 +1,5 @@ db-uri = "$(POSTGREST_TEST_CONNECTION)" -db-schema = "test" +db-schemas = "test" db-anon-role = "postgrest_test_anonymous" db-pool = 1 server-host = "127.0.0.1"