Add security definitions to the OpenAPI output
This commit is contained in:
@@ -34,6 +34,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
+ Works for GET, RPC, POST/PATCH/DELETE with `Prefer: return=representation`.
|
+ Works for GET, RPC, POST/PATCH/DELETE with `Prefer: return=representation`.
|
||||||
+ Resource embedding works and the embedded rows will go into the `properties` key
|
+ Resource embedding works and the embedded rows will go into the `properties` key
|
||||||
+ In case of multiple geometries in the same table, you can choose which one will go into the `geometry` key with the usual `?select` query parameter.
|
+ In case of multiple geometries in the same table, you can choose which one will go into the `geometry` key with the usual `?select` query parameter.
|
||||||
|
- #1082, Add security definitions to the OpenAPI output - @laurenceisla
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ test-suite spec
|
|||||||
Feature.OpenApi.OpenApiSpec
|
Feature.OpenApi.OpenApiSpec
|
||||||
Feature.OpenApi.ProxySpec
|
Feature.OpenApi.ProxySpec
|
||||||
Feature.OpenApi.RootSpec
|
Feature.OpenApi.RootSpec
|
||||||
|
Feature.OpenApi.SecurityOpenApiSpec
|
||||||
Feature.OptionsSpec
|
Feature.OptionsSpec
|
||||||
Feature.Query.AndOrParamsSpec
|
Feature.Query.AndOrParamsSpec
|
||||||
Feature.Query.DeleteSpec
|
Feature.Query.DeleteSpec
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ data AppConfig = AppConfig
|
|||||||
, configJwtSecretIsBase64 :: Bool
|
, configJwtSecretIsBase64 :: Bool
|
||||||
, configLogLevel :: LogLevel
|
, configLogLevel :: LogLevel
|
||||||
, configOpenApiMode :: OpenAPIMode
|
, configOpenApiMode :: OpenAPIMode
|
||||||
|
, configOpenApiSecurityActive :: Bool
|
||||||
, configOpenApiServerProxyUri :: Maybe Text
|
, configOpenApiServerProxyUri :: Maybe Text
|
||||||
, configRawMediaTypes :: [MediaType]
|
, configRawMediaTypes :: [MediaType]
|
||||||
, configServerHost :: Text
|
, configServerHost :: Text
|
||||||
@@ -143,6 +144,7 @@ toText conf =
|
|||||||
,("jwt-secret-is-base64", T.toLower . show . configJwtSecretIsBase64)
|
,("jwt-secret-is-base64", T.toLower . show . configJwtSecretIsBase64)
|
||||||
,("log-level", q . dumpLogLevel . configLogLevel)
|
,("log-level", q . dumpLogLevel . configLogLevel)
|
||||||
,("openapi-mode", q . dumpOpenApiMode . configOpenApiMode)
|
,("openapi-mode", q . dumpOpenApiMode . configOpenApiMode)
|
||||||
|
,("openapi-security-active", T.toLower . show . configOpenApiSecurityActive)
|
||||||
,("openapi-server-proxy-uri", q . fromMaybe mempty . configOpenApiServerProxyUri)
|
,("openapi-server-proxy-uri", q . fromMaybe mempty . configOpenApiServerProxyUri)
|
||||||
,("raw-media-types", q . T.decodeUtf8 . BS.intercalate "," . fmap toMime . configRawMediaTypes)
|
,("raw-media-types", q . T.decodeUtf8 . BS.intercalate "," . fmap toMime . configRawMediaTypes)
|
||||||
,("server-host", q . configServerHost)
|
,("server-host", q . configServerHost)
|
||||||
@@ -238,6 +240,7 @@ parser optPath env dbSettings =
|
|||||||
(optBool "secret-is-base64"))
|
(optBool "secret-is-base64"))
|
||||||
<*> parseLogLevel "log-level"
|
<*> parseLogLevel "log-level"
|
||||||
<*> parseOpenAPIMode "openapi-mode"
|
<*> parseOpenAPIMode "openapi-mode"
|
||||||
|
<*> (fromMaybe False <$> optBool "openapi-security-active")
|
||||||
<*> parseOpenAPIServerProxyURI "openapi-server-proxy-uri"
|
<*> parseOpenAPIServerProxyURI "openapi-server-proxy-uri"
|
||||||
<*> (maybe [] (fmap (MTOther . encodeUtf8) . splitOnCommas) <$> optValue "raw-media-types")
|
<*> (maybe [] (fmap (MTOther . encodeUtf8) . splitOnCommas) <$> optValue "raw-media-types")
|
||||||
<*> (fromMaybe "!4" <$> optString "server-host")
|
<*> (fromMaybe "!4" <$> optString "server-host")
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ encode conf dbStructure tables procs schemaDescription =
|
|||||||
(snd <$> HM.toList tables)
|
(snd <$> HM.toList tables)
|
||||||
(proxyUri conf)
|
(proxyUri conf)
|
||||||
schemaDescription
|
schemaDescription
|
||||||
|
(configOpenApiSecurityActive conf)
|
||||||
|
|
||||||
makeMimeList :: [MediaType] -> MimeList
|
makeMimeList :: [MediaType] -> MimeList
|
||||||
makeMimeList cs = MimeList $ fmap (fromString . BS.unpack . toMime) cs
|
makeMimeList cs = MimeList $ fmap (fromString . BS.unpack . toMime) cs
|
||||||
@@ -313,6 +314,14 @@ makePathItems :: [ProcDescription] -> [Table] -> InsOrdHashMap FilePath PathItem
|
|||||||
makePathItems pds ti = fromList $ makeRootPathItem :
|
makePathItems pds ti = fromList $ makeRootPathItem :
|
||||||
fmap makePathItem ti ++ fmap makeProcPathItem pds
|
fmap makePathItem ti ++ fmap makeProcPathItem pds
|
||||||
|
|
||||||
|
makeSecurityDefinitions :: Text -> Bool -> SecurityDefinitions
|
||||||
|
makeSecurityDefinitions secName allow
|
||||||
|
| allow = SecurityDefinitions (fromList [(secName, SecurityScheme secSchType secSchDescription)])
|
||||||
|
| otherwise = mempty
|
||||||
|
where
|
||||||
|
secSchType = SecuritySchemeApiKey (ApiKeyParams "Authorization" ApiKeyHeader)
|
||||||
|
secSchDescription = Just "Add the token prepending \"Bearer \" (without quotes) to it"
|
||||||
|
|
||||||
escapeHostName :: Text -> Text
|
escapeHostName :: Text -> Text
|
||||||
escapeHostName "*" = "0.0.0.0"
|
escapeHostName "*" = "0.0.0.0"
|
||||||
escapeHostName "*4" = "0.0.0.0"
|
escapeHostName "*4" = "0.0.0.0"
|
||||||
@@ -321,8 +330,8 @@ escapeHostName "*6" = "0.0.0.0"
|
|||||||
escapeHostName "!6" = "0.0.0.0"
|
escapeHostName "!6" = "0.0.0.0"
|
||||||
escapeHostName h = h
|
escapeHostName h = h
|
||||||
|
|
||||||
postgrestSpec :: RelationshipsMap -> [ProcDescription] -> [Table] -> (Text, Text, Integer, Text) -> Maybe Text -> Swagger
|
postgrestSpec :: RelationshipsMap -> [ProcDescription] -> [Table] -> (Text, Text, Integer, Text) -> Maybe Text -> Bool -> Swagger
|
||||||
postgrestSpec rels pds ti (s, h, p, b) sd = (mempty :: Swagger)
|
postgrestSpec rels pds ti (s, h, p, b) sd allowSecurityDef = (mempty :: Swagger)
|
||||||
& basePath ?~ T.unpack b
|
& basePath ?~ T.unpack b
|
||||||
& schemes ?~ [s']
|
& schemes ?~ [s']
|
||||||
& info .~ ((mempty :: Info)
|
& info .~ ((mempty :: Info)
|
||||||
@@ -338,10 +347,13 @@ postgrestSpec rels pds ti (s, h, p, b) sd = (mempty :: Swagger)
|
|||||||
& paths .~ makePathItems pds ti
|
& paths .~ makePathItems pds ti
|
||||||
& produces .~ makeMimeList [MTApplicationJSON, MTSingularJSON, MTTextCSV]
|
& produces .~ makeMimeList [MTApplicationJSON, MTSingularJSON, MTTextCSV]
|
||||||
& consumes .~ makeMimeList [MTApplicationJSON, MTSingularJSON, MTTextCSV]
|
& consumes .~ makeMimeList [MTApplicationJSON, MTSingularJSON, MTTextCSV]
|
||||||
|
& securityDefinitions .~ makeSecurityDefinitions securityDefName allowSecurityDef
|
||||||
|
& security .~ [SecurityRequirement (fromList [(securityDefName, [])]) | allowSecurityDef]
|
||||||
where
|
where
|
||||||
s' = if s == "http" then Http else Https
|
s' = if s == "http" then Http else Https
|
||||||
h' = Just $ Host (T.unpack $ escapeHostName h) (Just (fromInteger p))
|
h' = Just $ Host (T.unpack $ escapeHostName h) (Just (fromInteger p))
|
||||||
d = fromMaybe "This is a dynamic API generated by PostgREST" sd
|
d = fromMaybe "This is a dynamic API generated by PostgREST" sd
|
||||||
|
securityDefName = "JWT"
|
||||||
|
|
||||||
pickProxy :: Maybe Text -> Maybe Proxy
|
pickProxy :: Maybe Text -> Maybe Proxy
|
||||||
pickProxy proxy
|
pickProxy proxy
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = ""
|
|||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-privileges"
|
openapi-mode = "follow-privileges"
|
||||||
|
openapi-security-active = false
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = ""
|
|||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-privileges"
|
openapi-mode = "follow-privileges"
|
||||||
|
openapi-security-active = false
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = ""
|
|||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-privileges"
|
openapi-mode = "follow-privileges"
|
||||||
|
openapi-security-active = false
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = ""
|
|||||||
jwt-secret-is-base64 = false
|
jwt-secret-is-base64 = false
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-privileges"
|
openapi-mode = "follow-privileges"
|
||||||
|
openapi-security-active = false
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = "ODERREALLYREALLYREALLYREALLYVERYSAFE"
|
|||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "disabled"
|
openapi-mode = "disabled"
|
||||||
|
openapi-security-active = false
|
||||||
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"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = "OVERRIDE=REALLY=REALLY=REALLY=REALLY=VERY=SAFE"
|
|||||||
jwt-secret-is-base64 = false
|
jwt-secret-is-base64 = false
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-privileges"
|
openapi-mode = "ignore-privileges"
|
||||||
|
openapi-security-active = true
|
||||||
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"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5"
|
|||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-privileges"
|
openapi-mode = "ignore-privileges"
|
||||||
|
openapi-security-active = true
|
||||||
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"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = ""
|
|||||||
jwt-secret-is-base64 = false
|
jwt-secret-is-base64 = false
|
||||||
log-level = "error"
|
log-level = "error"
|
||||||
openapi-mode = "follow-privileges"
|
openapi-mode = "follow-privileges"
|
||||||
|
openapi-security-active = false
|
||||||
openapi-server-proxy-uri = ""
|
openapi-server-proxy-uri = ""
|
||||||
raw-media-types = ""
|
raw-media-types = ""
|
||||||
server-host = "!4"
|
server-host = "!4"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ 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-privileges'
|
PGRST_OPENAPI_MODE: 'ignore-privileges'
|
||||||
|
PGRST_OPENAPI_SECURITY_ACTIVE: true
|
||||||
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
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5"
|
|||||||
jwt-secret-is-base64 = true
|
jwt-secret-is-base64 = true
|
||||||
log-level = "info"
|
log-level = "info"
|
||||||
openapi-mode = "ignore-privileges"
|
openapi-mode = "ignore-privileges"
|
||||||
|
openapi-security-active = true
|
||||||
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"
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ ALTER ROLE other_authenticator SET pgrst.db_pre_request = 'test.other_custom_hea
|
|||||||
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';
|
ALTER ROLE other_authenticator SET pgrst.openapi_mode = 'disabled';
|
||||||
|
ALTER ROLE other_authenticator SET pgrst.openapi_security_active = 'false';
|
||||||
|
|
||||||
-- limited authenticator used for failed schema cache loads
|
-- limited authenticator used for failed schema cache loads
|
||||||
CREATE ROLE limited_authenticator LOGIN NOINHERIT;
|
CREATE ROLE limited_authenticator LOGIN NOINHERIT;
|
||||||
|
|||||||
@@ -636,3 +636,15 @@ spec actualPgVersion = describe "OpenAPI" $ do
|
|||||||
|
|
||||||
liftIO $ params `shouldBe` Just [aesonQQ|["num", "str"]|]
|
liftIO $ params `shouldBe` Just [aesonQQ|["num", "str"]|]
|
||||||
|
|
||||||
|
describe "Security" $
|
||||||
|
it "does not include security or security definitions by default" $ do
|
||||||
|
r <- simpleBody <$> get "/"
|
||||||
|
|
||||||
|
let sec = r ^? key "security"
|
||||||
|
secDef = r ^? key "securityDefinitions"
|
||||||
|
|
||||||
|
liftIO $ do
|
||||||
|
|
||||||
|
sec `shouldBe` Nothing
|
||||||
|
|
||||||
|
secDef `shouldBe` Nothing
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
module Feature.OpenApi.SecurityOpenApiSpec where
|
||||||
|
|
||||||
|
import Control.Lens ((^?))
|
||||||
|
|
||||||
|
import Data.Aeson.Lens
|
||||||
|
import Data.Aeson.QQ
|
||||||
|
|
||||||
|
import Network.Wai (Application)
|
||||||
|
import Network.Wai.Test (SResponse (..))
|
||||||
|
|
||||||
|
import Test.Hspec hiding (pendingWith)
|
||||||
|
import Test.Hspec.Wai
|
||||||
|
|
||||||
|
import Protolude hiding (get)
|
||||||
|
|
||||||
|
spec :: SpecWith ((), Application)
|
||||||
|
spec =
|
||||||
|
describe "Security active" $
|
||||||
|
it "includes security and security definitions" $ do
|
||||||
|
r <- simpleBody <$> get "/"
|
||||||
|
|
||||||
|
let sec = r ^? key "security"
|
||||||
|
secDef = r ^? key "securityDefinitions"
|
||||||
|
|
||||||
|
liftIO $ do
|
||||||
|
|
||||||
|
sec `shouldBe` Just
|
||||||
|
[aesonQQ|
|
||||||
|
[
|
||||||
|
{ "JWT": [] }
|
||||||
|
]
|
||||||
|
|]
|
||||||
|
|
||||||
|
secDef `shouldBe` Just
|
||||||
|
[aesonQQ|
|
||||||
|
{
|
||||||
|
"JWT": {
|
||||||
|
"description": "Add the token prepending \"Bearer \" (without quotes) to it",
|
||||||
|
"in": "header",
|
||||||
|
"name": "Authorization",
|
||||||
|
"type": "apiKey"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|]
|
||||||
@@ -34,6 +34,7 @@ import qualified Feature.OpenApi.IgnorePrivOpenApiSpec
|
|||||||
import qualified Feature.OpenApi.OpenApiSpec
|
import qualified Feature.OpenApi.OpenApiSpec
|
||||||
import qualified Feature.OpenApi.ProxySpec
|
import qualified Feature.OpenApi.ProxySpec
|
||||||
import qualified Feature.OpenApi.RootSpec
|
import qualified Feature.OpenApi.RootSpec
|
||||||
|
import qualified Feature.OpenApi.SecurityOpenApiSpec
|
||||||
import qualified Feature.OptionsSpec
|
import qualified Feature.OptionsSpec
|
||||||
import qualified Feature.Query.AndOrParamsSpec
|
import qualified Feature.Query.AndOrParamsSpec
|
||||||
import qualified Feature.Query.DeleteSpec
|
import qualified Feature.Query.DeleteSpec
|
||||||
@@ -95,6 +96,7 @@ main = do
|
|||||||
let withApp = app testCfg
|
let withApp = app testCfg
|
||||||
maxRowsApp = app testMaxRowsCfg
|
maxRowsApp = app testMaxRowsCfg
|
||||||
disabledOpenApi = app testDisabledOpenApiCfg
|
disabledOpenApi = app testDisabledOpenApiCfg
|
||||||
|
securityOpenApi = app testSecurityOpenApiCfg
|
||||||
proxyApp = app testProxyCfg
|
proxyApp = app testProxyCfg
|
||||||
noAnonApp = app testCfgNoAnon
|
noAnonApp = app testCfgNoAnon
|
||||||
noJwtApp = app testCfgNoJWT
|
noJwtApp = app testCfgNoJWT
|
||||||
@@ -171,6 +173,10 @@ main = do
|
|||||||
parallel $ before proxyApp $
|
parallel $ before proxyApp $
|
||||||
describe "Feature.OpenApi.ProxySpec" Feature.OpenApi.ProxySpec.spec
|
describe "Feature.OpenApi.ProxySpec" Feature.OpenApi.ProxySpec.spec
|
||||||
|
|
||||||
|
-- this test runs with openapi-security-active set to true
|
||||||
|
parallel $ before securityOpenApi $
|
||||||
|
describe "Feature.OpenApi.SecurityOpenApiSpec" Feature.OpenApi.SecurityOpenApiSpec.spec
|
||||||
|
|
||||||
-- this test runs without an anonymous role
|
-- this test runs without an anonymous role
|
||||||
parallel $ before noAnonApp $
|
parallel $ before noAnonApp $
|
||||||
describe "Feature.Auth.NoAnonSpec" Feature.Auth.NoAnonSpec.spec
|
describe "Feature.Auth.NoAnonSpec" Feature.Auth.NoAnonSpec.spec
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
|||||||
, configJwtSecretIsBase64 = False
|
, configJwtSecretIsBase64 = False
|
||||||
, configLogLevel = LogCrit
|
, configLogLevel = LogCrit
|
||||||
, configOpenApiMode = OAFollowPriv
|
, configOpenApiMode = OAFollowPriv
|
||||||
|
, configOpenApiSecurityActive = False
|
||||||
, configOpenApiServerProxyUri = Nothing
|
, configOpenApiServerProxyUri = Nothing
|
||||||
, configRawMediaTypes = []
|
, configRawMediaTypes = []
|
||||||
, configServerHost = "localhost"
|
, configServerHost = "localhost"
|
||||||
@@ -134,6 +135,9 @@ testIgnorePrivOpenApiCfg = baseCfg { configOpenApiMode = OAIgnorePriv, configDbS
|
|||||||
testProxyCfg :: AppConfig
|
testProxyCfg :: AppConfig
|
||||||
testProxyCfg = baseCfg { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
testProxyCfg = baseCfg { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }
|
||||||
|
|
||||||
|
testSecurityOpenApiCfg :: AppConfig
|
||||||
|
testSecurityOpenApiCfg = baseCfg { configOpenApiSecurityActive = True }
|
||||||
|
|
||||||
testCfgBinaryJWT :: AppConfig
|
testCfgBinaryJWT :: AppConfig
|
||||||
testCfgBinaryJWT =
|
testCfgBinaryJWT =
|
||||||
let secret = Just . B64.decodeLenient $ "cmVhbGx5cmVhbGx5cmVhbGx5cmVhbGx5dmVyeXNhZmU=" in
|
let secret = Just . B64.decodeLenient $ "cmVhbGx5cmVhbGx5cmVhbGx5cmVhbGx5dmVyeXNhZmU=" in
|
||||||
|
|||||||
Reference in New Issue
Block a user