Skip to content

Commit

Permalink
[Workspace] Update default workspace permission and users config supp…
Browse files Browse the repository at this point in the history
…ort wildcard (opensearch-project#8617)

* Update default workspace permission and support wildcard

Signed-off-by: yubonluo <yubonluo@amazon.com>

* update the config yaml file

Signed-off-by: yubonluo <yubonluo@amazon.com>

* Changeset file for PR opensearch-project#8617 created/updated

* Changeset file for PR opensearch-project#8617 created/updated

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

* optimize the code

Signed-off-by: yubonluo <yubonluo@amazon.com>

---------

Signed-off-by: yubonluo <yubonluo@amazon.com>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
  • Loading branch information
2 people authored and Qxisylolo committed Oct 30, 2024
1 parent 14b4cb6 commit fca95e4
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 13 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/8617.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
refactor:
- [Workspace] Update default OSD admin config permission and support wildcard. ([#8617](/~https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8617))
2 changes: 2 additions & 0 deletions config/opensearch_dashboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,7 @@

# Set the backend roles in groups or users, whoever has the backend roles or exactly match the user ids defined in this config will be regard as dashboard admin.
# Dashboard admin will have the access to all the workspaces(workspace.enabled: true) and objects inside OpenSearch Dashboards.
# The default config is [], and no one will be dashboard admin.
# If the user config is set to wildcard ["*"], anyone will be dashboard admin.
# opensearchDashboards.dashboardAdmin.groups: ["dashboard_admin"]
# opensearchDashboards.dashboardAdmin.users: ["dashboard_admin"]
2 changes: 2 additions & 0 deletions src/plugins/workspace/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,5 @@ export const WORKSPACE_DATA_SOURCE_AND_CONNECTION_OBJECT_TYPES = [
];

export const USE_CASE_CARD_GRADIENT_PREFIX = 'workspace-initial-use-case-card';

export const OSD_ADMIN_WILDCARD_MATCH_ALL = '*';
56 changes: 53 additions & 3 deletions src/plugins/workspace/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe('Workspace server plugin', () => {
},
});
let registerOnPostAuthFn: OnPostAuthHandler = () => httpServerMock.createResponseFactory().ok();
setupMock.http.registerOnPostAuth.mockImplementation((fn) => {
setupMock.http.registerOnPostAuth.mockImplementationOnce((fn) => {
registerOnPostAuthFn = fn;
return fn;
});
Expand All @@ -137,7 +137,7 @@ describe('Workspace server plugin', () => {
expect(toolKitMock.next).toBeCalledTimes(1);
});

it('with yml config', async () => {
it('with configuring user as OSD admin', async () => {
jest
.spyOn(serverUtils, 'getPrincipalsFromRequest')
.mockImplementation(() => ({ users: [`user1`] }));
Expand All @@ -153,10 +153,56 @@ describe('Workspace server plugin', () => {
httpServerMock.createResponseFactory(),
toolKitMock
);

expect(getWorkspaceState(requestWithWorkspaceInUrl)).toEqual({
isDashboardAdmin: true,
});
expect(toolKitMock.next).toBeCalledTimes(1);
});

it('with configuring wildcard * and anyone will be OSD admin', async () => {
jest
.spyOn(serverUtils, 'getPrincipalsFromRequest')
.mockImplementation(() => ({ users: [`user1`] }));
jest.spyOn(utilsExports, 'getOSDAdminConfigFromYMLConfig').mockResolvedValue([[], ['*']]);

await workspacePlugin.setup(setupMock);
const toolKitMock = httpServerMock.createToolkit();

await registerOnPostAuthFn(
requestWithWorkspaceInUrl,
httpServerMock.createResponseFactory(),
toolKitMock
);

expect(getWorkspaceState(requestWithWorkspaceInUrl)).toEqual({
isDashboardAdmin: true,
});
expect(toolKitMock.next).toBeCalledTimes(1);
});

it('uninstall security plugin', async () => {
it('without configuring yml config and anyone will be not OSD admin', async () => {
jest
.spyOn(serverUtils, 'getPrincipalsFromRequest')
.mockImplementation(() => ({ users: [`user1`] }));
jest.spyOn(utilsExports, 'getOSDAdminConfigFromYMLConfig').mockResolvedValue([[], []]);

await workspacePlugin.setup(setupMock);
const toolKitMock = httpServerMock.createToolkit();

await registerOnPostAuthFn(
requestWithWorkspaceInUrl,
httpServerMock.createResponseFactory(),
toolKitMock
);

expect(getWorkspaceState(requestWithWorkspaceInUrl)).toEqual({
isDashboardAdmin: false,
});
expect(toolKitMock.next).toBeCalledTimes(1);
});

it('uninstall security plugin and anyone will be OSD admin', async () => {
jest.spyOn(serverUtils, 'getPrincipalsFromRequest').mockImplementation(() => ({}));

await workspacePlugin.setup(setupMock);
Expand All @@ -167,6 +213,10 @@ describe('Workspace server plugin', () => {
httpServerMock.createResponseFactory(),
toolKitMock
);

expect(getWorkspaceState(requestWithWorkspaceInUrl)).toEqual({
isDashboardAdmin: true,
});
expect(toolKitMock.next).toBeCalledTimes(1);
});

Expand Down
17 changes: 14 additions & 3 deletions src/plugins/workspace/server/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { getWorkspaceState } from '../../../core/server/utils';
import { Observable, of } from 'rxjs';
import { DEFAULT_DATA_SOURCE_UI_SETTINGS_ID } from '../../data_source_management/common';
import { OSD_ADMIN_WILDCARD_MATCH_ALL } from '../common/constants';

describe('workspace utils', () => {
it('should generate id with the specified size', () => {
Expand Down Expand Up @@ -76,13 +77,23 @@ describe('workspace utils', () => {
expect(getWorkspaceState(mockRequest)?.isDashboardAdmin).toBe(true);
});

it('should be dashboard admin when configGroups and configUsers are []', () => {
it('should not be dashboard admin when configGroups and configUsers are []', () => {
const mockRequest = httpServerMock.createOpenSearchDashboardsRequest();
const groups: string[] = ['user1'];
const users: string[] = [];
const groups: string[] = [];
const users: string[] = ['user1'];
const configGroups: string[] = [];
const configUsers: string[] = [];
updateDashboardAdminStateForRequest(mockRequest, groups, users, configGroups, configUsers);
expect(getWorkspaceState(mockRequest)?.isDashboardAdmin).toBe(false);
});

it('should be dashboard admin when configGroups or configUsers include wildcard *', () => {
const mockRequest = httpServerMock.createOpenSearchDashboardsRequest();
const groups: string[] = [];
const users: string[] = ['user1'];
const configGroups: string[] = [];
const configUsers: string[] = [OSD_ADMIN_WILDCARD_MATCH_ALL];
updateDashboardAdminStateForRequest(mockRequest, groups, users, configGroups, configUsers);
expect(getWorkspaceState(mockRequest)?.isDashboardAdmin).toBe(true);
});

Expand Down
13 changes: 6 additions & 7 deletions src/plugins/workspace/server/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
CURRENT_USER_PLACEHOLDER,
WorkspacePermissionMode,
WORKSPACE_DATA_SOURCE_AND_CONNECTION_OBJECT_TYPES,
OSD_ADMIN_WILDCARD_MATCH_ALL,
} from '../common/constants';
import { PermissionModeId } from '../../../core/server';

Expand All @@ -39,17 +40,15 @@ export const updateDashboardAdminStateForRequest = (
) => {
// If the security plugin is not installed, login defaults to OSD Admin
if (!groups.length && !users.length) {
updateWorkspaceState(request, { isDashboardAdmin: true });
return;
return updateWorkspaceState(request, { isDashboardAdmin: true });
}
// If groups/users are not configured or [], login defaults to OSD Admin
if (!configGroups.length && !configUsers.length) {
updateWorkspaceState(request, { isDashboardAdmin: true });
return;
// If user config contains wildcard characters '*', login defaults to OSD Admin
if (configUsers.includes(OSD_ADMIN_WILDCARD_MATCH_ALL)) {
return updateWorkspaceState(request, { isDashboardAdmin: true });
}
const groupMatchAny = groups.some((group) => configGroups.includes(group));
const userMatchAny = users.some((user) => configUsers.includes(user));
updateWorkspaceState(request, {
return updateWorkspaceState(request, {
isDashboardAdmin: groupMatchAny || userMatchAny,
});
};
Expand Down

0 comments on commit fca95e4

Please sign in to comment.