[8.9] Do not enforce app authorization for features that have opted out of RBAC. (#165190) (#165230)

# Backport

This will backport the following commits from `main` to `8.9`:
- [Do not enforce app authorization for features that have opted out of
RBAC. (#165190)](https://github.com/elastic/kibana/pull/165190)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Aleh
Zasypkin","email":"aleh.zasypkin@elastic.co"},"sourceCommit":{"committedDate":"2023-08-30T12:38:13Z","message":"Do
not enforce app authorization for features that have opted out of RBAC.
(#165190)\n\n## Summary\r\n\r\nThe title says it all, we shouldn't
enforce app authorization for\r\nfeatures that have opted out of RBAC.
Currently we have just two such\r\nfeatures: Enterprise Search and
Monitoring.","sha":"f1cc1eb53879a21f0eaf13ef900e0fd872bd7038","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","Team:Security","release_note:skip","Feature:Security/Authorization","backport:all-open","Project:Serverless","ci:build-serverless-image","v8.11.0"],"number":165190,"url":"https://github.com/elastic/kibana/pull/165190","mergeCommit":{"message":"Do
not enforce app authorization for features that have opted out of RBAC.
(#165190)\n\n## Summary\r\n\r\nThe title says it all, we shouldn't
enforce app authorization for\r\nfeatures that have opted out of RBAC.
Currently we have just two such\r\nfeatures: Enterprise Search and
Monitoring.","sha":"f1cc1eb53879a21f0eaf13ef900e0fd872bd7038"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/165190","number":165190,"mergeCommit":{"message":"Do
not enforce app authorization for features that have opted out of RBAC.
(#165190)\n\n## Summary\r\n\r\nThe title says it all, we shouldn't
enforce app authorization for\r\nfeatures that have opted out of RBAC.
Currently we have just two such\r\nfeatures: Enterprise Search and
Monitoring.","sha":"f1cc1eb53879a21f0eaf13ef900e0fd872bd7038"}}]}]
BACKPORT-->

Co-authored-by: Aleh Zasypkin <aleh.zasypkin@elastic.co>
This commit is contained in:
Kibana Machine 2023-08-30 10:18:42 -04:00 committed by GitHub
parent 3256376c69
commit 4f33e26474
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 9 deletions

View file

@ -11,17 +11,22 @@ import {
httpServiceMock,
loggingSystemMock,
} from '@kbn/core/server/mocks';
import type { PluginSetupContract as FeaturesSetupContract } from '@kbn/features-plugin/server';
import type {
PluginSetupContract as FeaturesSetupContract,
KibanaFeature,
} from '@kbn/features-plugin/server';
import { featuresPluginMock } from '@kbn/features-plugin/server/mocks';
import { initAppAuthorization } from './app_authorization';
import { authorizationMock } from './index.mock';
const createFeaturesSetupContractMock = (): FeaturesSetupContract => {
const createFeaturesSetupContractMock = (
features: KibanaFeature[] = [
{ id: 'foo', name: 'Foo', app: ['foo'], privileges: {} } as unknown as KibanaFeature,
]
): FeaturesSetupContract => {
const mock = featuresPluginMock.createSetup();
mock.getKibanaFeatures.mockReturnValue([
{ id: 'foo', name: 'Foo', app: ['foo'], privileges: {} } as any,
]);
mock.getKibanaFeatures.mockReturnValue(features);
return mock;
};
@ -97,6 +102,33 @@ describe('initAppAuthorization', () => {
expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest);
});
test(`unprotected route that starts with "/app/", from feature that opted out of RBAC, and "mode.useRbacForRequest()" returns true continues`, async () => {
const mockHTTPSetup = coreMock.createSetup().http;
const mockAuthz = authorizationMock.create();
initAppAuthorization(
mockHTTPSetup,
mockAuthz,
loggingSystemMock.create().get(),
createFeaturesSetupContractMock([
{ id: 'foo', name: 'Foo', app: ['foo'], privileges: null } as unknown as KibanaFeature,
])
);
const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls;
const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', path: '/app/foo' });
const mockResponse = httpServerMock.createResponseFactory();
const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit();
mockAuthz.mode.useRbacForRequest.mockReturnValue(true);
await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit);
expect(mockResponse.notFound).not.toHaveBeenCalled();
expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1);
expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest);
});
test(`protected route that starts with "/app/", "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => {
const mockHTTPSetup = coreMock.createSetup().http;
const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' });

View file

@ -20,10 +20,11 @@ class ProtectedApplications {
// we wait until we actually need to consume these before getting them
if (this.applications == null) {
this.applications = new Set(
this.featuresService
.getKibanaFeatures()
.map((feature) => feature.app)
.flat()
this.featuresService.getKibanaFeatures().flatMap((feature) => {
// If the feature has explicitly opted out of our RBAC by setting the `privileges` field to `null`, we
// shouldn't check permissions when the app defined by such feature is accessed.
return feature.privileges === null ? [] : feature.app;
})
);
}