Skip to content

Commit

Permalink
[7.17] Do not enforce app authorization for features that have opted …
Browse files Browse the repository at this point in the history
…out of RBAC. (#165190) (#165234)

# Backport

This will backport the following commits from `main` to `7.17`:
- [Do not enforce app authorization for features that have opted out of
RBAC. (#165190)](#165190)

<!--- Backport version: 8.9.8 -->

### 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"}},{"url":"https://github.com/elastic/kibana/pull/165229","number":165229,"branch":"8.10","state":"OPEN"},{"url":"https://github.com/elastic/kibana/pull/165230","number":165230,"branch":"8.9","state":"OPEN"}]}]
BACKPORT-->
  • Loading branch information
azasypkin authored Aug 30, 2023
1 parent 595d330 commit 8ee2d5b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ import {
loggingSystemMock,
} from 'src/core/server/mocks';

import type { PluginSetupContract as FeaturesSetupContract } from '../../../features/server';
import type {
PluginSetupContract as FeaturesSetupContract,
KibanaFeature,
} from '../../../features/server';
import { featuresPluginMock } from '../../../features/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;
};

Expand Down Expand Up @@ -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' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
})
);
}

Expand Down

0 comments on commit 8ee2d5b

Please sign in to comment.