align cors settings names with elasticsearch (#85738)

* align cors settings names with elasticsearch

* server.cors.origin: * --> server.cors.origin: ["*"]
This commit is contained in:
Mikhail Shustov 2020-12-14 15:57:28 +03:00 committed by GitHub
parent 4f48401b20
commit fbb83af63d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 36 deletions

View file

@ -453,11 +453,11 @@ deprecation warning at startup. This setting cannot end in a slash (`/`).
| `server.cors.enabled:`
| experimental[] Set to `true` to allow cross-origin API calls. *Default:* `false`
| `server.cors.credentials:`
| `server.cors.allowCredentials:`
| experimental[] Set to `true` to allow browser code to access response body whenever request performed with user credentials. *Default:* `false`
| `server.cors.origin:`
| experimental[] List of origins permitted to access resources. You must specify explicit hostnames and not use `*` for `server.cors.origin` when `server.cors.credentials: true`. *Default:* "*"
| `server.cors.allowOrigin:`
| experimental[] List of origins permitted to access resources. You must specify explicit hostnames and not use `server.cors.allowOrigin: ["*"]` when `server.cors.allowCredentials: true`. *Default:* ["*"]
| `server.compression.referrerWhitelist:`
| Specifies an array of trusted hostnames, such as the {kib} host, or a reverse

View file

@ -39,9 +39,11 @@ Object {
"enabled": true,
},
"cors": Object {
"credentials": false,
"allowCredentials": false,
"allowOrigin": Array [
"*",
],
"enabled": false,
"origin": "*",
},
"customResponseHeaders": Object {},
"host": "localhost",

View file

@ -331,51 +331,67 @@ describe('with compression', () => {
});
describe('cors', () => {
describe('origin', () => {
describe('allowOrigin', () => {
it('list cannot be empty', () => {
expect(() =>
config.schema.validate({
cors: {
origin: [],
allowOrigin: [],
},
})
).toThrowErrorMatchingInlineSnapshot(`
"[cors.origin]: types that failed validation:
- [cors.origin.0]: expected value to equal [*]
- [cors.origin.1]: array size is [0], but cannot be smaller than [1]"
`);
"[cors.allowOrigin]: types that failed validation:
- [cors.allowOrigin.0]: array size is [0], but cannot be smaller than [1]
- [cors.allowOrigin.1]: array size is [0], but cannot be smaller than [1]"
`);
});
it('list of valid URLs', () => {
const origin = ['http://127.0.0.1:3000', 'https://elastic.co'];
const allowOrigin = ['http://127.0.0.1:3000', 'https://elastic.co'];
expect(
config.schema.validate({
cors: { origin },
}).cors.origin
).toStrictEqual(origin);
cors: { allowOrigin },
}).cors.allowOrigin
).toStrictEqual(allowOrigin);
expect(() =>
config.schema.validate({
cors: {
origin: ['*://elastic.co/*'],
allowOrigin: ['*://elastic.co/*'],
},
})
).toThrow();
});
it('can be configured as "*" wildcard', () => {
expect(config.schema.validate({ cors: { origin: '*' } }).cors.origin).toBe('*');
expect(config.schema.validate({ cors: { allowOrigin: ['*'] } }).cors.allowOrigin).toEqual([
'*',
]);
});
it('cannot mix wildcard "*" with valid URLs', () => {
expect(
() =>
config.schema.validate({ cors: { allowOrigin: ['*', 'https://elastic.co'] } }).cors
.allowOrigin
).toThrowErrorMatchingInlineSnapshot(`
"[cors.allowOrigin]: types that failed validation:
- [cors.allowOrigin.0.0]: expected URI with scheme [http|https].
- [cors.allowOrigin.1.1]: expected value to equal [*]"
`);
});
});
describe('credentials', () => {
it('cannot use wildcard origin if "credentials: true"', () => {
it('cannot use wildcard allowOrigin if "credentials: true"', () => {
expect(
() => config.schema.validate({ cors: { credentials: true, origin: '*' } }).cors.origin
() =>
config.schema.validate({ cors: { allowCredentials: true, allowOrigin: ['*'] } }).cors
.allowOrigin
).toThrowErrorMatchingInlineSnapshot(
`"[cors]: Cannot specify wildcard origin \\"*\\" with \\"credentials: true\\". Please provide a list of allowed origins."`
);
expect(
() => config.schema.validate({ cors: { credentials: true } }).cors.origin
() => config.schema.validate({ cors: { allowCredentials: true } }).cors.allowOrigin
).toThrowErrorMatchingInlineSnapshot(
`"[cors]: Cannot specify wildcard origin \\"*\\" with \\"credentials: true\\". Please provide a list of allowed origins."`
);

View file

@ -48,17 +48,20 @@ export const config = {
cors: schema.object(
{
enabled: schema.boolean({ defaultValue: false }),
credentials: schema.boolean({ defaultValue: false }),
origin: schema.oneOf(
[schema.literal('*'), schema.arrayOf(hostURISchema, { minSize: 1 })],
allowCredentials: schema.boolean({ defaultValue: false }),
allowOrigin: schema.oneOf(
[
schema.arrayOf(hostURISchema, { minSize: 1 }),
schema.arrayOf(schema.literal('*'), { minSize: 1, maxSize: 1 }),
],
{
defaultValue: '*',
defaultValue: ['*'],
}
),
},
{
validate(value) {
if (value.credentials === true && value.origin === '*') {
if (value.allowCredentials === true && value.allowOrigin.includes('*')) {
return 'Cannot specify wildcard origin "*" with "credentials: true". Please provide a list of allowed origins.';
}
},
@ -168,8 +171,8 @@ export class HttpConfig {
public port: number;
public cors: {
enabled: boolean;
credentials: boolean;
origin: '*' | string[];
allowCredentials: boolean;
allowOrigin: string[];
};
public customResponseHeaders: Record<string, string | string[]>;
public maxPayload: ByteSizeValue;

View file

@ -196,8 +196,8 @@ describe('getServerOptions', () => {
config.schema.validate({
cors: {
enabled: true,
credentials: false,
origin: '*',
allowCredentials: false,
allowOrigin: ['*'],
},
}),
{} as any,
@ -206,7 +206,7 @@ describe('getServerOptions', () => {
expect(getServerOptions(httpConfig).routes?.cors).toEqual({
credentials: false,
origin: '*',
origin: ['*'],
headers: ['Accept', 'Authorization', 'Content-Type', 'If-None-Match', 'kbn-xsrf'],
});
});

View file

@ -39,8 +39,8 @@ const corsAllowedHeaders = ['Accept', 'Authorization', 'Content-Type', 'If-None-
export function getServerOptions(config: HttpConfig, { configureTLS = true } = {}) {
const cors: RouteOptionsCors | false = config.cors.enabled
? {
credentials: config.cors.credentials,
origin: config.cors.origin,
credentials: config.cors.allowCredentials,
origin: config.cors.allowOrigin,
headers: corsAllowedHeaders,
}
: false;

View file

@ -55,8 +55,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
`--plugin-path=${corsTestPlugin}`,
`--test.cors.port=${pluginPort}`,
'--server.cors.enabled=true',
'--server.cors.credentials=true',
`--server.cors.origin=["${originUrl}"]`,
'--server.cors.allowCredentials=true',
`--server.cors.allowOrigin=["${originUrl}"]`,
],
},
};

View file

@ -15,9 +15,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('CORS', () => {
it('Communicates to Kibana with configured CORS', async () => {
const args: string[] = config.get('kbnTestServer.serverArgs');
const originSetting = args.find((str) => str.includes('server.cors.origin'));
const originSetting = args.find((str) => str.includes('server.cors.allowOrigin'));
if (!originSetting) {
throw new Error('Cannot find "server.cors.origin" argument');
throw new Error('Cannot find "server.cors.allowOrigin" argument');
}
const [, value] = originSetting.split('=');
const url = JSON.parse(value);