Skip to content

Commit

Permalink
Merge branch 'main' of github.com:elastic/kibana into kbn-team-1309-r…
Browse files Browse the repository at this point in the history
…elocate-20250106110819
  • Loading branch information
Dosant committed Jan 6, 2025
2 parents 1485a50 + 26cc597 commit 8b27248
Show file tree
Hide file tree
Showing 104 changed files with 1,422 additions and 1,426 deletions.
33 changes: 0 additions & 33 deletions packages/kbn-babel-preset/styled_components_files.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/kbn-test/jest-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ module.exports = {

// A map from regular expressions to paths to transformers
transform: {
'^.+\\.(js|tsx?)$': '<rootDir>/packages/kbn-test/src/jest/transforms/babel.js',
'^.+\\.(js|tsx?)$': '<rootDir>/packages/kbn-test/src/jest/transforms/babel/index.js',
'^.+\\.(txt|html)?$': '<rootDir>/packages/kbn-test/src/jest/transforms/raw.js',
'^.+\\.peggy?$': '<rootDir>/packages/kbn-test/src/jest/transforms/peggy.js',
},
Expand Down
13 changes: 13 additions & 0 deletions packages/kbn-test/src/jest/transforms/babel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

const babelJest = require('babel-jest');
const transformerConfig = require('./transformer_config');

module.exports = babelJest.default.createTransformer(transformerConfig);
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

const babelJest = require('babel-jest');

module.exports = babelJest.default.createTransformer({
module.exports = {
presets: [
[
require.resolve('@kbn/babel-preset/node_preset'),
Expand All @@ -22,4 +20,4 @@ module.exports = babelJest.default.createTransformer({
},
],
],
});
};
29 changes: 0 additions & 29 deletions src/core/packages/http/router-server-internal/src/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,35 +397,6 @@ describe('CoreKibanaRequest', () => {

expect(kibanaRequest.route.options.authRequired).toBe(true);
});
it('handles required authc: { enabled: false }', () => {
const request = hapiMocks.createRequest({
route: {
settings: {
app: {
security: { authc: { enabled: false } },
},
},
},
});
const kibanaRequest = CoreKibanaRequest.from(request);

expect(kibanaRequest.route.options.authRequired).toBe(false);
});

it(`handles required authc: { enabled: 'optional' }`, () => {
const request = hapiMocks.createRequest({
route: {
settings: {
app: {
security: { authc: { enabled: 'optional' } },
},
},
},
});
const kibanaRequest = CoreKibanaRequest.from(request);

expect(kibanaRequest.route.options.authRequired).toBe('optional');
});

it('handles required authz simple config', () => {
const security: RouteSecurity = {
Expand Down
6 changes: 0 additions & 6 deletions src/core/packages/http/router-server-internal/src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,6 @@ export class CoreKibanaRequest<
return true;
}

const security = this.getSecurity(request);

if (security?.authc !== undefined) {
return security.authc?.enabled ?? true;
}

const authOptions = request.route.settings.auth;
if (typeof authOptions === 'object') {
// 'try' is used in the legacy platform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,22 +542,19 @@ describe('Versioned route', () => {
authz: {
requiredPrivileges: ['foo', 'bar', 'baz'],
},
authc: undefined,
};
const securityConfig1: RouteSecurity = {
authz: {
requiredPrivileges: ['foo'],
},
authc: {
enabled: 'optional',
},
authc: undefined,
};
const securityConfig2: RouteSecurity = {
authz: {
requiredPrivileges: ['foo', 'bar'],
},
authc: {
enabled: true,
},
authc: undefined,
};
const versionedRoute = versionedRouter
.get({ path: '/test/{id}', access: 'internal', security: securityConfigDefault })
Expand Down Expand Up @@ -669,4 +666,42 @@ describe('Versioned route', () => {
- [authz.requiredPrivileges.0.1]: expected value of type [string] but got [Object]"
`);
});

it('should correctly merge security configuration for versions', () => {
const versionedRouter = CoreVersionedRouter.from({ router });
const validSecurityConfig: RouteSecurity = {
authz: {
requiredPrivileges: ['foo'],
},
authc: {
enabled: 'optional',
},
};

const route = versionedRouter.get({
path: '/test/{id}',
access: 'internal',
security: validSecurityConfig,
});

route.addVersion(
{
version: '1',
validate: false,
security: {
authz: {
requiredPrivileges: ['foo', 'bar'],
},
},
},
handlerFn
);

// @ts-expect-error for test purpose
const security = route.getSecurity({ headers: { [ELASTIC_HTTP_VERSION_HEADER]: '1' } });

expect(security.authc).toEqual({ enabled: 'optional' });

expect(security.authz).toEqual({ requiredPrivileges: ['foo', 'bar'] });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,18 @@ export class CoreVersionedRoute implements VersionedRoute {
return [...this.handlers.values()];
}

public getSecurity: RouteSecurityGetter = (req: RequestLike) => {
public getSecurity: RouteSecurityGetter = (req?: RequestLike) => {
if (!req) {
return this.defaultSecurityConfig;
}

const version = this.getVersion(req)!;
const security = this.handlers.get(version)?.options.security ?? this.defaultSecurityConfig;

return this.handlers.get(version)?.options.security ?? this.defaultSecurityConfig;
// authc can be defined only on the top route level,
// so we need to merge it with the versioned one which can have different authz per version
return security
? { authz: security.authz, authc: this.defaultSecurityConfig?.authc }
: undefined;
};
}
69 changes: 69 additions & 0 deletions src/core/packages/http/server-internal/src/http_server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1777,3 +1777,72 @@ describe('configuration change', () => {
);
});
});

test('exposes authentication details of incoming request to a route handler', async () => {
const { registerRouter, registerAuth, server: innerServer } = await server.setup({ config$ });

const router = new Router('', logger, enhanceWithContext, routerOptions);
router.get(
{
path: '/',
validate: false,
security: {
authc: { enabled: false, reason: 'test' },
authz: { enabled: false, reason: 'test' },
},
},
(context, req, res) => res.ok({ body: req.route })
);
router.get(
{
path: '/foo',
validate: false,
security: {
authc: { enabled: 'optional' },
authz: { enabled: false, reason: 'test' },
},
},
(context, req, res) => res.ok({ body: req.route })
);
// mocking to have `authRegistered` filed set to true
registerAuth((req, res) => res.unauthorized());
registerRouter(router);

await server.start();
await supertest(innerServer.listener)
.get('/')
.expect(200, {
method: 'get',
path: '/',
routePath: '/',
options: {
authRequired: false,
xsrfRequired: false,
access: 'internal',
tags: [],
timeout: {},
security: {
authc: { enabled: false, reason: 'test' },
authz: { enabled: false, reason: 'test' },
},
},
});
await supertest(innerServer.listener)
.get('/foo')
.expect(200, {
method: 'get',
path: '/foo',
routePath: '/foo',
options: {
authRequired: 'optional',
xsrfRequired: false,
access: 'internal',
tags: [],
timeout: {},
security: {
authc: { enabled: 'optional' },
authz: { enabled: false, reason: 'test' },
},
},
});
});
11 changes: 10 additions & 1 deletion src/core/packages/http/server-internal/src/http_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -742,14 +742,23 @@ export class HttpServer {
});
}

private getSecurity(route: RouterRoute) {
const securityConfig = route?.security;

// for versioned routes, we need to check if the security config is a function
return typeof securityConfig === 'function' ? securityConfig() : securityConfig;
}

private configureRoute(route: RouterRoute) {
const optionsLogger = this.log.get('options');
this.log.debug(`registering route handler for [${route.path}]`);
// Hapi does not allow payload validation to be specified for 'head' or 'get' requests
const validate = isSafeMethod(route.method) ? undefined : { payload: true };
const { authRequired, tags, body = {}, timeout, deprecated } = route.options;
const { tags, body = {}, timeout, deprecated } = route.options;
const { accepts: allow, override, maxBytes, output, parse } = body;

const authRequired = this.getSecurity(route)?.authc?.enabled ?? route.options.authRequired;

const kibanaRouteOptions: KibanaRouteOptions = {
xsrfRequired: route.options.xsrfRequired ?? !isSafeMethod(route.method),
access: route.options.access ?? 'internal',
Expand Down
2 changes: 1 addition & 1 deletion src/core/packages/http/server/src/router/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { IKibanaSocket } from './socket';
import type { RouteMethod, RouteConfigOptions, RouteSecurity, RouteDeprecationInfo } from './route';
import type { Headers } from './headers';

export type RouteSecurityGetter = (request: {
export type RouteSecurityGetter = (request?: {
headers: KibanaRequest['headers'];
query?: KibanaRequest['query'];
}) => RouteSecurity | undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/core/packages/http/server/src/versioning/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ export interface AddVersionOpts<P, Q, B> {
*/
validate: false | VersionedRouteValidation<P, Q, B> | (() => VersionedRouteValidation<P, Q, B>); // Provide a way to lazily load validation schemas

security?: RouteSecurity;
security?: Pick<RouteSecurity, 'authz'>;

options?: {
deprecated?: RouteDeprecationInfo;
Expand Down
8 changes: 4 additions & 4 deletions x-pack/.telemetryrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
{
"output": "platform/plugins/private/telemetry_collection_xpack/schema/xpack_plugins.json",
"root": "plugins/",
"exclude": [
"platform/plugins/private/monitoring/server/telemetry_collection/"
]
"exclude": []
},
{
"output": "platform/plugins/private/telemetry_collection_xpack/schema/xpack_monitoring.json",
Expand All @@ -14,7 +12,9 @@
{
"output": "platform/plugins/private/telemetry_collection_xpack/schema/xpack_platform.json",
"root": "platform/",
"exclude": []
"exclude": [
"platform/plugins/private/monitoring/server/telemetry_collection/"
]
},
{
"output": "platform/plugins/private/telemetry_collection_xpack/schema/xpack_observability.json",
Expand Down
Loading

0 comments on commit 8b27248

Please sign in to comment.