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

Fixed The page of not having permissions appears when you update in a… #3041

Merged
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to the Wazuh app project will be documented in this file.

## Wazuh v4.2.0 - Kibana 7.10.0 , 7.10.2 - Revision 4201

### Added

- Added loading view while the user is logging to prevent permissions prompts [#3041](https://github.com/wazuh/wazuh-kibana-app/pull/3041)

### Fixed

- Fixed unexpected behaviour in Roles mapping [#3028](https://github.com/wazuh/wazuh-kibana-app/pull/3028)
Expand All @@ -17,6 +21,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Creation of index pattern after the default one is changes in Settings [#2985](https://github.com/wazuh/wazuh-kibana-app/pull/2985)
- Added node name of agent list and detail [#3039](https://github.com/wazuh/wazuh-kibana-app/pull/3039)


### Fixed

- Fix rule filter is no applied when you click on a rule id in other module.[#3057](https://github.com/wazuh/wazuh-kibana-app/pull/3057)
Expand Down
6 changes: 4 additions & 2 deletions public/components/common/hocs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export { withUserPermissions, withUserPermissionsRequirements, withUserPermissio

export { withUserRoles, withUserRolesRequirements, withUserRolesPrivate } from './withUserRoles';

export { withUserAuthorizationPrompt } from './withUserAuthorization';
export { withUserAuthorizationPrompt} from './withUserAuthorization';

export { withGlobalBreadcrumb } from './withGlobalBreadcrumb';

Expand All @@ -27,4 +27,6 @@ export { withGuard } from './withGuard';

export { withButtonOpenOnClick } from './withButtonOpenOnClick';

export { withAgentSupportModule } from './withAgentSupportModule';
export { withAgentSupportModule } from './withAgentSupportModule';

export { withUserLogged } from './withUserLogged';
32 changes: 32 additions & 0 deletions public/components/common/hocs/withUserLogged.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Wazuh app - React HOC to manage if the user is logged in
* Copyright (C) 2015-2021 Wazuh, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Find more information about this on the LICENSE file.
*/

import React from "react";
import { useSelector } from 'react-redux';
import { EuiProgress, EuiText,EuiSpacer } from '@elastic/eui';
import { getHttp } from '../../../kibana-services';



export const withUserLogged = (WrappedComponent) => (props) => {
const withUserLogged = useSelector((state)=> state.appStateReducers.withUserLogged);
return withUserLogged ? <WrappedComponent {...props}/> : (
<div className="withUserLogged">
<img src={getHttp().basePath.prepend('/plugins/wazuh/assets/icon_blue.svg')} className="withUserLogged-logo" alt=""></img>
<EuiSpacer size="s" />
<EuiText className="subdued-color">Loading ...</EuiText>
<EuiSpacer size="s" />
<EuiProgress className ="withUserLogged-loader" size="xs" color="primary" />
</div>
)
}

3 changes: 2 additions & 1 deletion public/components/common/modules/main-mitre.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@

import React, { Component } from 'react';
import { Mitre } from '../../../components/overview/mitre/mitre';
import { withUserAuthorizationPrompt } from '../hocs';
import { withUserAuthorizationPrompt, withUserLogged } from '../hocs';
import { compose } from 'redux';

export const MainMitre = compose(
withUserLogged,
withUserAuthorizationPrompt([
{ action: 'mitre:read', resource: '*:*:*' },
])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ import store from '../../../../../redux/store';
import { updateCurrentAgentData } from '../../../../../redux/actions/appStateActions';
import { WzRequest } from '../../../../../react-services';
import { getAngularModule } from '../../../../../kibana-services';
import { withReduxProvider, withUserAuthorizationPrompt } from "../../../hocs";
import { withReduxProvider, withUserAuthorizationPrompt, withUserLogged } from "../../../hocs";
import { compose } from 'redux';

export const ScaScan = compose(
withReduxProvider,
withUserLogged,
withUserAuthorizationPrompt([{action: 'agent:read', resource: 'agent:id:*'}, {action: 'sca:read', resource: 'agent:id:*'}])
)(class ScaScan extends Component {
_isMount = false;
Expand Down
3 changes: 2 additions & 1 deletion public/components/security/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { API_USER_STATUS_RUN_AS } from '../../../server/lib/cache-api-user-has-r
import { AppState } from '../../react-services/app-state';
import { ErrorHandler } from '../../react-services/error-handler';
import { RolesMapping } from './roles-mapping/roles-mapping';
import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt } from '../common/hocs';
import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt, withUserLogged } from '../common/hocs';
import { compose } from 'redux';
import { WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../../common/constants';
import { updateSecuritySection } from '../../redux/actions/securityActions';
Expand Down Expand Up @@ -50,6 +50,7 @@ const tabs = [
export const WzSecurity = compose(
withReduxProvider,
withGlobalBreadcrumb([{ text: '' }, { text: 'Security' }]),
withUserLogged,
withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])
)(() => {
const dispatch = useDispatch();
Expand Down
3 changes: 2 additions & 1 deletion public/controllers/agent/components/agents-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ import { FilterHandler } from '../../../utils/filter-handler';
import { TabVisualizations } from '../../../factories/tab-visualizations';
import { WazuhConfig } from './../../../react-services/wazuh-config.js';
import { WzDatePicker } from '../../../components/wz-date-picker/wz-date-picker';
import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt } from '../../../components/common/hocs';
import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt, withUserLogged } from '../../../components/common/hocs';
import { compose } from 'redux';

export const AgentsPreview = compose(
withReduxProvider,
withGlobalBreadcrumb([{ text: '' }, { text: 'Agents' }]),
withUserLogged,
withUserAuthorizationPrompt([[{action: 'agent:read', resource: 'agent:id:*'},{action: 'agent:read', resource: 'agent:group:*'}]])
)(class AgentsPreview extends Component {
_isMount = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import { withRenderIfOrWrapped } from './util-hocs/render-if';
import { WzAgentNeverConnectedPrompt } from './configuration-no-agent';
import WzConfigurationPath from './util-components/configuration-path';
import WzRefreshClusterInfoButton from './util-components/refresh-cluster-info-button';
import { withUserAuthorizationPrompt } from '../../../../../components/common/hocs';
import { withUserAuthorizationPrompt, withUserLogged } from '../../../../../components/common/hocs';

import { clusterNodes, clusterReq } from './utils/wz-fetch';
import {
Expand Down Expand Up @@ -415,6 +415,7 @@ const mapDispatchToProps = dispatch => ({
});

export default compose(
withUserLogged,
withUserAuthorizationPrompt((props) => [props.agent.id === '000' ? {action: 'manager:read', resource: '*:*:*'} : {action: 'agent:read', resource: `agent:id:${props.agent.id}`}]), //TODO: this need cluster:read permission but manager/cluster is managed in WzConfigurationSwitch component
withRenderIfOrWrapped((props) => props.agent.status === 'never_connected', WzAgentNeverConnectedPrompt),
connect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import WzGroupsActionButtonsAgents from './actions-buttons-agents';
import WzGroupsActionButtonsFiles from './actions-buttons-files';
import WzGroupAgentsTable from './group-agents-table';
import WzGroupFilesTable from './group-files-table';
import { withUserAuthorizationPrompt } from '../../../../../components/common/hocs';
import { withUserAuthorizationPrompt, withUserLogged } from '../../../../../components/common/hocs';
import { compose } from 'redux';

class WzGroupDetail extends Component {
Expand Down Expand Up @@ -191,5 +191,6 @@ export default compose(
mapStateToProps,
mapDispatchToProps
),
withUserLogged,
withUserAuthorizationPrompt((props) => [{action: 'group:read', resource: `group:id:${props.state.itemDetail.name}`}]),
)(WzGroupDetail);
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import WzGroupsTable from './groups-table';
import WzGroupsActionButtons from './actions-buttons-main';

import { connect } from 'react-redux';
import { withUserAuthorizationPrompt } from '../../../../../components/common/hocs'
import { withUserAuthorizationPrompt, withUserLogged } from '../../../../../components/common/hocs'
import { compose } from 'redux';

export class WzGroupsOverview extends Component {
Expand Down Expand Up @@ -77,6 +77,7 @@ const mapStateToProps = state => {


export default compose(
withUserLogged,
withUserAuthorizationPrompt([{action: 'group:read', resource: 'group:id:*'}]),
connect(
mapStateToProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import 'brace/theme/github';
import exportCsv from '../../../../../react-services/wz-csv';
import { getToasts } from '../../../../../kibana-services';
import { WzRequest } from '../../../../../react-services/wz-request';
import { withUserAuthorizationPrompt, withGlobalBreadcrumb } from '../../../../../components/common/hocs';
import { withUserAuthorizationPrompt, withGlobalBreadcrumb , withUserLogged} from '../../../../../components/common/hocs';
import { compose } from 'redux';
import { WzFieldSearch } from '../../../../../components/wz-field-search-bar/wz-field-search-bar';

Expand All @@ -41,6 +41,7 @@ export default compose(
{ text: 'Management', href: '/app/wazuh#/manager' },
{ text: 'Logs' }
]),
withUserLogged,
withUserAuthorizationPrompt([{action: 'cluster:status', resource: '*:*:*'}, {action: 'cluster:read', resource: 'node:id:*'}])
)
(class WzLogs extends Component {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import WzRulesetTable from './ruleset-table';
import WzRulesetSearchBar from './ruleset-search-bar';
import WzRulesetActionButtons from './actions-buttons';
import './ruleset-overview.scss';
import { withUserAuthorizationPrompt, withGlobalBreadcrumb } from '../../../../../components/common/hocs';
import { withUserAuthorizationPrompt, withGlobalBreadcrumb, withUserLogged } from '../../../../../components/common/hocs';
import { compose } from 'redux';
import { resourceDictionary } from './utils/ruleset-handler';

Expand Down Expand Up @@ -96,5 +96,6 @@ export default compose(
{ text: sectionNames[props.state.section] }
];
}),
withUserLogged,
withUserAuthorizationPrompt((props) => [{action: `${props.state.section}:read`, resource: resourceDictionary[props.state.section].permissionResource('*')}])
)(WzRulesetOverview);
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import WzStatusAgentInfo from './status-agent-info';

import { getToasts } from '../../../../../kibana-services';

import { withUserAuthorizationPrompt, withGlobalBreadcrumb } from '../../../../../components/common/hocs';
import { withUserAuthorizationPrompt, withGlobalBreadcrumb, withUserLogged } from '../../../../../components/common/hocs';
import { compose } from 'redux';
import { ToastNotifications } from '../../../../../react-services/toast-notifications';

Expand Down Expand Up @@ -253,6 +253,7 @@ export default compose(
{ text: 'Management', href: '/app/wazuh#/manager' },
{ text: 'Status' }
]),
withUserLogged,
withUserAuthorizationPrompt([{ action: 'agent:read', resource: 'agent:id:*' }, { action: 'manager:read', resource: '*:*:*' }, { action: 'cluster:read', resource: 'node:id:*' }]),
connect(
mapStateToProps,
Expand Down
3 changes: 2 additions & 1 deletion public/react-services/wz-authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { WzRequest } from './wz-request';
import { AppState } from './app-state';
import jwtDecode from 'jwt-decode';
import store from '../redux/store';
import { updateUserPermissions, updateUserRoles } from '../redux/actions/appStateActions';
import { updateUserPermissions, updateUserRoles, updateWithUserLogged } from '../redux/actions/appStateActions';
import { WAZUH_ROLE_ADMINISTRATOR_ID, WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../common/constants';
import { getToasts } from '../kibana-services';

Expand Down Expand Up @@ -54,6 +54,7 @@ export class WzAuthentication{
// Dispatch actions to set permissions and roles
store.dispatch(updateUserPermissions(userPolicies));
store.dispatch(updateUserRoles(WzAuthentication.mapUserRolesIDToAdministratorRole(jwtPayload.rbac_roles || [])));
store.dispatch(updateWithUserLogged(true));
}catch(error){
getToasts().add({
color: 'danger',
Expand Down
11 changes: 11 additions & 0 deletions public/redux/actions/appStateActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,14 @@ export const updateClusterStatus = (clusterStatus) => {
clusterStatus,
};
};

/**
* Updates the status of whether the user is logged in
* @param withUserLogged
*/
export const updateWithUserLogged = (withUserLogged) => {
return {
type: 'UPDATE_WITH_USER_LOGGED',
withUserLogged,
};
};
8 changes: 8 additions & 0 deletions public/redux/reducers/appStateReducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const initialState = {
status: false,
contextConfigServer: 'manager',
},
withUserLogged: false,
};

const appStateReducers = (state = initialState, action) => {
Expand Down Expand Up @@ -131,6 +132,13 @@ const appStateReducers = (state = initialState, action) => {
};
}

if (action.type === 'UPDATE_WITH_USER_LOGGED') {
return {
...state,
withUserLogged: action.withUserLogged,
};
}

return state;
};

Expand Down
20 changes: 20 additions & 0 deletions public/styles/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1675,4 +1675,24 @@ iframe.width-changed {

.dscFieldDetails__barContainer {
min-width: 0;
}

.withUserLogged {
padding-top: 5%;
width: 250px;
margin: 0 auto;
text-align: center;
}

.withUserLogged-logo{
width: 40px;
height: 40px;
margin: 0 auto;

filter: brightness(0) saturate(100%) invert(24%) sepia(97%) saturate(1757%) hue-rotate(186deg) brightness(94%) contrast(101%);
}

.withUserLogged-loader{
width: 20px;
margin: 0 auto;
}