Skip to content

Commit

Permalink
Always show security screen and shows error page when trying to acces…
Browse files Browse the repository at this point in the history
…s forbidden data-source

Signed-off-by: Darshit Chanpura <[email protected]>
  • Loading branch information
DarshitChanpura committed May 17, 2024
1 parent 37c2695 commit 74e9661
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 236 deletions.
32 changes: 32 additions & 0 deletions public/apps/access-error-component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright OpenSearch Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import { EuiPageContent } from '@elastic/eui';
import React from 'react';

interface AccessErrorComponentProps {
dataSourceLabel?: string;
message?: string;
}

export const AccessErrorComponent: React.FC<AccessErrorComponentProps> = (props) => {
const { dataSourceLabel, message = 'You do not have permissions to view this data' } = props;
return (
<EuiPageContent>
{message}
{dataSourceLabel ? ` for ${props.dataSourceLabel}.` : '.'}
</EuiPageContent>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { ViewSettingGroup } from './view-setting-group';
import { DocLinks } from '../../constants';
import { DataSourceContext } from '../../app-router';
import { SecurityPluginTopNavMenu } from '../../top-nav-menu';
import { AccessErrorComponent } from '../../../access-error-component';

interface AuditLoggingProps extends AppDependencies {
fromType: string;
Expand Down Expand Up @@ -137,6 +138,7 @@ export function renderComplianceSettings(config: AuditLoggingSettings) {
export function AuditLogging(props: AuditLoggingProps) {
const [configuration, setConfiguration] = React.useState<AuditLoggingSettings>({});
const { dataSource, setDataSource } = useContext(DataSourceContext)!;
const [errorFlag, setErrorFlag] = React.useState(false);

const onSwitchChange = async () => {
try {
Expand All @@ -156,9 +158,11 @@ export function AuditLogging(props: AuditLoggingProps) {
try {
const auditLogging = await getAuditLogging(props.coreStart.http, dataSource.id);
setConfiguration(auditLogging);
setErrorFlag(false);
} catch (e) {
// TODO: switch to better error handling.
console.log(e);
setErrorFlag(true);
}
};

Expand Down Expand Up @@ -237,7 +241,11 @@ export function AuditLogging(props: AuditLoggingProps) {
setDataSource={setDataSource}
selectedDataSource={dataSource}
/>
{content}
{errorFlag ? (
<AccessErrorComponent dataSourceLabel={dataSource && dataSource.label} />
) : (
content
)}
</div>
);
}
55 changes: 38 additions & 17 deletions public/apps/configuration/panels/auth-view/auth-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ import { getSecurityConfig } from '../../utils/auth-view-utils';
import { InstructionView } from './instruction-view';
import { DataSourceContext } from '../../app-router';
import { SecurityPluginTopNavMenu } from '../../top-nav-menu';
import { AccessErrorComponent } from '../../../access-error-component';

export function AuthView(props: AppDependencies) {
const [authentication, setAuthentication] = React.useState([]);
const [authorization, setAuthorization] = React.useState([]);
const [loading, setLoading] = useState(false);
const { dataSource, setDataSource } = useContext(DataSourceContext)!;
const [errorFlag, setErrorFlag] = React.useState(false);

React.useEffect(() => {
const fetchData = async () => {
Expand All @@ -40,8 +42,10 @@ export function AuthView(props: AppDependencies) {

setAuthentication(config.authc);
setAuthorization(config.authz);
setErrorFlag(false);
} catch (e) {
console.log(e);
setErrorFlag(true);
} finally {
setLoading(false);
}
Expand All @@ -59,7 +63,11 @@ export function AuthView(props: AppDependencies) {
setDataSource={setDataSource}
selectedDataSource={dataSource}
/>
<InstructionView config={props.config} />
{errorFlag ? (
<AccessErrorComponent dataSourceLabel={dataSource && dataSource.label} />
) : (
<InstructionView config={props.config} />
)}
</>
);
}
Expand All @@ -72,22 +80,35 @@ export function AuthView(props: AppDependencies) {
setDataSource={setDataSource}
selectedDataSource={dataSource}
/>
<EuiPageHeader>
<EuiTitle size="l">
<h1>Authentication and authorization</h1>
</EuiTitle>
{props.config.ui.backend_configurable && (
<ExternalLinkButton
href={DocLinks.BackendConfigurationDoc}
text="Manage via config.yml"
/>
)}
</EuiPageHeader>
{/* @ts-ignore */}
<AuthenticationSequencePanel authc={authentication} loading={loading} />
<EuiSpacer size="m" />
{/* @ts-ignore */}
<AuthorizationPanel authz={authorization} loading={loading} config={props.config} />
{errorFlag ? (
<>
<EuiPageHeader>
<EuiTitle size="l">
<h1>Authentication and authorization</h1>
</EuiTitle>
</EuiPageHeader>
<AccessErrorComponent dataSourceLabel={dataSource && dataSource.label} />
</>
) : (
<>
<EuiPageHeader>
<EuiTitle size="l">
<h1>Authentication and authorization</h1>
</EuiTitle>
{props.config.ui.backend_configurable && (
<ExternalLinkButton
href={DocLinks.BackendConfigurationDoc}
text="Manage via config.yml"
/>
)}
</EuiPageHeader>
/* @ts-ignore */
<AuthenticationSequencePanel authc={authentication} loading={loading} />
<EuiSpacer size="m" />
/* @ts-ignore */
<AuthorizationPanel authz={authorization} loading={loading} config={props.config} />
</>
)}
</>
);
}
112 changes: 61 additions & 51 deletions public/apps/configuration/panels/permission-list/permission-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { generateResourceName } from '../../utils/resource-utils';
import { DocLinks } from '../../constants';
import { SecurityPluginTopNavMenu } from '../../top-nav-menu';
import { DataSourceContext } from '../../app-router';
import { AccessErrorComponent } from '../../../access-error-component';

export function renderBooleanToCheckMark(value: boolean): React.ReactNode {
return value ? <EuiIcon type="check" /> : '';
Expand Down Expand Up @@ -361,57 +362,66 @@ export function PermissionList(props: AppDependencies) {
<h1>Permissions</h1>
</EuiTitle>
</EuiPageHeader>
<EuiPageContent>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle size="s">
<h3>
Permissions
<span className="panel-header-count">
{' '}
({Query.execute(query || '', permissionList).length})
</span>
</h3>
</EuiTitle>
<EuiText size="xs" color="subdued">
Permissions are individual actions, such as cluster:admin/snapshot/restore, which lets
you restore snapshots. Action groups are reusable collections of permissions, such as
MANAGE_SNAPSHOTS, which lets you view, take, delete, and restore snapshots. You can
often meet your security needs using the default action groups, but you might find it
convenient to create your own. <ExternalLink href={DocLinks.PermissionsDoc} />
</EuiText>
</EuiPageContentHeaderSection>
<EuiPageContentHeaderSection>
<EuiFlexGroup>
<EuiFlexItem>{actionsMenu}</EuiFlexItem>
<EuiFlexItem>{createActionGroupMenu}</EuiFlexItem>
</EuiFlexGroup>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageBody>
<EuiInMemoryTable
tableLayout={'auto'}
loading={permissionList === [] && !errorFlag}
columns={getColumns(itemIdToExpandedRowMap, actionGroupDict, setItemIdToExpandedRowMap)}
items={permissionList}
itemId={'name'}
pagination
search={{
...SEARCH_OPTIONS,
onChange: (arg) => {
setQuery(arg.query);
return true;
},
}}
selection={{ onSelectionChange: setSelection }}
sorting={{ sort: { field: 'type', direction: 'asc' } }}
error={errorFlag ? 'Load data failed, please check console log for more detail.' : ''}
isExpandable={true}
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
message={showTableStatusMessage(loading, permissionList)}
/>
</EuiPageBody>
</EuiPageContent>
{errorFlag ? (
<AccessErrorComponent dataSourceLabel={dataSource && dataSource.label} />
) : (
<EuiPageContent>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle size="s">
<h3>
Permissions
<span className="panel-header-count">
{' '}
({Query.execute(query || '', permissionList).length})
</span>
</h3>
</EuiTitle>
<EuiText size="xs" color="subdued">
Permissions are individual actions, such as cluster:admin/snapshot/restore, which
lets you restore snapshots. Action groups are reusable collections of permissions,
such as MANAGE_SNAPSHOTS, which lets you view, take, delete, and restore snapshots.
You can often meet your security needs using the default action groups, but you
might find it convenient to create your own.{' '}
<ExternalLink href={DocLinks.PermissionsDoc} />
</EuiText>
</EuiPageContentHeaderSection>
<EuiPageContentHeaderSection>
<EuiFlexGroup>
<EuiFlexItem>{actionsMenu}</EuiFlexItem>
<EuiFlexItem>{createActionGroupMenu}</EuiFlexItem>
</EuiFlexGroup>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageBody>
<EuiInMemoryTable
tableLayout={'auto'}
loading={permissionList === [] && !errorFlag}
columns={getColumns(
itemIdToExpandedRowMap,
actionGroupDict,
setItemIdToExpandedRowMap
)}
items={permissionList}
itemId={'name'}
pagination
search={{
...SEARCH_OPTIONS,
onChange: (arg) => {
setQuery(arg.query);
return true;
},
}}
selection={{ onSelectionChange: setSelection }}
sorting={{ sort: { field: 'type', direction: 'asc' } }}
error={errorFlag ? 'Load data failed, please check console log for more detail.' : ''}
isExpandable={true}
itemIdToExpandedRowMap={itemIdToExpandedRowMap}
message={showTableStatusMessage(loading, permissionList)}
/>
</EuiPageBody>
</EuiPageContent>
)}
{editModal}
{deleteConfirmModal}
<EuiGlobalToastList toasts={toasts} toastLifeTimeMs={10000} dismissToast={removeToast} />
Expand Down
Loading

0 comments on commit 74e9661

Please sign in to comment.