Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2.x] Allow patch on allowedRoles #1144

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/constants/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const OBSERVABILITY_BASE = '/api/observability';
export const INTEGRATIONS_BASE = '/api/integrations';
export const JOBS_BASE = '/query/jobs';
export const DATACONNECTIONS_BASE = '/api/dataconnections';
export const EDIT = '/edit';
export const SECURITY_ROLES = '/api/v1/configuration/roles';
export const EVENT_ANALYTICS = '/event_analytics';
export const SAVED_OBJECTS = '/saved_objects';
export const SAVED_QUERY = '/query';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,25 @@ exports[`Data Connection Page test Renders Prometheus data connection page with
Control which OpenSearch users have access to this data source.
</div>
</div>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<button
class="euiButton euiButton--primary euiButton--fill"
data-test-subj="createButton"
type="button"
>
<span
class="euiButtonContent euiButton__content"
>
<span
class="euiButton__text"
>
Edit
</span>
</span>
</button>
</div>
</div>
<hr
class="euiHorizontalRule euiHorizontalRule--full euiHorizontalRule--marginLarge"
Expand Down Expand Up @@ -763,6 +782,25 @@ exports[`Data Connection Page test Renders S3 data connection page with data 1`]
Control which OpenSearch users have access to this data source.
</div>
</div>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<button
class="euiButton euiButton--primary euiButton--fill"
data-test-subj="createButton"
type="button"
>
<span
class="euiButtonContent euiButton__content"
>
<span
class="euiButton__text"
>
Edit
</span>
</span>
</button>
</div>
</div>
<hr
class="euiHorizontalRule euiHorizontalRule--full euiHorizontalRule--marginLarge"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiHorizontalRule } from '@elastic/eui';
import React, { useState } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiText,
EuiHorizontalRule,
EuiButton,
} from '@elastic/eui';
import React, { useEffect, useState } from 'react';
import { EuiPanel } from '@elastic/eui';
import { ConnectionManagementCallout } from './connection_management_callout';
import { Role } from '../../../../../common/types/data_connections';
import { coreRefs } from '../../../../../public/framework/core_refs';
import { QueryPermissionsConfiguration } from '../new/query_permissions';
import { DATACONNECTIONS_BASE, EDIT, SECURITY_ROLES } from '../../../../../common/constants/shared';
import { SaveOrCancel } from '../save_or_cancel';

interface AccessControlTabProps {
dataConnection: string;
Expand All @@ -17,6 +28,24 @@ interface AccessControlTabProps {
}

export const AccessControlTab = (props: AccessControlTabProps) => {
const [mode, setMode] = useState<'view' | 'edit'>('view');
const [roles, setRoles] = useState<Role[]>([]);
const [hasSecurityAccess, setHasSecurityAccess] = useState(true);
const { http } = coreRefs;

useEffect(() => {
http!
.get(SECURITY_ROLES)
.then((data) =>
setRoles(
Object.keys(data.data).map((key) => {
return { label: key };
})
)
)
.catch((err) => setHasSecurityAccess(false));
}, []);

const [selectedQueryPermissionRoles, setSelectedQueryPermissionRoles] = useState<Role[]>(
props.allowedRoles.map((role) => {
return { label: role };
Expand Down Expand Up @@ -44,6 +73,30 @@ export const AccessControlTab = (props: AccessControlTabProps) => {
);
};

const EditAccessControlDetails = () => {
return (
<EuiFlexGroup direction="column">
<QueryPermissionsConfiguration
roles={roles}
selectedRoles={selectedQueryPermissionRoles}
setSelectedRoles={setSelectedQueryPermissionRoles}
layout={'vertical'}
hasSecurityAccess={hasSecurityAccess}
/>
</EuiFlexGroup>
);
};

const saveChanges = () => {
http!.post(`${DATACONNECTIONS_BASE}${EDIT}`, {
body: JSON.stringify({
name: props.dataConnection,
allowedRoles: selectedQueryPermissionRoles.map((role) => role.label),
}),
});
setMode('view');
};

const AccessControlHeader = () => {
return (
<EuiFlexGroup direction="row">
Expand All @@ -53,6 +106,15 @@ export const AccessControlTab = (props: AccessControlTabProps) => {
Control which OpenSearch users have access to this data source.
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="createButton"
onClick={() => setMode(mode === 'view' ? 'edit' : 'view')}
fill={mode === 'view' ? true : false}
>
{mode === 'view' ? 'Edit' : 'Cancel'}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
);
};
Expand All @@ -65,9 +127,17 @@ export const AccessControlTab = (props: AccessControlTabProps) => {
<EuiPanel>
<AccessControlHeader />
<EuiHorizontalRule />
<AccessControlDetails />
{mode === 'view' ? <AccessControlDetails /> : <EditAccessControlDetails />}
</EuiPanel>
<EuiSpacer />
{mode === 'edit' && (
<SaveOrCancel
onCancel={() => {
setMode('view');
}}
onSave={saveChanges}
/>
)}
<EuiSpacer />
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
import React, { useCallback, useEffect, useState } from 'react';
import { ConfigureS3Datasource } from './configure_s3_datasource';
import { coreRefs } from '../../../../../public/framework/core_refs';
import { DATACONNECTIONS_BASE } from '../../../../../common/constants/shared';
import { DATACONNECTIONS_BASE, SECURITY_ROLES } from '../../../../../common/constants/shared';
import { ReviewS3Datasource } from './review_s3_datasource_configuration';
import { useToast } from '../../../../../public/components/common/toast';
import { DatasourceType, Role } from '../../../../../common/types/data_connections';
Expand Down Expand Up @@ -67,7 +67,7 @@ export function Configure(props: ConfigureDatasourceProps) {

useEffect(() => {
http!
.get('/api/v1/configuration/roles')
.get(SECURITY_ROLES)
.then((data) =>
setRoles(
Object.keys(data.data).map((key) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ export const QueryPermissionsConfiguration = (props: PermissionsConfigurationPro
<EuiRadioGroup
options={accessLevelOptions}
idSelected={selectedAccessLevel}
onChange={(id) => setSelectedAccessLevel(id)}
onChange={(id) => {
if (id === QUERY_ALL) {
setSelectedRoles([]);
}
setSelectedAccessLevel(id);
}}
name="query-radio-group"
legend={{
children: <span>Query access level</span>,
Expand Down
2 changes: 1 addition & 1 deletion server/adaptors/ppl_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const PPLPlugin = function (Client, config, components) {
fmt: `${OPENSEARCH_DATACONNECTIONS_API.DATACONNECTION}`,
},
needBody: true,
method: 'PUT',
method: 'PATCH',
});

ppl.getDataConnections = ca({
Expand Down
10 changes: 3 additions & 7 deletions server/routes/data_connections/data_connections_router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
IRouter,
ResponseError,
} from '../../../../../src/core/server';
import { DATACONNECTIONS_BASE } from '../../../common/constants/shared';
import { DATACONNECTIONS_BASE, EDIT } from '../../../common/constants/shared';

export function registerDataConnectionsRoute(router: IRouter) {
router.get(
Expand Down Expand Up @@ -70,15 +70,13 @@ export function registerDataConnectionsRoute(router: IRouter) {
}
);

router.put(
router.post(
{
path: `${DATACONNECTIONS_BASE}`,
path: `${DATACONNECTIONS_BASE}${EDIT}`,
validate: {
body: schema.object({
name: schema.string(),
connector: schema.string(),
allowedRoles: schema.arrayOf(schema.string()),
properties: schema.any(),
}),
},
},
Expand All @@ -89,9 +87,7 @@ export function registerDataConnectionsRoute(router: IRouter) {
.callAsCurrentUser('ppl.modifyDataConnection', {
body: {
name: request.body.name,
connector: request.body.connector,
allowedRoles: request.body.allowedRoles,
properties: request.body.properties,
},
});
return response.ok({
Expand Down
Loading