feat: add config to specify CORS origins (#2986)

This commit is contained in:
Taimoor Zaeem
2023-10-24 09:38:25 -05:00
committed by GitHub
parent 618f93dec1
commit d94286c185
19 changed files with 134 additions and 52 deletions
+1
View File
@@ -28,6 +28,7 @@ openapi-mode = "follow-privileges"
openapi-security-active = false
openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = ""
server-host = "!4"
server-port = 3000
server-trace-header = ""
@@ -28,6 +28,7 @@ openapi-mode = "follow-privileges"
openapi-security-active = false
openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = ""
server-host = "!4"
server-port = 3000
server-trace-header = ""
@@ -28,6 +28,7 @@ openapi-mode = "follow-privileges"
openapi-security-active = false
openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = ""
server-host = "!4"
server-port = 3000
server-trace-header = ""
+1
View File
@@ -28,6 +28,7 @@ openapi-mode = "follow-privileges"
openapi-security-active = false
openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = ""
server-host = "!4"
server-port = 3000
server-trace-header = ""
@@ -28,6 +28,7 @@ openapi-mode = "disabled"
openapi-security-active = false
openapi-server-proxy-uri = "https://otherexample.org/api"
raw-media-types = "application/vnd.pgrst.other-db-config"
server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0"
server-port = 80
server-trace-header = "traceparent"
@@ -28,6 +28,7 @@ openapi-mode = "ignore-privileges"
openapi-security-active = true
openapi-server-proxy-uri = "https://example.org/api"
raw-media-types = "application/vnd.pgrst.db-config"
server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0"
server-port = 80
server-trace-header = "CF-Ray"
@@ -28,6 +28,7 @@ openapi-mode = "ignore-privileges"
openapi-security-active = true
openapi-server-proxy-uri = "https://postgrest.org"
raw-media-types = "application/vnd.pgrst.config"
server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0"
server-port = 80
server-trace-header = "X-Request-Id"
+1
View File
@@ -28,6 +28,7 @@ openapi-mode = "follow-privileges"
openapi-security-active = false
openapi-server-proxy-uri = ""
raw-media-types = ""
server-cors-allowed-origins = ""
server-host = "!4"
server-port = 3000
server-trace-header = ""
+1
View File
@@ -30,6 +30,7 @@ PGRST_OPENAPI_MODE: 'ignore-privileges'
PGRST_OPENAPI_SECURITY_ACTIVE: true
PGRST_OPENAPI_SERVER_PROXY_URI: 'https://postgrest.org'
PGRST_RAW_MEDIA_TYPES: application/vnd.pgrst.config
PGRST_SERVER_CORS_ALLOWED_ORIGINS: "http://example.com"
PGRST_SERVER_HOST: 0.0.0.0
PGRST_SERVER_PORT: 80
PGRST_SERVER_TRACE_HEADER: X-Request-Id
+1
View File
@@ -28,6 +28,7 @@ openapi-mode = "ignore-privileges"
openapi-security-active = true
openapi-server-proxy-uri = "https://postgrest.org"
raw-media-types = "application/vnd.pgrst.config"
server-cors-allowed-origins = "http://example.com"
server-host = "0.0.0.0"
server-port = 80
server-trace-header = "X-Request-Id"
+2
View File
@@ -18,6 +18,7 @@ ALTER ROLE db_config_authenticator SET pgrst.db_pre_request = 'test.custom_heade
ALTER ROLE db_config_authenticator SET pgrst.db_max_rows = '1000';
ALTER ROLE db_config_authenticator SET pgrst.db_extra_search_path = 'public, extensions';
ALTER ROLE db_config_authenticator SET pgrst.not_existing = 'should be ignored';
ALTER ROLE db_config_authenticator SET pgrst.server_cors_allowed_origins = 'http://example.com';
ALTER ROLE db_config_authenticator SET pgrst.server_trace_header = 'CF-Ray';
-- override with database specific setting
@@ -62,6 +63,7 @@ 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.openapi_mode = 'disabled';
ALTER ROLE other_authenticator SET pgrst.openapi_security_active = 'false';
ALTER ROLE other_authenticator SET pgrst.server_cors_allowed_origins = 'http://example.com';
ALTER ROLE other_authenticator SET pgrst.server_trace_header = 'traceparent';
ALTER ROLE other_authenticator SET pgrst.db_pre_config = 'postgrest.pre_config';
+59
View File
@@ -1214,3 +1214,62 @@ def test_jwt_cache_with_no_exp_claim(defaultenv):
# their difference should be atleast 300, implying
# that JWT Caching is working as expected
assert (first_dur - second_dur) > 300.0
def test_preflight_request_with_cors_allowed_origin_config(defaultenv):
"OPTIONS preflight request should return Access-Control-Allow-Origin equal to origin"
env = {
**defaultenv,
"PGRST_SERVER_CORS_ALLOWED_ORIGINS": "http://example.com, http://example2.com",
}
headers = {
"Accept": "*/*",
"Origin": "http://example.com",
"Access-Control-Request-Method": "POST",
"Access-Control-Request-Headers": "Content-Type",
}
with run(env=env) as postgrest:
response = postgrest.session.options("/items", headers=headers)
assert (
response.headers["Access-Control-Allow-Origin"] == "http://example.com"
and response.headers["Access-Control-Allow-Credentials"] == "true"
)
def test_no_preflight_request_with_CORS_config_should_return_header(defaultenv):
"GET no preflight request should return Access-Control-Allow-Origin equal to origin"
env = {
**defaultenv,
"PGRST_SERVER_CORS_ALLOWED_ORIGINS": "http://example.com, http://example2.com",
}
headers = {
"Accept": "*/*",
"Origin": "http://example.com",
}
with run(env=env) as postgrest:
response = postgrest.session.get("/items", headers=headers)
assert response.headers["Access-Control-Allow-Origin"] == "http://example.com"
def test_no_preflight_request_with_CORS_config_should_not_return_header(defaultenv):
"GET no preflight request should not return Access-Control-Allow-Origin"
env = {
**defaultenv,
"PGRST_SERVER_CORS_ALLOWED_ORIGINS": "http://example.com, http://example2.com",
}
headers = {
"Accept": "*/*",
"Origin": "http://invalid.com",
}
with run(env=env) as postgrest:
response = postgrest.session.get("/items", headers=headers)
assert "Access-Control-Allow-Origin" not in response.headers
+1 -2
View File
@@ -20,8 +20,7 @@ spec =
""
`shouldRespondWith`
""
{ matchHeaders = [ "Access-Control-Allow-Origin" <:> "http://example.com"
, "Access-Control-Allow-Credentials" <:> "true"
{ matchHeaders = [ "Access-Control-Allow-Origin" <:> "*"
, "Access-Control-Allow-Methods" <:> "GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD"
, "Access-Control-Allow-Headers" <:> "Authorization, Foo, Bar, Accept, Accept-Language, Content-Language"
, "Access-Control-Max-Age" <:> "86400" ]
+44 -43
View File
@@ -97,49 +97,50 @@ validateOpenApiResponse headers = do
baseCfg :: AppConfig
baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
AppConfig {
configAppSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ]
, configDbAnonRole = Just "postgrest_test_anonymous"
, configDbChannel = mempty
, configDbChannelEnabled = True
, configDbExtraSearchPath = []
, configDbMaxRows = Nothing
, configDbPlanEnabled = False
, configDbPoolSize = 10
, configDbPoolAcquisitionTimeout = 10
, configDbPoolMaxLifetime = 1800
, configDbPoolMaxIdletime = 600
, configDbPoolAutomaticRecovery = True
, configDbPreRequest = Just $ QualifiedIdentifier "test" "switch_role"
, configDbPreparedStatements = True
, configDbRootSpec = Nothing
, configDbSchemas = fromList ["test"]
, configDbConfig = False
, configDbPreConfig = Nothing
, configDbUri = "postgresql://"
, configDbUseLegacyGucs = True
, configFilePath = Nothing
, configJWKS = parseSecret <$> secret
, configJwtAudience = Nothing
, configJwtRoleClaimKey = [JSPKey "role"]
, configJwtSecret = secret
, configJwtSecretIsBase64 = False
, configJwtCacheMaxLifetime = 0
, configLogLevel = LogCrit
, configOpenApiMode = OAFollowPriv
, configOpenApiSecurityActive = False
, configOpenApiServerProxyUri = Nothing
, configRawMediaTypes = []
, configServerHost = "localhost"
, configServerPort = 3000
, configServerTraceHeader = Nothing
, configServerUnixSocket = Nothing
, configServerUnixSocketMode = 432
, configDbTxAllowOverride = True
, configDbTxRollbackAll = True
, configAdminServerPort = Nothing
, configRoleSettings = mempty
, configRoleIsoLvl = mempty
, configInternalSCSleep = Nothing
configAppSettings = [ ("app.settings.app_host", "localhost") , ("app.settings.external_api_secret", "0123456789abcdef") ]
, configDbAnonRole = Just "postgrest_test_anonymous"
, configDbChannel = mempty
, configDbChannelEnabled = True
, configDbExtraSearchPath = []
, configDbMaxRows = Nothing
, configDbPlanEnabled = False
, configDbPoolSize = 10
, configDbPoolAcquisitionTimeout = 10
, configDbPoolMaxLifetime = 1800
, configDbPoolMaxIdletime = 600
, configDbPoolAutomaticRecovery = True
, configDbPreRequest = Just $ QualifiedIdentifier "test" "switch_role"
, configDbPreparedStatements = True
, configDbRootSpec = Nothing
, configDbSchemas = fromList ["test"]
, configDbConfig = False
, configDbPreConfig = Nothing
, configDbUri = "postgresql://"
, configDbUseLegacyGucs = True
, configFilePath = Nothing
, configJWKS = parseSecret <$> secret
, configJwtAudience = Nothing
, configJwtRoleClaimKey = [JSPKey "role"]
, configJwtSecret = secret
, configJwtSecretIsBase64 = False
, configJwtCacheMaxLifetime = 0
, configLogLevel = LogCrit
, configOpenApiMode = OAFollowPriv
, configOpenApiSecurityActive = False
, configOpenApiServerProxyUri = Nothing
, configRawMediaTypes = []
, configServerCorsAllowedOrigins = Nothing
, configServerHost = "localhost"
, configServerPort = 3000
, configServerTraceHeader = Nothing
, configServerUnixSocket = Nothing
, configServerUnixSocketMode = 432
, configDbTxAllowOverride = True
, configDbTxRollbackAll = True
, configAdminServerPort = Nothing
, configRoleSettings = mempty
, configRoleIsoLvl = mempty
, configInternalSCSleep = Nothing
}
testCfg :: AppConfig