Correct openapi ignore mode to filter schemas
Also rename openapi-mode options * follow-acl -> follow-privileges * ignore-acl -> ignore-privileges
This commit is contained in:
committed by
Steve Chavez
parent
41d119b19f
commit
f3a184af01
+1
-1
@@ -179,7 +179,7 @@ test-suite spec
|
|||||||
Feature.ExtraSearchPathSpec
|
Feature.ExtraSearchPathSpec
|
||||||
Feature.HtmlRawOutputSpec
|
Feature.HtmlRawOutputSpec
|
||||||
Feature.InsertSpec
|
Feature.InsertSpec
|
||||||
Feature.IgnoreAclOpenApiSpec
|
Feature.IgnorePrivOpenApiSpec
|
||||||
Feature.JsonOperatorSpec
|
Feature.JsonOperatorSpec
|
||||||
Feature.MultipleSchemaSpec
|
Feature.MultipleSchemaSpec
|
||||||
Feature.NoJwtSpec
|
Feature.NoJwtSpec
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import System.Posix.Types (FileMode)
|
|||||||
|
|
||||||
import qualified Data.ByteString.Char8 as BS8
|
import qualified Data.ByteString.Char8 as BS8
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
|
import qualified Data.HashMap.Strict as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Hasql.DynamicStatements.Snippet as SQL
|
import qualified Hasql.DynamicStatements.Snippet as SQL
|
||||||
import qualified Hasql.Pool as SQL
|
import qualified Hasql.Pool as SQL
|
||||||
@@ -465,15 +466,15 @@ handleOpenApi :: Bool -> Schema -> RequestContext -> DbHandler Wai.Response
|
|||||||
handleOpenApi headersOnly tSchema (RequestContext conf@AppConfig{..} dbStructure apiRequest _) = do
|
handleOpenApi headersOnly tSchema (RequestContext conf@AppConfig{..} dbStructure apiRequest _) = do
|
||||||
body <-
|
body <-
|
||||||
lift $ case configOpenApiMode of
|
lift $ case configOpenApiMode of
|
||||||
OAFollowACL ->
|
OAFollowPriv ->
|
||||||
OpenAPI.encode conf dbStructure
|
OpenAPI.encode conf dbStructure
|
||||||
<$> SQL.statement tSchema (DbStructure.accessibleTables configDbPreparedStatements)
|
<$> SQL.statement tSchema (DbStructure.accessibleTables configDbPreparedStatements)
|
||||||
<*> SQL.statement tSchema (DbStructure.accessibleProcs configDbPreparedStatements)
|
<*> SQL.statement tSchema (DbStructure.accessibleProcs configDbPreparedStatements)
|
||||||
<*> SQL.statement tSchema (DbStructure.schemaDescription configDbPreparedStatements)
|
<*> SQL.statement tSchema (DbStructure.schemaDescription configDbPreparedStatements)
|
||||||
OAIgnoreACL ->
|
OAIgnorePriv ->
|
||||||
OpenAPI.encode conf dbStructure
|
OpenAPI.encode conf dbStructure
|
||||||
(DbStructure.dbTables dbStructure)
|
(filter (\x -> tableSchema x == tSchema) $ DbStructure.dbTables dbStructure)
|
||||||
(DbStructure.dbProcs dbStructure)
|
(Map.filterWithKey (\(QualifiedIdentifier sch _) _ -> sch == tSchema) $ DbStructure.dbProcs dbStructure)
|
||||||
<$> SQL.statement tSchema (DbStructure.schemaDescription configDbPreparedStatements)
|
<$> SQL.statement tSchema (DbStructure.schemaDescription configDbPreparedStatements)
|
||||||
OADisabled ->
|
OADisabled ->
|
||||||
pure mempty
|
pure mempty
|
||||||
|
|||||||
@@ -192,11 +192,11 @@ exampleConfigFile =
|
|||||||
|## when none is provided, 660 is applied by default
|
|## when none is provided, 660 is applied by default
|
||||||
|# server-unix-socket-mode = "660"
|
|# server-unix-socket-mode = "660"
|
||||||
|
|
|
|
||||||
|## determine if swagger output should follow or ignore ACL constraints or be disabled entirely
|
|## determine if the OpenAPI output should follow or ignore role privileges or be disabled entirely
|
||||||
|## admitted values: follow-acl, ignore-acl, disabled
|
|## admitted values: follow-privileges, ignore-privileges, disabled
|
||||||
|openapi-mode = "follow-acl"
|
|openapi-mode = "follow-privileges"
|
||||||
|
|
|
|
||||||
|## base url for swagger output
|
|## base url for the OpenAPI output
|
||||||
|openapi-server-proxy-uri = ""
|
|openapi-server-proxy-uri = ""
|
||||||
|
|
|
|
||||||
|## choose a secret, JSON Web Key (or set) to enable JWT auth
|
|## choose a secret, JSON Web Key (or set) to enable JWT auth
|
||||||
|
|||||||
@@ -103,13 +103,13 @@ instance Show LogLevel where
|
|||||||
show LogWarn = "warn"
|
show LogWarn = "warn"
|
||||||
show LogInfo = "info"
|
show LogInfo = "info"
|
||||||
|
|
||||||
data OpenAPIMode = OAFollowACL | OAIgnoreACL | OADisabled
|
data OpenAPIMode = OAFollowPriv | OAIgnorePriv | OADisabled
|
||||||
deriving Eq
|
deriving Eq
|
||||||
|
|
||||||
instance Show OpenAPIMode where
|
instance Show OpenAPIMode where
|
||||||
show OAFollowACL = "follow-acl"
|
show OAFollowPriv = "follow-privileges"
|
||||||
show OAIgnoreACL = "ignore-acl"
|
show OAIgnorePriv = "ignore-privileges"
|
||||||
show OADisabled = "disabled"
|
show OADisabled = "disabled"
|
||||||
|
|
||||||
-- | Dump the config
|
-- | Dump the config
|
||||||
toText :: AppConfig -> Text
|
toText :: AppConfig -> Text
|
||||||
@@ -262,11 +262,11 @@ parser optPath env dbSettings =
|
|||||||
parseOpenAPIMode :: C.Key -> C.Parser C.Config OpenAPIMode
|
parseOpenAPIMode :: C.Key -> C.Parser C.Config OpenAPIMode
|
||||||
parseOpenAPIMode k =
|
parseOpenAPIMode k =
|
||||||
optString k >>= \case
|
optString k >>= \case
|
||||||
Nothing -> pure OAFollowACL
|
Nothing -> pure OAFollowPriv
|
||||||
Just "follow-acl" -> pure OAFollowACL
|
Just "follow-privileges" -> pure OAFollowPriv
|
||||||
Just "ignore-acl" -> pure OAIgnoreACL
|
Just "ignore-privileges" -> pure OAIgnorePriv
|
||||||
Just "disabled" -> pure OADisabled
|
Just "disabled" -> pure OADisabled
|
||||||
Just _ -> fail "Invalid openapi-mode. Check your configuration."
|
Just _ -> fail "Invalid openapi-mode. Check your configuration."
|
||||||
|
|
||||||
parseOpenAPIServerProxyURI :: C.Key -> C.Parser C.Config (Maybe Text)
|
parseOpenAPIServerProxyURI :: C.Key -> C.Parser C.Config (Maybe Text)
|
||||||
parseOpenAPIServerProxyURI k =
|
parseOpenAPIServerProxyURI k =
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module Feature.IgnoreAclOpenApiSpec where
|
module Feature.IgnorePrivOpenApiSpec where
|
||||||
|
|
||||||
import Control.Lens ((^?))
|
import Control.Lens ((^?))
|
||||||
|
|
||||||
@@ -32,6 +32,17 @@ spec = describe "OpenAPI Ignore ACL" $ do
|
|||||||
|
|
||||||
liftIO $ tableTag `shouldBe` Just [aesonQQ|"authors_only"|]
|
liftIO $ tableTag `shouldBe` Just [aesonQQ|"authors_only"|]
|
||||||
|
|
||||||
|
it "only includes tables that belong to another schema if the Accept-Profile header is used" $ do
|
||||||
|
r1 <- simpleBody <$> get "/"
|
||||||
|
let tableKey1 = r1 ^? key "paths" . key "/children"
|
||||||
|
|
||||||
|
liftIO $ tableKey1 `shouldBe` Nothing
|
||||||
|
|
||||||
|
r2 <- simpleBody <$> request methodGet "/" [("Accept-Profile", "v1")] ""
|
||||||
|
let tableKey2 = r2 ^? key "paths" . key "/children"
|
||||||
|
|
||||||
|
liftIO $ tableKey2 `shouldNotBe` Nothing
|
||||||
|
|
||||||
describe "RPC" $ do
|
describe "RPC" $ do
|
||||||
|
|
||||||
it "includes privileged function even if user does not have permission" $ do
|
it "includes privileged function even if user does not have permission" $ do
|
||||||
@@ -41,3 +52,14 @@ spec = describe "OpenAPI Ignore ACL" $ do
|
|||||||
. nth 0
|
. nth 0
|
||||||
|
|
||||||
liftIO $ funcTag `shouldBe` Just [aesonQQ|"(rpc) privileged_hello"|]
|
liftIO $ funcTag `shouldBe` Just [aesonQQ|"(rpc) privileged_hello"|]
|
||||||
|
|
||||||
|
it "only includes functions that belong to another schema if the Accept-Profile header is used" $ do
|
||||||
|
r1 <- simpleBody <$> get "/"
|
||||||
|
let funcKey1 = r1 ^? key "paths" . key "/rpc/get_parents_below"
|
||||||
|
|
||||||
|
liftIO $ funcKey1 `shouldBe` Nothing
|
||||||
|
|
||||||
|
r2 <- simpleBody <$> request methodGet "/" [("Accept-Profile", "v1")] ""
|
||||||
|
let funcKey2 = r2 ^? key "paths" . key "/rpc/get_parents_below"
|
||||||
|
|
||||||
|
liftIO $ funcKey2 `shouldNotBe` Nothing
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
module Feature.IgnorePrivOpenApiSpec where
|
||||||
|
|
||||||
|
import Control.Lens ((^?))
|
||||||
|
|
||||||
|
import Data.Aeson.Lens
|
||||||
|
import Data.Aeson.QQ
|
||||||
|
|
||||||
|
import Network.HTTP.Types
|
||||||
|
import Network.Wai (Application)
|
||||||
|
import Network.Wai.Test (SResponse (..))
|
||||||
|
|
||||||
|
import Test.Hspec hiding (pendingWith)
|
||||||
|
import Test.Hspec.Wai
|
||||||
|
|
||||||
|
import Protolude hiding (get)
|
||||||
|
import SpecHelper
|
||||||
|
|
||||||
|
spec :: SpecWith ((), Application)
|
||||||
|
spec = describe "OpenAPI Ignore Privileges" $ do
|
||||||
|
it "root path returns a valid openapi spec" $ do
|
||||||
|
validateOpenApiResponse [("Accept", "application/openapi+json")]
|
||||||
|
request methodHead "/" (acceptHdrs "application/openapi+json") ""
|
||||||
|
`shouldRespondWith` "" { matchStatus = 200 }
|
||||||
|
|
||||||
|
describe "table" $ do
|
||||||
|
|
||||||
|
it "includes privileged table even if user does not have permission" $ do
|
||||||
|
r <- simpleBody <$> get "/"
|
||||||
|
let tableTag = r ^? key "paths" . key "/authors_only"
|
||||||
|
. key "post" . key "tags"
|
||||||
|
. nth 0
|
||||||
|
|
||||||
|
liftIO $ tableTag `shouldBe` Just [aesonQQ|"authors_only"|]
|
||||||
|
|
||||||
|
it "only includes tables that belong to another schema if the Accept-Profile header is used" $ do
|
||||||
|
r1 <- simpleBody <$> get "/"
|
||||||
|
let tableKey1 = r1 ^? key "paths" . key "/children"
|
||||||
|
|
||||||
|
liftIO $ tableKey1 `shouldBe` Nothing
|
||||||
|
|
||||||
|
r2 <- simpleBody <$> request methodGet "/" [("Accept-Profile", "v1")] ""
|
||||||
|
let tableKey2 = r2 ^? key "paths" . key "/children"
|
||||||
|
|
||||||
|
liftIO $ tableKey2 `shouldNotBe` Nothing
|
||||||
|
|
||||||
|
describe "RPC" $ do
|
||||||
|
|
||||||
|
it "includes privileged function even if user does not have permission" $ do
|
||||||
|
r <- simpleBody <$> get "/"
|
||||||
|
let funcTag = r ^? key "paths" . key "/rpc/privileged_hello"
|
||||||
|
. key "post" . key "tags"
|
||||||
|
. nth 0
|
||||||
|
|
||||||
|
liftIO $ funcTag `shouldBe` Just [aesonQQ|"(rpc) privileged_hello"|]
|
||||||
|
|
||||||
|
it "only includes functions that belong to another schema if the Accept-Profile header is used" $ do
|
||||||
|
r1 <- simpleBody <$> get "/"
|
||||||
|
let funcKey1 = r1 ^? key "paths" . key "/rpc/get_parents_below"
|
||||||
|
|
||||||
|
liftIO $ funcKey1 `shouldBe` Nothing
|
||||||
|
|
||||||
|
r2 <- simpleBody <$> request methodGet "/" [("Accept-Profile", "v1")] ""
|
||||||
|
let funcKey2 = r2 ^? key "paths" . key "/rpc/get_parents_below"
|
||||||
|
|
||||||
|
liftIO $ funcKey2 `shouldNotBe` Nothing
|
||||||
+4
-4
@@ -32,7 +32,7 @@ import qualified Feature.DisabledOpenApiSpec
|
|||||||
import qualified Feature.EmbedDisambiguationSpec
|
import qualified Feature.EmbedDisambiguationSpec
|
||||||
import qualified Feature.ExtraSearchPathSpec
|
import qualified Feature.ExtraSearchPathSpec
|
||||||
import qualified Feature.HtmlRawOutputSpec
|
import qualified Feature.HtmlRawOutputSpec
|
||||||
import qualified Feature.IgnoreAclOpenApiSpec
|
import qualified Feature.IgnorePrivOpenApiSpec
|
||||||
import qualified Feature.InsertSpec
|
import qualified Feature.InsertSpec
|
||||||
import qualified Feature.JsonOperatorSpec
|
import qualified Feature.JsonOperatorSpec
|
||||||
import qualified Feature.MultipleSchemaSpec
|
import qualified Feature.MultipleSchemaSpec
|
||||||
@@ -95,7 +95,6 @@ main = do
|
|||||||
let withApp = app testCfg
|
let withApp = app testCfg
|
||||||
maxRowsApp = app testMaxRowsCfg
|
maxRowsApp = app testMaxRowsCfg
|
||||||
disabledOpenApi = app testDisabledOpenApiCfg
|
disabledOpenApi = app testDisabledOpenApiCfg
|
||||||
ignoreAclOpenApi = app testIgnoreAclOpenApiCfg
|
|
||||||
proxyApp = app testProxyCfg
|
proxyApp = app testProxyCfg
|
||||||
noJwtApp = app testCfgNoJWT
|
noJwtApp = app testCfgNoJWT
|
||||||
binaryJwtApp = app testCfgBinaryJWT
|
binaryJwtApp = app testCfgBinaryJWT
|
||||||
@@ -112,6 +111,7 @@ main = do
|
|||||||
unicodeApp = appDbs testUnicodeCfg
|
unicodeApp = appDbs testUnicodeCfg
|
||||||
nonexistentSchemaApp = appDbs testNonexistentSchemaCfg
|
nonexistentSchemaApp = appDbs testNonexistentSchemaCfg
|
||||||
multipleSchemaApp = appDbs testMultipleSchemaCfg
|
multipleSchemaApp = appDbs testMultipleSchemaCfg
|
||||||
|
ignorePrivOpenApi = appDbs testIgnorePrivOpenApiCfg
|
||||||
|
|
||||||
let analyze :: IO ()
|
let analyze :: IO ()
|
||||||
analyze = do
|
analyze = do
|
||||||
@@ -161,8 +161,8 @@ main = do
|
|||||||
describe "Feature.DisabledOpenApiSpec" Feature.DisabledOpenApiSpec.spec
|
describe "Feature.DisabledOpenApiSpec" Feature.DisabledOpenApiSpec.spec
|
||||||
|
|
||||||
-- this test runs with openapi-mode set to ignore-acl
|
-- this test runs with openapi-mode set to ignore-acl
|
||||||
parallel $ before ignoreAclOpenApi $
|
parallel $ before ignorePrivOpenApi $
|
||||||
describe "Feature.IgnoreAclOpenApiSpec" Feature.IgnoreAclOpenApiSpec.spec
|
describe "Feature.IgnorePrivOpenApiSpec" Feature.IgnorePrivOpenApiSpec.spec
|
||||||
|
|
||||||
-- this test runs with a proxy
|
-- this test runs with a proxy
|
||||||
parallel $ before proxyApp $
|
parallel $ before proxyApp $
|
||||||
|
|||||||
+3
-3
@@ -96,7 +96,7 @@ _baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
|||||||
, configJwtSecret = secret
|
, configJwtSecret = secret
|
||||||
, configJwtSecretIsBase64 = False
|
, configJwtSecretIsBase64 = False
|
||||||
, configLogLevel = LogCrit
|
, configLogLevel = LogCrit
|
||||||
, configOpenApiMode = OAFollowACL
|
, configOpenApiMode = OAFollowPriv
|
||||||
, configOpenApiServerProxyUri = Nothing
|
, configOpenApiServerProxyUri = Nothing
|
||||||
, configRawMediaTypes = []
|
, configRawMediaTypes = []
|
||||||
, configServerHost = "localhost"
|
, configServerHost = "localhost"
|
||||||
@@ -128,8 +128,8 @@ testMaxRowsCfg testDbConn = (testCfg testDbConn) { configDbMaxRows = Just 2 }
|
|||||||
testDisabledOpenApiCfg :: Text -> AppConfig
|
testDisabledOpenApiCfg :: Text -> AppConfig
|
||||||
testDisabledOpenApiCfg testDbConn = (testCfg testDbConn) { configOpenApiMode = OADisabled }
|
testDisabledOpenApiCfg testDbConn = (testCfg testDbConn) { configOpenApiMode = OADisabled }
|
||||||
|
|
||||||
testIgnoreAclOpenApiCfg :: Text -> AppConfig
|
testIgnorePrivOpenApiCfg :: Text -> AppConfig
|
||||||
testIgnoreAclOpenApiCfg testDbConn = (testCfg testDbConn) { configOpenApiMode = OAIgnoreACL }
|
testIgnorePrivOpenApiCfg testDbConn = (testCfg testDbConn) { configOpenApiMode = OAIgnorePriv, configDbSchemas = fromList ["test", "v1"] }
|
||||||
|
|
||||||
testProxyCfg :: Text -> AppConfig
|
testProxyCfg :: Text -> AppConfig
|
||||||
testProxyCfg testDbConn = (testCfg testDbConn) { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
testProxyCfg testDbConn = (testCfg testDbConn) { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
||||||
|
|||||||
Vendored
+1
@@ -59,3 +59,4 @@ ALTER ROLE other_authenticator SET pgrst.db_prepared_statements = 'false';
|
|||||||
ALTER ROLE other_authenticator SET pgrst.db_pre_request = 'test.other_custom_headers';
|
ALTER ROLE other_authenticator SET pgrst.db_pre_request = 'test.other_custom_headers';
|
||||||
ALTER ROLE other_authenticator SET pgrst.db_max_rows = '100';
|
ALTER ROLE other_authenticator SET pgrst.db_max_rows = '100';
|
||||||
ALTER ROLE other_authenticator SET pgrst.db_extra_search_path = 'public, extensions, other';
|
ALTER ROLE other_authenticator SET pgrst.db_extra_search_path = 'public, extensions, other';
|
||||||
|
ALTER ROLE other_authenticator SET pgrst.openapi_mode = 'disabled';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"aliased\""
|
|||||||
jwt-secret = ""
|
jwt-secret = ""
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-acl"
|
openapi-mode = "follow-privileges"
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"role\""
|
|||||||
jwt-secret = ""
|
jwt-secret = ""
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-acl"
|
openapi-mode = "follow-privileges"
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"role\""
|
|||||||
jwt-secret = ""
|
jwt-secret = ""
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-acl"
|
openapi-mode = "follow-privileges"
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"role\""
|
|||||||
jwt-secret = ""
|
jwt-secret = ""
|
||||||
jwt-secret-is-base64 = false
|
jwt-secret-is-base64 = false
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-acl"
|
openapi-mode = "follow-privileges"
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"other\".\"role\""
|
|||||||
jwt-secret = "ODERREALLYREALLYREALLYREALLYVERYSAFE"
|
jwt-secret = "ODERREALLYREALLYREALLYREALLYVERYSAFE"
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-acl"
|
openapi-mode = "disabled"
|
||||||
openapi-server-proxy-uri = "https://otherexample.org/api"
|
openapi-server-proxy-uri = "https://otherexample.org/api"
|
||||||
raw-media-types = "application/vnd.pgrst.other-db-config"
|
raw-media-types = "application/vnd.pgrst.other-db-config"
|
||||||
server-host = "0.0.0.0"
|
server-host = "0.0.0.0"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"a\".\"role\""
|
|||||||
jwt-secret = "OVERRIDEREALLYREALLYREALLYREALLYVERYSAFE"
|
jwt-secret = "OVERRIDEREALLYREALLYREALLYREALLYVERYSAFE"
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-acl"
|
openapi-mode = "ignore-privileges"
|
||||||
openapi-server-proxy-uri = "https://example.org/api"
|
openapi-server-proxy-uri = "https://example.org/api"
|
||||||
raw-media-types = "application/vnd.pgrst.db-config"
|
raw-media-types = "application/vnd.pgrst.db-config"
|
||||||
server-host = "0.0.0.0"
|
server-host = "0.0.0.0"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"user\"[0].\"real-role\""
|
|||||||
jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5"
|
jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5"
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-acl"
|
openapi-mode = "ignore-privileges"
|
||||||
openapi-server-proxy-uri = "https://postgrest.org"
|
openapi-server-proxy-uri = "https://postgrest.org"
|
||||||
raw-media-types = "application/vnd.pgrst.config"
|
raw-media-types = "application/vnd.pgrst.config"
|
||||||
server-host = "0.0.0.0"
|
server-host = "0.0.0.0"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".\"role\""
|
|||||||
jwt-secret = ""
|
jwt-secret = ""
|
||||||
jwt-secret-is-base64 = false
|
jwt-secret-is-base64 = false
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-acl"
|
openapi-mode = "follow-privileges"
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ PGRST_JWT_ROLE_CLAIM_KEY: '.user[0]."real-role"'
|
|||||||
PGRST_JWT_SECRET: c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5
|
PGRST_JWT_SECRET: c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5
|
||||||
PGRST_JWT_SECRET_IS_BASE64: true
|
PGRST_JWT_SECRET_IS_BASE64: true
|
||||||
PGRST_LOG_LEVEL: info
|
PGRST_LOG_LEVEL: info
|
||||||
PGRST_OPENAPI_MODE: 'ignore-acl'
|
PGRST_OPENAPI_MODE: 'ignore-privileges'
|
||||||
PGRST_OPENAPI_SERVER_PROXY_URI: 'https://postgrest.org'
|
PGRST_OPENAPI_SERVER_PROXY_URI: 'https://postgrest.org'
|
||||||
PGRST_RAW_MEDIA_TYPES: application/vnd.pgrst.config
|
PGRST_RAW_MEDIA_TYPES: application/vnd.pgrst.config
|
||||||
PGRST_SERVER_HOST: 0.0.0.0
|
PGRST_SERVER_HOST: 0.0.0.0
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jwt-role-claim-key = ".user[0].\"real-role\""
|
|||||||
jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5"
|
jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5"
|
||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-acl"
|
openapi-mode = "ignore-privileges"
|
||||||
openapi-server-proxy-uri = "https://postgrest.org"
|
openapi-server-proxy-uri = "https://postgrest.org"
|
||||||
raw-media-types = "application/vnd.pgrst.config"
|
raw-media-types = "application/vnd.pgrst.config"
|
||||||
server-host = "0.0.0.0"
|
server-host = "0.0.0.0"
|
||||||
|
|||||||
@@ -174,3 +174,8 @@ invalidroleclaimkeys:
|
|||||||
- '.my_role;;domain'
|
- '.my_role;;domain'
|
||||||
- '.#$$%&$%/'
|
- '.#$$%&$%/'
|
||||||
- '1234'
|
- '1234'
|
||||||
|
|
||||||
|
invalidopenapimodes:
|
||||||
|
- 'follow-'
|
||||||
|
- 'ignore-'
|
||||||
|
- '.#$$%&$%/'
|
||||||
|
|||||||
@@ -425,6 +425,21 @@ def test_invalid_role_claim_key(invalidroleclaimkey, defaultenv):
|
|||||||
print(line)
|
print(line)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("invalidopenapimodes", FIXTURES["invalidopenapimodes"])
|
||||||
|
def test_invalid_openapi_mode(invalidopenapimodes, defaultenv):
|
||||||
|
"Given an invalid openapi-mode, Postgrest should exit with a non-zero exit code."
|
||||||
|
env = {
|
||||||
|
**defaultenv,
|
||||||
|
"PGRST_OPENAPI_MODE": invalidopenapimodes,
|
||||||
|
}
|
||||||
|
|
||||||
|
with pytest.raises(PostgrestError):
|
||||||
|
dump = dumpconfig(CONFIGSDIR / "defaults.config", env=env)
|
||||||
|
for line in dump.split("\n"):
|
||||||
|
if line.startswith("openapi-mode"):
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
|
||||||
def test_iat_claim(defaultenv):
|
def test_iat_claim(defaultenv):
|
||||||
"""
|
"""
|
||||||
A claim with an 'iat' (issued at) attribute should be successful.
|
A claim with an 'iat' (issued at) attribute should be successful.
|
||||||
|
|||||||
Reference in New Issue
Block a user