Skip to content

Commit

Permalink
Update dwh types (#21077)
Browse files Browse the repository at this point in the history
* update types

* check indexset section permissions

* check permissions for destination sections

* adjust data routing and stream rule match permissions

* add filter permissions check

* handle case indexSet undefined

* fix eslint issue

---------

Co-authored-by: Laura <[email protected]>
Co-authored-by: Mohamed OULD HOCINE <[email protected]>
Co-authored-by: Maxwell <[email protected]>
Co-authored-by: Mohamed Ould Hocine <[email protected]>
  • Loading branch information
5 people authored Dec 11, 2024
1 parent a18ee23 commit 414b079
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,17 @@ export type FieldValueProvider = {
}

interface PluginDataWarehouse {
StreamDataWarehouse: React.ComponentType,
StreamDataWarehouse: React.ComponentType<{
permissions: Immutable.List<string>,
}>,
DataWarehouseStatus: React.ComponentType<{
datawareHouseEnabled: boolean;
}>,
DataWarehouseJournal: React.ComponentType<{
nodeId: string,
}>,
DataWarehouseJobs: React.ComponentType<{
permissions: Immutable.List<string>,
streamId: string,
}>,
StreamIlluminateProcessingSection: React.ComponentType<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import React, { useState } from 'react';
import styled, { css } from 'styled-components';

import { Input } from 'components/bootstrap';
import ConfirmDialog from 'components/common/ConfirmDialog';
import UserNotification from 'util/UserNotification';
import useCurrentUser from 'hooks/useCurrentUser';
import StreamsStore, { type Stream } from 'stores/streams/StreamsStore';

import ConfirmDialog from '../common/ConfirmDialog';
import { isPermitted } from 'util/PermissionsMixin';

const StreamRuleConnector = styled.div(({ theme }) => css`
margin-top: 10px;
Expand Down Expand Up @@ -53,7 +54,8 @@ type Props = {

const MatchingTypeSwitcher = ({ stream, onChange }: Props) => {
const [matchingType, setMatchingType] = useState<'AND'|'OR'|undefined>(undefined);
const disabled = stream.is_default || !stream.is_editable;
const currentUser = useCurrentUser();
const disabled = stream.is_default || !stream.is_editable || !isPermitted(currentUser.permissions, `streams:edit:${stream.id}`);

const handleTypeChange = (newValue: 'AND'|'OR') => {
StreamsStore.update(stream.id, { matching_type: newValue }, (response) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import * as React from 'react';

import { Alert } from 'components/bootstrap';

type Props = {
sectionName: string,
};

const DestinationPermissionAlert = ({ sectionName }: Props) => (
<Alert bsStyle="danger">
{`You currently do not have the permissions to view or manage ${sectionName} destination.`}
</Alert>
);

export default DestinationPermissionAlert;
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import * as React from 'react';
import { PluginStore } from 'graylog-web-plugin/plugin';
import styled, { css } from 'styled-components';

import { IfPermitted } from 'components/common';
import type { Stream } from 'stores/streams/StreamsStore';
import useSingleIndexSet from 'components/indices/hooks/useSingleIndexSet';
import DestinationOutputs from 'components/streams/StreamDetails/routing-destination/DestinationOutputs';
import DestinationIndexSetSection from 'components/streams/StreamDetails/routing-destination/DestinationIndexSetSection';
import useCurrentUser from 'hooks/useCurrentUser';
import { isPermitted } from 'util/PermissionsMixin';

import DestinationPermissionAlert from './DestinationPermissionAlert';

type Props = {
stream: Stream;
Expand All @@ -36,17 +38,17 @@ const Container = styled.div(({ theme }) => css`
`);

const StreamDataRoutingDestinations = ({ stream }: Props) => {
const { index_set_id: indexSetId } = stream;
const { data: indexSet, isSuccess } = useSingleIndexSet(indexSetId);
const currentUser = useCurrentUser();
const StreamDataWarehouseComponent = PluginStore.exports('dataWarehouse')?.[0]?.StreamDataWarehouse;

const destinationIndexset = isPermitted(currentUser.permissions, ['indexsets:read']) ? <DestinationIndexSetSection stream={stream} /> : <DestinationPermissionAlert sectionName="Index Set" />;
const destinationOutput = isPermitted(currentUser.permissions, ['output:read']) ? <DestinationOutputs stream={stream} /> : <DestinationPermissionAlert sectionName="Outputs" />;

return (
<Container>
{isSuccess && <DestinationIndexSetSection indexSet={indexSet} stream={stream} />}
{StreamDataWarehouseComponent && <StreamDataWarehouseComponent />}
<IfPermitted permissions="outputs:edit">
<DestinationOutputs stream={stream} />
</IfPermitted>
{destinationIndexset}
{StreamDataWarehouseComponent && <StreamDataWarehouseComponent permissions={currentUser.permissions} />}
{destinationOutput}
</Container>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import useHistory from 'routing/useHistory';
import useSendTelemetry from 'logic/telemetry/useSendTelemetry';
import useQuery from 'routing/useQuery';
import { TELEMETRY_EVENT_TYPE } from 'logic/telemetry/Constants';
import useCurrentUser from 'hooks/useCurrentUser';

import StreamDataRoutingIntake from './StreamDataRoutingIntake';
import StreamDataRoutingProcessing from './StreamDataRoutingProcessing';
Expand Down Expand Up @@ -163,6 +164,7 @@ const StreamDetails = ({ stream }: Props) => {
const { indexSets } = useStore(IndexSetsStore);
const queryClient = useQueryClient();
const history = useHistory();
const currentUser = useCurrentUser();
const sendTelemetry = useSendTelemetry();

const updateURLStepQueryParam = (nextSegment: DetailsSegment) => {
Expand Down Expand Up @@ -199,7 +201,7 @@ const StreamDetails = ({ stream }: Props) => {

return (
<>
{DataWarehouseJobComponent && <DataWarehouseJobComponent streamId={stream.id} />}
{DataWarehouseJobComponent && <DataWarehouseJobComponent permissions={currentUser.permissions} streamId={stream.id} />}
<Container>
<Header>
<LeftCol>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,31 @@ type Props = {
destinationType: string,
paginatedFilters: PaginatedListType<StreamOutputFilterRule>,
onPaginationChange: (newPage: number, newPerPage: number) => void,
requiredPermissions: Array<string>,
};
const _headerCellFormatter = (header: string) => (<th>{header}</th>);
const buildFilterItem = (destinationType: string) => (filter: StreamOutputFilterRule) => (
const buildFilterItem = (destinationType: string, requiredPermissions: Array<string>) => (filter: StreamOutputFilterRule) => (
<tr key={filter.id}>
<td>
{filter.title}
<StyledText>{filter.description}</StyledText>
</td>
<td><FilterStatusCell filterOutputRule={filter} /></td>
<td><FilterActions filterRule={filter} destinationType={destinationType} /></td>
<td>
<IfPermitted permissions={requiredPermissions}>
<FilterActions filterRule={filter} destinationType={destinationType} />
</IfPermitted>
</td>
</tr>
);

const FilterRulesList = ({ streamId, destinationType, paginatedFilters, onPaginationChange }: Props) => {
const FilterRulesList = ({ streamId, destinationType, paginatedFilters, onPaginationChange, requiredPermissions }: Props) => {
const { list: filters, pagination: { total } } = paginatedFilters;

return (
<StyledSectionComponent title="Filter Rules"
headerActions={(
<IfPermitted permissions="">
<IfPermitted permissions={requiredPermissions}>
<FilterRuleEditButton filterRule={{ stream_id: streamId }}
destinationType={destinationType}
streamId={streamId} />
Expand All @@ -112,7 +117,7 @@ const FilterRulesList = ({ streamId, destinationType, paginatedFilters, onPagina
sortByKey="title"
noDataText={<NoSearchResult>No filter have been found.</NoSearchResult>}
rows={filters.toJS()}
dataRowFormatter={buildFilterItem(destinationType)} />
dataRowFormatter={buildFilterItem(destinationType, requiredPermissions)} />
</PaginatedList>
</StyledSectionComponent>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import styled, { css } from 'styled-components';

import { ARCHIVE_RETENTION_STRATEGY } from 'stores/indices/IndicesStore';
import { Icon, Section, Spinner } from 'components/common';
import { IndexSetsStore, type IndexSet } from 'stores/indices/IndexSetsStore';
import { IndexSetsStore } from 'stores/indices/IndexSetsStore';
import { Table, Button, Alert } from 'components/bootstrap';
import { LinkContainer } from 'components/common/router';
import Routes from 'routing/Routes';
Expand All @@ -36,29 +36,30 @@ import SectionCountLabel from 'components/streams/StreamDetails/SectionCountLabe
import useIndexSetStats from 'hooks/useIndexSetStats';
import { DEFAULT_PAGINATION } from 'stores/PaginationTypes';
import useIndexerOverview from 'hooks/useIndexerOverview';
import useSingleIndexSet from 'components/indices/hooks/useSingleIndexSet';

import IndexSetOldestMessageCell from './IndexSetOldestMessageCell';

type Props = {
indexSet: IndexSet,
stream: Stream,
};

const ActionButtonsWrap = styled.span(() => css`
float: right;
`);

const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
const DestinationIndexSetSection = ({ stream }: Props) => {
const [pagination, setPagination] = useState(DEFAULT_PAGINATION);
const archivingEnabled = indexSet.retention_strategy_class === ARCHIVE_RETENTION_STRATEGY || indexSet?.data_tiering?.archive_before_deletion;
const { data: indexSet, isInitialLoading: isLoadingIndexSet } = useSingleIndexSet(stream.index_set_id);
const archivingEnabled = indexSet?.retention_strategy_class === ARCHIVE_RETENTION_STRATEGY || indexSet?.data_tiering?.archive_before_deletion;
const { indexSets } = useStore(IndexSetsStore);
const { data: streamOutputFilters, isLoading: isLoadingStreamOutputFilters } = useStreamOutputFilters(stream.id, 'indexer', pagination);
const { data: indexerOverview, isSuccess: isLoadingIndexerOverviewSuccess } = useIndexerOverview(indexSet.id);
const { data: indexerOverview, isSuccess: isLoadingIndexerOverviewSuccess } = useIndexerOverview(stream.index_set_id);
/* eslint-disable no-constant-condition */
const title = true ? 'Enabled' : 'Disabled'; // TODO use api to check if enabled
const { data: indexSetStats, isSuccess: isStatsLoaded } = useIndexSetStats(indexSet.id);
const { data: indexSetStats, isSuccess: isStatsLoaded } = useIndexSetStats(stream.index_set_id);

if (isLoadingStreamOutputFilters) {
if (isLoadingStreamOutputFilters || isLoadingIndexSet) {
<Spinner />;
}

Expand All @@ -84,7 +85,7 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
</>
)}
actions={(
<IndexSetUpdateForm initialValues={{ index_set_id: indexSet.id }}
<IndexSetUpdateForm initialValues={{ index_set_id: stream.index_set_id }}
indexSets={indexSets}
stream={stream} />
)}>
Expand All @@ -103,26 +104,28 @@ const DestinationIndexSetSection = ({ indexSet, stream }: Props) => {
</tr>
</thead>
<tbody>
<tr>
<td>{indexSet?.title}</td>
<td>{(isStatsLoaded && indexSetStats?.size) ? NumberUtils.formatBytes(indexSetStats.size) : 0}</td>
<td>{isLoadingIndexerOverviewSuccess && <IndexSetOldestMessageCell index={indexerOverview?.indices?.pop()} />}</td>
<td>
<IndexSetArchivingCell isArchivingEnabled={archivingEnabled} streamId={stream.id} />
</td>
<td>
<ActionButtonsWrap>
<LinkContainer to={Routes.SYSTEM.INDEX_SETS.SHOW(indexSet.id)}>
<Button bsStyle="default"
bsSize="xsmall"
onClick={() => {}}
title="View index set">
<Icon name="pageview" type="regular" />
</Button>
</LinkContainer>
</ActionButtonsWrap>
</td>
</tr>
{indexSet && (
<tr>
<td>{indexSet?.title}</td>
<td>{(isStatsLoaded && indexSetStats?.size) ? NumberUtils.formatBytes(indexSetStats.size) : 0}</td>
<td>{isLoadingIndexerOverviewSuccess && <IndexSetOldestMessageCell index={indexerOverview?.indices?.pop()} />}</td>
<td>
<IndexSetArchivingCell isArchivingEnabled={archivingEnabled} streamId={stream.id} />
</td>
<td>
<ActionButtonsWrap>
<LinkContainer to={Routes.SYSTEM.INDEX_SETS.SHOW(indexSet?.id)}>
<Button bsStyle="default"
bsSize="xsmall"
onClick={() => {}}
title="View index set">
<Icon name="pageview" type="regular" />
</Button>
</LinkContainer>
</ActionButtonsWrap>
</td>
</tr>
)}
</tbody>
</Table>
{streamOutputFilters && (<IndexSetFilters streamId={stream.id} paginatedFilters={streamOutputFilters} onPaginationChange={onPaginationChange} />)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const IndexSetFilters = ({ streamId, paginatedFilters, onPaginationChange }: Pro
<FilterRulesList streamId={streamId}
paginatedFilters={paginatedFilters}
destinationType="indexer"
onPaginationChange={onPaginationChange} />
onPaginationChange={onPaginationChange}
requiredPermissions={['indexsets:edit']} />

);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const StreamActions = ({

return (
<ButtonToolbar>
<IfPermitted permissions={`streams:edit:${stream.id}`}>
<IfPermitted permissions={`streams:read:${stream.id}`}>
<LinkContainer to={Routes.stream_view(stream.id)}>
<Button disabled={isNotEditable}
bsStyle="primary"
Expand Down

0 comments on commit 414b079

Please sign in to comment.