diff --git a/CHANGELOG.md b/CHANGELOG.md index f976e1e3f..7dc6b01c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #1988, Add the current user to the request log on stdout - @DavidLindbom, @wolfgangwalther - #1991, Add the ability to run without `db-uri` using libpq's PG environment variables to connect. @wolfgangwalther - #1769, Add the ability to run without `db-schemas`, defaulting to `db-schemas=public`. @wolfgangwalther + - #1689, Add the ability to run without `db-anon-role` disabling anonymous access. @wolfgangwalther ### Fixed diff --git a/nix/tools/loadtest.nix b/nix/tools/loadtest.nix index 8b7840c46..0f097a113 100644 --- a/nix/tools/loadtest.nix +++ b/nix/tools/loadtest.nix @@ -46,6 +46,7 @@ let } '' # previously required settings to make this work with older branches + export PGRST_DB_ANON_ROLE="postgrest_test_anonymous" export PGRST_DB_URI="postgresql://" export PGRST_DB_SCHEMAS="test" diff --git a/nix/tools/withTools.nix b/nix/tools/withTools.nix index a3c4ed2d6..736ccb9b1 100644 --- a/nix/tools/withTools.nix +++ b/nix/tools/withTools.nix @@ -25,7 +25,6 @@ let "ARG_USE_ENV([PGUSER], [postgrest_test_authenticator], [Authenticator PG role])" "ARG_USE_ENV([PGDATABASE], [postgres], [PG database name])" "ARG_USE_ENV([PGRST_DB_SCHEMAS], [test], [Schema to expose])" - "ARG_USE_ENV([PGRST_DB_ANON_ROLE], [postgrest_test_anonymous], [Anonymous PG role])" ]; positionalCompletion = "_command"; inRootDir = true; @@ -54,7 +53,6 @@ let export PGUSER export PGDATABASE export PGRST_DB_SCHEMAS - export PGRST_DB_ANON_ROLE log "Initializing database cluster..." # We try to make the database cluster as independent as possible from the host diff --git a/postgrest.cabal b/postgrest.cabal index bf82f8fc6..daeab9556 100644 --- a/postgrest.cabal +++ b/postgrest.cabal @@ -185,6 +185,7 @@ test-suite spec Feature.JsonOperatorSpec Feature.LegacyGucsSpec Feature.MultipleSchemaSpec + Feature.NoAnonSpec Feature.NoJwtSpec Feature.NonexistentSchemaSpec Feature.OpenApiSpec diff --git a/src/PostgREST/App.hs b/src/PostgREST/App.hs index 9e0ddb9c8..a100e26b4 100644 --- a/src/PostgREST/App.hs +++ b/src/PostgREST/App.hs @@ -208,7 +208,7 @@ postgrestResponse conf@AppConfig{..} maybeDbStructure jsonDbS pgVer pool AuthRes let handleReq apiReq = handleRequest $ RequestContext conf dbStructure apiReq pgVer - runDbHandler pool (txMode apiRequest) (authRole /= configDbAnonRole) configDbPreparedStatements . + runDbHandler pool (txMode apiRequest) (Just authRole /= configDbAnonRole) configDbPreparedStatements . Middleware.optionalRollback conf apiRequest $ Middleware.runPgLocals conf authClaims authRole handleReq apiRequest jsonDbS pgVer diff --git a/src/PostgREST/Auth.hs b/src/PostgREST/Auth.hs index 0b1482698..093300d01 100644 --- a/src/PostgREST/Auth.hs +++ b/src/PostgREST/Auth.hs @@ -32,7 +32,7 @@ import qualified Network.Wai.Middleware.HttpAuth as Wai import Control.Lens (set) import Control.Monad.Except (liftEither) -import Data.Either.Combinators (mapLeft, mapRight) +import Data.Either.Combinators (mapLeft) import Data.List (lookup) import Data.Time.Clock (UTCTime) import System.IO.Unsafe (unsafePerformIO) @@ -71,16 +71,17 @@ parseToken AppConfig{..} token time = do jwtClaimsError JWT.JWTExpired = JwtTokenInvalid "JWT expired" jwtClaimsError e = JwtTokenInvalid $ show e -parseClaims :: AppConfig -> JSON.Value -> AuthResult -parseClaims AppConfig{..} jclaims@(JSON.Object mclaims) = - AuthResult - { authClaims = mclaims & M.insert "role" (JSON.toJSON role) - , authRole = role - } +parseClaims :: Monad m => + AppConfig -> JSON.Value -> ExceptT Error m AuthResult +parseClaims AppConfig{..} jclaims@(JSON.Object mclaims) = do + -- role defaults to anon if not specified in jwt + role <- liftEither . maybeToRight JwtTokenRequired $ + unquoted <$> walkJSPath (Just jclaims) configJwtRoleClaimKey <|> configDbAnonRole + return AuthResult + { authClaims = mclaims & M.insert "role" (JSON.toJSON role) + , authRole = role + } where - -- role defaults to anon if not specified in jwt - role = maybe configDbAnonRole unquoted (walkJSPath (Just jclaims) configJwtRoleClaimKey) - walkJSPath :: Maybe JSON.Value -> JSPath -> Maybe JSON.Value walkJSPath x [] = x walkJSPath (Just (JSON.Object o)) (JSPKey key:rest) = walkJSPath (M.lookup key o) rest @@ -91,7 +92,7 @@ parseClaims AppConfig{..} jclaims@(JSON.Object mclaims) = unquoted (JSON.String t) = t unquoted v = T.decodeUtf8 . LBS.toStrict $ JSON.encode v -- impossible case - just added to please -Wincomplete-patterns -parseClaims _ _ = AuthResult { authClaims = M.empty, authRole = mempty } +parseClaims _ _ = return AuthResult { authClaims = M.empty, authRole = mempty } -- | Validate authorization header. -- Parse and store JWT claims for future use in the request. @@ -101,11 +102,11 @@ middleware appState app req respond = do time <- getTime appState let token = fromMaybe "" $ Wai.extractBearerAuth =<< lookup HTTP.hAuthorization (Wai.requestHeaders req) - claims <- runExceptT $ parseToken conf (LBS.fromStrict token) time + authResult <- runExceptT $ + parseToken conf (LBS.fromStrict token) time >>= + parseClaims conf - let - authResult = mapRight (parseClaims conf) claims - req' = req { Wai.vault = Wai.vault req & Vault.insert authResultKey authResult } + let req' = req { Wai.vault = Wai.vault req & Vault.insert authResultKey authResult } app req' respond authResultKey :: Vault.Key (Either Error AuthResult) diff --git a/src/PostgREST/Config.hs b/src/PostgREST/Config.hs index d89389f76..278db164b 100644 --- a/src/PostgREST/Config.hs +++ b/src/PostgREST/Config.hs @@ -63,7 +63,7 @@ import Protolude hiding (Proxy, toList) data AppConfig = AppConfig { configAppSettings :: [(Text, Text)] - , configDbAnonRole :: Text + , configDbAnonRole :: Maybe Text , configDbChannel :: Text , configDbChannelEnabled :: Bool , configDbExtraSearchPath :: [Text] @@ -121,7 +121,7 @@ toText conf = where -- apply conf to all pgrst settings pgrstSettings = (\(k, v) -> (k, v conf)) <$> - [("db-anon-role", q . configDbAnonRole) + [("db-anon-role", q . fromMaybe "" . configDbAnonRole) ,("db-channel", q . configDbChannel) ,("db-channel-enabled", T.toLower . show . configDbChannelEnabled) ,("db-extra-search-path", q . T.intercalate "," . configDbExtraSearchPath) @@ -207,7 +207,7 @@ parser :: Maybe FilePath -> Environment -> [(Text, Text)] -> C.Parser C.Config A parser optPath env dbSettings = AppConfig <$> parseAppSettings "app.settings" - <*> reqString "db-anon-role" + <*> optString "db-anon-role" <*> (fromMaybe "pgrst" <$> optString "db-channel") <*> (fromMaybe True <$> optBool "db-channel-enabled") <*> (maybe ["public"] splitOnCommas <$> optValue "db-extra-search-path") @@ -322,9 +322,6 @@ parser optPath env dbSettings = Just v -> pure $ Just v Nothing -> alias - reqString :: C.Key -> C.Parser C.Config Text - reqString k = overrideFromDbOrEnvironment C.required k coerceText - optString :: C.Key -> C.Parser C.Config (Maybe Text) optString k = mfilter (/= "") <$> overrideFromDbOrEnvironment C.optional k coerceText @@ -352,7 +349,7 @@ parser optPath env dbSettings = let dbSettingName = T.pack $ dashToUnderscore <$> toS key in if dbSettingName `notElem` [ "server_host", "server_port", "server_unix_socket", "server_unix_socket_mode", "log_level", - "db_anon_role", "db_uri", "db_channel_enabled", "db_channel", "db_pool", "db_pool_timeout", "db_config"] + "db_uri", "db_channel_enabled", "db_channel", "db_pool", "db_pool_timeout", "db_config"] then lookup dbSettingName dbSettings else Nothing diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs index a150e2be0..c1de45448 100644 --- a/src/PostgREST/Error.hs +++ b/src/PostgREST/Error.hs @@ -274,6 +274,7 @@ data Error | PutRangeNotAllowedError | JwtTokenMissing | JwtTokenInvalid Text + | JwtTokenRequired | SingularityError Integer | NotFound | ApiRequestError ApiRequestError @@ -288,6 +289,7 @@ instance PgrstError Error where status PutRangeNotAllowedError = HTTP.status400 status JwtTokenMissing = HTTP.status500 status (JwtTokenInvalid _) = HTTP.unauthorized401 + status JwtTokenRequired = HTTP.unauthorized401 status (SingularityError _) = HTTP.status406 status NotFound = HTTP.status404 status (PgErr err) = status err @@ -295,6 +297,7 @@ instance PgrstError Error where headers (SingularityError _) = [ContentType.toHeader CTSingularJSON] headers (JwtTokenInvalid m) = [ContentType.toHeader CTApplicationJSON, invalidTokenHeader m] + headers JwtTokenRequired = [ContentType.toHeader CTApplicationJSON, requiredTokenHeader] headers (PgErr err) = headers err headers (ApiRequestError err) = headers err headers _ = [ContentType.toHeader CTApplicationJSON] @@ -322,6 +325,8 @@ instance JSON.ToJSON Error where "message" .= ("Server lacks JWT secret" :: Text)] toJSON (JwtTokenInvalid message) = JSON.object [ "message" .= (message :: Text)] + toJSON JwtTokenRequired = JSON.object [ + "message" .= ("Anonymous access is disabled" :: Text)] toJSON NotFound = JSON.object [] toJSON (PgErr err) = JSON.toJSON err toJSON (ApiRequestError err) = JSON.toJSON err @@ -330,5 +335,8 @@ invalidTokenHeader :: Text -> Header invalidTokenHeader m = ("WWW-Authenticate", "Bearer error=\"invalid_token\", " <> "error_description=" <> encodeUtf8 (show m)) +requiredTokenHeader :: Header +requiredTokenHeader = ("WWW-Authenticate", "Bearer") + singularityError :: (Integral a) => a -> Error singularityError = SingularityError . toInteger diff --git a/test/io/configs/aliases.config b/test/io/configs/aliases.config index 7e83050af..6a9482e87 100644 --- a/test/io/configs/aliases.config +++ b/test/io/configs/aliases.config @@ -1,5 +1,3 @@ -db-anon-role = "required" - db-schema = "provided_through_alias" max-rows = 1000 pre-request = "check_alias" diff --git a/test/io/configs/boolean-numeric.config b/test/io/configs/boolean-numeric.config index c8d9ea3d7..fc0d7f39f 100644 --- a/test/io/configs/boolean-numeric.config +++ b/test/io/configs/boolean-numeric.config @@ -1,5 +1,3 @@ -db-anon-role = "required" - db-channel-enabled = "1" db-prepared-statements = "0" jwt-secret-is-base64 = "2" diff --git a/test/io/configs/boolean-string.config b/test/io/configs/boolean-string.config index dfa222e0c..25b1d27c1 100644 --- a/test/io/configs/boolean-string.config +++ b/test/io/configs/boolean-string.config @@ -1,5 +1,3 @@ -db-anon-role = "required" - db-channel-enabled = "true" db-prepared-statements = "FALSE" jwt-secret-is-base64 = "\"true\"" diff --git a/test/io/configs/defaults.config b/test/io/configs/defaults.config index fa9a3e474..f2cbab203 100644 --- a/test/io/configs/defaults.config +++ b/test/io/configs/defaults.config @@ -1,3 +1,2 @@ -db-anon-role = "required" # Not the default, but only works with PG* variables, which are not set db-config = false diff --git a/test/io/configs/expected/aliases.config b/test/io/configs/expected/aliases.config index 091175fdb..c03f098ef 100644 --- a/test/io/configs/expected/aliases.config +++ b/test/io/configs/expected/aliases.config @@ -1,4 +1,4 @@ -db-anon-role = "required" +db-anon-role = "" db-channel = "pgrst" db-channel-enabled = true db-extra-search-path = "public" diff --git a/test/io/configs/expected/boolean-numeric.config b/test/io/configs/expected/boolean-numeric.config index 94d378e7b..3aa9dc6ae 100644 --- a/test/io/configs/expected/boolean-numeric.config +++ b/test/io/configs/expected/boolean-numeric.config @@ -1,4 +1,4 @@ -db-anon-role = "required" +db-anon-role = "" db-channel = "pgrst" db-channel-enabled = true db-extra-search-path = "public" diff --git a/test/io/configs/expected/boolean-string.config b/test/io/configs/expected/boolean-string.config index 94d378e7b..3aa9dc6ae 100644 --- a/test/io/configs/expected/boolean-string.config +++ b/test/io/configs/expected/boolean-string.config @@ -1,4 +1,4 @@ -db-anon-role = "required" +db-anon-role = "" db-channel = "pgrst" db-channel-enabled = true db-extra-search-path = "public" diff --git a/test/io/configs/expected/defaults.config b/test/io/configs/expected/defaults.config index fa192c3d4..8c1d89675 100644 --- a/test/io/configs/expected/defaults.config +++ b/test/io/configs/expected/defaults.config @@ -1,4 +1,4 @@ -db-anon-role = "required" +db-anon-role = "" db-channel = "pgrst" db-channel-enabled = true db-extra-search-path = "public" diff --git a/test/io/configs/expected/no-defaults-with-db-other-authenticator.config b/test/io/configs/expected/no-defaults-with-db-other-authenticator.config index d94a183bb..5f9d38fb1 100644 --- a/test/io/configs/expected/no-defaults-with-db-other-authenticator.config +++ b/test/io/configs/expected/no-defaults-with-db-other-authenticator.config @@ -1,4 +1,4 @@ -db-anon-role = "postgrest_test_anonymous" +db-anon-role = "other" db-channel = "postgrest" db-channel-enabled = false db-extra-search-path = "public,extensions,other" diff --git a/test/io/configs/expected/no-defaults-with-db.config b/test/io/configs/expected/no-defaults-with-db.config index 06bd6d3f7..40eee3c87 100644 --- a/test/io/configs/expected/no-defaults-with-db.config +++ b/test/io/configs/expected/no-defaults-with-db.config @@ -1,4 +1,4 @@ -db-anon-role = "postgrest_test_anonymous" +db-anon-role = "anonymous" db-channel = "postgrest" db-channel-enabled = false db-extra-search-path = "public,extensions,private" diff --git a/test/io/configs/expected/types.config b/test/io/configs/expected/types.config index b1347acd4..3f2a2b4d2 100644 --- a/test/io/configs/expected/types.config +++ b/test/io/configs/expected/types.config @@ -1,4 +1,4 @@ -db-anon-role = "required" +db-anon-role = "" db-channel = "pgrst" db-channel-enabled = true db-extra-search-path = "public" diff --git a/test/io/configs/types.config b/test/io/configs/types.config index 1719a51cb..3e1981146 100644 --- a/test/io/configs/types.config +++ b/test/io/configs/types.config @@ -1,5 +1,4 @@ # tests how config options fall back with invalid types -db-anon-role = "required" # expects string app.settings.test = false diff --git a/test/io/db_config.sql b/test/io/db_config.sql index 57caf2521..bafcc4918 100644 --- a/test/io/db_config.sql +++ b/test/io/db_config.sql @@ -7,6 +7,7 @@ ALTER ROLE db_config_authenticator SET pgrst.raw_media_types = 'application/vnd. ALTER ROLE db_config_authenticator SET pgrst.jwt_secret = 'REALLY=REALLY=REALLY=REALLY=VERY=SAFE'; ALTER ROLE db_config_authenticator SET pgrst.jwt_secret_is_base64 = 'false'; ALTER ROLE db_config_authenticator SET pgrst.jwt_role_claim_key = '."a"."role"'; +ALTER ROLE db_config_authenticator SET pgrst.db_anon_role = 'anonymous'; ALTER ROLE db_config_authenticator SET pgrst.db_tx_end = 'commit-allow-override'; ALTER ROLE db_config_authenticator SET pgrst.db_schemas = 'test, tenant1, tenant2'; ALTER ROLE db_config_authenticator SET pgrst.db_root_spec = 'root'; @@ -29,7 +30,6 @@ ALTER ROLE db_config_authenticator SET pgrst.server_port = 'ignored'; ALTER ROLE db_config_authenticator SET pgrst.server_unix_socket = 'ignored'; ALTER ROLE db_config_authenticator SET pgrst.server_unix_socket_mode = 'ignored'; ALTER ROLE db_config_authenticator SET pgrst.log_level = 'ignored'; -ALTER ROLE db_config_authenticator SET pgrst.db_anon_role = 'ignored'; ALTER ROLE db_config_authenticator SET pgrst.db_uri = 'postgresql://ignored'; ALTER ROLE db_config_authenticator SET pgrst.db_channel_enabled = 'ignored'; ALTER ROLE db_config_authenticator SET pgrst.db_channel = 'ignored'; @@ -45,6 +45,7 @@ ALTER ROLE other_authenticator SET pgrst.raw_media_types = 'application/vnd.pgrs ALTER ROLE other_authenticator SET pgrst.jwt_secret = 'ODERREALLYREALLYREALLYREALLYVERYSAFE'; ALTER ROLE other_authenticator SET pgrst.jwt_secret_is_base64 = 'true'; ALTER ROLE other_authenticator SET pgrst.jwt_role_claim_key = '."other"."role"'; +ALTER ROLE other_authenticator SET pgrst.db_anon_role = 'other'; ALTER ROLE other_authenticator SET pgrst.db_tx_end = 'rollback-allow-override'; ALTER ROLE other_authenticator SET pgrst.db_schemas = 'test, other_tenant1, other_tenant2'; ALTER ROLE other_authenticator SET pgrst.db_root_spec = 'other_root'; diff --git a/test/io/fixtures.sql b/test/io/fixtures.sql index 4c8a3a3cb..2e95e1131 100644 --- a/test/io/fixtures.sql +++ b/test/io/fixtures.sql @@ -1,6 +1,8 @@ \ir db_config.sql CREATE ROLE postgrest_test_anonymous; +ALTER ROLE :USER SET pgrst.db_anon_role = 'postgrest_test_anonymous'; + CREATE ROLE postgrest_test_author; GRANT postgrest_test_anonymous, postgrest_test_author TO :USER; diff --git a/test/io/fixtures.yaml b/test/io/fixtures.yaml index 8f0dfd489..19e957c91 100644 --- a/test/io/fixtures.yaml +++ b/test/io/fixtures.yaml @@ -23,10 +23,6 @@ cli: - name: invalid config file expect: error args: ['test/io-tests/configs/invalid.yaml'] -# failures: required config options - - name: missing db-anon-role - expect: error - env: # failures: wrong config values - name: invalid server-unix-socket-mode not octal expect: error diff --git a/test/io/test_io.py b/test/io/test_io.py index 589e70a25..a8a592794 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -92,8 +92,7 @@ def defaultenv(): "PGDATABASE": os.environ["PGDATABASE"], "PGHOST": os.environ["PGHOST"], "PGUSER": os.environ["PGUSER"], - "PGRST_DB_ANON_ROLE": os.environ["PGRST_DB_ANON_ROLE"], - "PGRST_DB_CONFIG": "false", + "PGRST_DB_CONFIG": "true", "PGRST_LOG_LEVEL": "info", } @@ -384,6 +383,7 @@ def test_read_secret_from_file(secretpath, defaultenv): with run(stdin=secret, env=env) as postgrest: response = postgrest.session.get("/authors_only", headers=headers) + print(response.text) assert response.status_code == 200 @@ -600,6 +600,8 @@ def test_jwt_secret_external_file_reload(tmp_path, defaultenv): **defaultenv, "PGRST_JWT_SECRET": f"@{external_secret_file}", "PGRST_DB_CHANNEL_ENABLED": "true", + "PGRST_DB_CONFIG": "false", + "PGRST_DB_ANON_ROLE": "postgrest_test_anonymous", # required for NOTIFY } with run(env=env) as postgrest: @@ -609,7 +611,7 @@ def test_jwt_secret_external_file_reload(tmp_path, defaultenv): # change external file external_secret_file.write_text(SECRET) - # SIGUSR1 doesn't reload external files + # SIGUSR1 doesn't reload external files, at least when db-config=false postgrest.process.send_signal(signal.SIGUSR1) time.sleep(0.1) @@ -627,7 +629,8 @@ def test_jwt_secret_external_file_reload(tmp_path, defaultenv): external_secret_file.write_text("invalid" * 5) # reload config and external file with NOTIFY - postgrest.session.post("/rpc/reload_pgrst_config") + response = postgrest.session.post("/rpc/reload_pgrst_config") + assert response.status_code == 200 time.sleep(0.1) response = postgrest.session.get("/authors_only", headers=headers) diff --git a/test/spec/Feature/NoAnonSpec.hs b/test/spec/Feature/NoAnonSpec.hs new file mode 100644 index 000000000..b46adb817 --- /dev/null +++ b/test/spec/Feature/NoAnonSpec.hs @@ -0,0 +1,30 @@ +module Feature.NoAnonSpec where + +import Network.Wai (Application) + +import Network.HTTP.Types +import Test.Hspec +import Test.Hspec.Wai +import Test.Hspec.Wai.JSON + +import Protolude hiding (get) +import SpecHelper + +spec :: SpecWith ((), Application) +spec = describe "server started without anonymous role" $ do + it "behaves normally on attempted auth" $ do + -- token body: { "role": "postgrest_test_author" } + let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIn0.Xod-F15qsGL0WhdOCr2j3DdKuTw9QJERVgoFD3vGaWA" + request methodGet "/authors_only" + [auth] + "" + `shouldRespondWith` + 200 + + it "responds with error when user does not attempt auth" $ + get "/items" + `shouldRespondWith` + [json|{"message":"Anonymous access is disabled"}|] + { matchStatus = 401 + , matchHeaders = ["WWW-Authenticate" <:> "Bearer"] + } diff --git a/test/spec/Main.hs b/test/spec/Main.hs index 625310a5e..f607525ac 100644 --- a/test/spec/Main.hs +++ b/test/spec/Main.hs @@ -37,6 +37,7 @@ import qualified Feature.InsertSpec import qualified Feature.JsonOperatorSpec import qualified Feature.LegacyGucsSpec import qualified Feature.MultipleSchemaSpec +import qualified Feature.NoAnonSpec import qualified Feature.NoJwtSpec import qualified Feature.NonexistentSchemaSpec import qualified Feature.OpenApiSpec @@ -96,6 +97,7 @@ main = do maxRowsApp = app testMaxRowsCfg disabledOpenApi = app testDisabledOpenApiCfg proxyApp = app testProxyCfg + noAnonApp = app testCfgNoAnon noJwtApp = app testCfgNoJWT binaryJwtApp = app testCfgBinaryJWT audJwtApp = app testCfgAudienceJWT @@ -170,6 +172,10 @@ main = do parallel $ before proxyApp $ describe "Feature.ProxySpec" Feature.ProxySpec.spec + -- this test runs without an anonymous role + parallel $ before noAnonApp $ + describe "Feature.NoAnonSpec" Feature.NoAnonSpec.spec + -- this test runs without a JWT secret parallel $ before noJwtApp $ describe "Feature.NoJwtSpec" Feature.NoJwtSpec.spec diff --git a/test/spec/SpecHelper.hs b/test/spec/SpecHelper.hs index 964fdcee8..3412b88bd 100644 --- a/test/spec/SpecHelper.hs +++ b/test/spec/SpecHelper.hs @@ -76,7 +76,7 @@ baseCfg :: AppConfig baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in AppConfig { configAppSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ] - , configDbAnonRole = "postgrest_test_anonymous" + , configDbAnonRole = Just "postgrest_test_anonymous" , configDbChannel = mempty , configDbChannelEnabled = True , configDbExtraSearchPath = [] @@ -118,6 +118,9 @@ testCfgDisallowRollback = baseCfg { configDbTxAllowOverride = False, configDbTxR testCfgForceRollback :: AppConfig testCfgForceRollback = baseCfg { configDbTxAllowOverride = False, configDbTxRollbackAll = True } +testCfgNoAnon :: AppConfig +testCfgNoAnon = baseCfg { configDbAnonRole = Nothing } + testCfgNoJWT :: AppConfig testCfgNoJWT = baseCfg { configJwtSecret = Nothing, configJWKS = Nothing }