Skip to content

Commit

Permalink
Merge branch 'master' into enhancement/migrate-wazuh-configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Machi3mfl committed Dec 23, 2024
2 parents 2382b23 + 74fb899 commit 3d754b2
Show file tree
Hide file tree
Showing 41 changed files with 1,824 additions and 320 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Support for Wazuh 5.0.0
- Added creation of report definition when creating dashboard by reference and the button to reset the report [#7091](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7091)
- Added a frontend http client to core plugin [#7000](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7000)
- Added serverSecurity service to core plugin [#7026](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7026)
- Added an initilization service to core plugin to run the initilization tasks related to user scope [#7145](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7145)

### Removed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,10 @@ export const PromptCheckIndex = (props: {
);
};

const mapStateToProps = state => {
return {
vulnerabilitiesStatesindexPatternID:
state.appConfig.data['vulnerabilities.pattern'],
};
};
const mapStateToProps = state => ({
vulnerabilitiesStatesindexPatternID:
state.appConfig.data['vulnerabilities.pattern'],
});

export const withVulnerabilitiesStateDataSource = compose(
connect(mapStateToProps),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const initializationTask = {
export const INITIALIZATION_TASK = {
RUN_STATUS: {
NOT_STARTED: 'not_started',
RUNNING: 'running',
Expand Down
8 changes: 4 additions & 4 deletions plugins/wazuh-core/common/services/initialization/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { initializationTask } from './constants';
import { INITIALIZATION_TASK } from './constants';

type RunStatusEnum = (typeof initializationTask)['RUN_STATUS'];
type RunStatusEnum = (typeof INITIALIZATION_TASK)['RUN_STATUS'];

export type InitializationTaskRunStatus = RunStatusEnum[keyof RunStatusEnum];

type RunResultEnum = (typeof initializationTask)['RUN_RESULT'];
type RunResultEnum = (typeof INITIALIZATION_TASK)['RUN_RESULT'];

export type InitializationTaskRunResult = RunResultEnum[keyof RunResultEnum];

type ContextEnum = (typeof initializationTask)['CONTEXT'];
type ContextEnum = (typeof INITIALIZATION_TASK)['CONTEXT'];

export type InitializationTaskContext = ContextEnum[keyof ContextEnum];
6 changes: 4 additions & 2 deletions plugins/wazuh-core/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This plugin provides some core services:

## Frontend

- Configuration: manage the plugins configuration
- Utils
- Constants
- Utils
- Configuration: manage the plugins configuration
- Dashboard Security: manage the security related to Wazuh dashboard
- Server Security: manage the security related to Wazuh server
47 changes: 42 additions & 5 deletions plugins/wazuh-core/public/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { WazuhCorePluginSetup, WazuhCorePluginStart } from './types';
import { setChrome, setCore, setUiSettings } from './plugin-services';
import { ConfigurationStore } from '../common/services/configuration/configuration-store';
import { DashboardSecurity } from './utils/dashboard-security';
import * as hooks from './hooks';
import { UISettingsConfigProvider } from './services/configuration/ui-settings-provider';
import { InitializerConfigProvider } from './services/configuration/initializer-context-provider';
import { EConfigurationProviders } from '../common/constants';
Expand All @@ -16,14 +14,17 @@ import { API_USER_STATUS_RUN_AS } from '../common/api-user-status-run-as';
import { Configuration } from '../common/services/configuration';
import * as utils from './utils';
import * as uiComponents from './components';
import { DashboardSecurity } from './services/dashboard-security';
import * as hooks from './hooks';
import { CoreServerSecurity } from './services';
import { CoreHTTPClient } from './services/http/http-client';

const noop = () => {};

export class WazuhCorePlugin
implements Plugin<WazuhCorePluginSetup, WazuhCorePluginStart>
{
runtime = { setup: {} };
runtime: Record<string, any> = { setup: {}, start: {} };
internal: Record<string, any> = {};
services: Record<string, any> = {};

Expand Down Expand Up @@ -87,6 +88,8 @@ export class WazuhCorePlugin
// Create dashboardSecurity
this.services.dashboardSecurity = new DashboardSecurity(logger, core.http);

this.services.serverSecurity = new CoreServerSecurity(logger);

// Create http
this.services.http = new CoreHTTPClient(logger, {
getTimeout: async () =>
Expand All @@ -98,16 +101,37 @@ export class WazuhCorePlugin
});

// Setup services
await this.services.dashboardSecurity.setup();
this.runtime.setup.dashboardSecurity =
await this.services.dashboardSecurity.setup({
updateData$: this.services.http.server.auth$,
});
this.runtime.setup.http = await this.services.http.setup({ core });

this.runtime.setup.serverSecurity = this.services.serverSecurity.setup({
useDashboardSecurityAccount:
this.runtime.setup.dashboardSecurity.hooks.useDashboardSecurityIsAdmin,
auth$: this.services.http.server.auth$,
useLoadingLogo: () =>
this.runtime.start.serverSecurityDeps.chrome.logos.AnimatedMark,
});

return {
...this.services,
utils,
API_USER_STATUS_RUN_AS,
hooks: {
...hooks,
...this.runtime.setup.dashboardSecurity.hooks,
...this.runtime.setup.serverSecurity.hooks,
},
hocs: {
...this.runtime.setup.dashboardSecurity.hocs,
...this.runtime.setup.serverSecurity.hocs,
},
ui: {
...uiComponents,
...this.runtime.setup.http.ui,
...this.runtime.setup.serverSecurity.ui,
},
};
}
Expand All @@ -122,14 +146,27 @@ export class WazuhCorePlugin
await this.services.dashboardSecurity.start();
await this.services.http.start();

this.runtime.start.serverSecurityDeps = {
chrome: core.chrome,
};

return {
...this.services,
utils,
API_USER_STATUS_RUN_AS,
hooks,
hooks: {
...hooks,
...this.runtime.setup.dashboardSecurity.hooks,
...this.runtime.setup.serverSecurity.hooks,
},
hocs: {
...this.runtime.setup.dashboardSecurity.hocs,
...this.runtime.setup.serverSecurity.hocs,
},
ui: {
...uiComponents,
...this.runtime.setup.http.ui,
...this.runtime.setup.serverSecurity.ui,
},
};
}
Expand Down
82 changes: 82 additions & 0 deletions plugins/wazuh-core/public/services/dashboard-security/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Dashboard security

The `dashboardSecurity` service is created in the core plugin and manage the security related to the Wazuh dashboard.

- Fetch data about the security platform (Wazuh dashboard security enabled or disabled)
- Store information about the current user account data
- administrator
- administrator requirements
- Expose hooks and HOCs for using with ReactJS

## Account data

```ts
export interface DashboardSecurityServiceAccount {
administrator: boolean; // user is considered as administrator of Wazuh dashboard. This can be used for some Wazuh plugin features with no dependency of Wazuh indexer permissions
administrator_requirements: string | null; // display a message about the requirements to be administrator if the user has not an administrator
}
```

## Get account data

See the [account data](#account-data).

### Using the service

```ts
plugins.wazuhCore.dashboardSecurity.account;
```

### In ReactJS components

- hook

```ts
const MyComponent = props => {
const [dashboardSecurityAccount, setDashboardSecurityAccount] =
getWazuhCorePlugin().hooks.useDashboardSecurityAccount();
};
```

- HOC

```ts
const MyComponent = getWazuhCorePlugin().hocs.withDashboardSecurityAccount(
({ dashboardSecurityAccount }) => {
// dashboardSecurityAccount contains the dashboard account data
},
);
```

## Get if the user is an administrator

Get if the user is considered as an administrator for Wazuh plugins.

> NOTE: this consideration is not related to Wazuh indexer permissions.
### Using the service

```ts
plugins.wazuhCore.dashboardSecurity.account.administrator;
```

### In ReactJS components

- hook

```ts
const MyComponent = props => {
const dashboardSecurityAccountAdmin =
getWazuhCorePlugin().hooks.useDashboardSecurityAccountAdmin();
};
```

- HOC

```ts
const MyComponent = getWazuhCorePlugin().hocs.withDashboardSecurityAccountAdmin(
({ dashboardSecurityAccountAdmin }) => {
// dashboardSecurityAccountAdmin contains if the user is admin or not
},
);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { BehaviorSubject } from 'rxjs';
import jwtDecode from 'jwt-decode';
import { Logger } from '../../../common/services/configuration';
import { WAZUH_ROLE_ADMINISTRATOR_ID } from '../../../common/constants';
import { createDashboardSecurityHooks } from './ui/hooks/creator';
import { createDashboardSecurityHOCs } from './ui/hocs/creator';
import {
DashboardSecurityServiceAccount,
DashboardSecurityService,
DashboardSecurityServiceSetupDeps,
DashboardSecurityServiceSetupReturn,
} from './types';

export class DashboardSecurity implements DashboardSecurityService {
private _securityPlatform = '';
public account$: BehaviorSubject<DashboardSecurityServiceAccount>;

constructor(
private readonly logger: Logger,
private readonly http: { get: (path: string) => any },
) {
this.account$ = new BehaviorSubject({
administrator: false,
administrator_requirements: null,
});
}

get securityPlatform() {
return this._securityPlatform;
}

private async fetchCurrentPlatform() {
try {
this.logger.debug('Fetching the security platform');

const response = await this.http.get(
'/elastic/security/current-platform',
);

this._securityPlatform = response.platform;
this.logger.debug(`Security platform: ${this._securityPlatform}`);

return this.securityPlatform;
} catch (error) {
this.logger.error(error.message);
throw error;
}
}

get account() {
return this.account$.getValue();
}

async setup({
updateData$,
}: DashboardSecurityServiceSetupDeps): Promise<DashboardSecurityServiceSetupReturn> {
this.logger.debug('Setup');

let hooks, hocs;

try {
this.logger.debug('Creating the UI utilities');

this.logger.debug('Creating hooks');
hooks = createDashboardSecurityHooks({
account$: this.account$,
});
this.logger.debug('Created hooks');

this.logger.debug('Creating HOCs');
hocs = createDashboardSecurityHOCs(hooks);
this.logger.debug('Created HOCs');
this.logger.debug('Created the UI utilities');
} catch (error) {
this.logger.error(`Error creating the UI utilities: ${error.message}`);
throw error;
}

try {
this.logger.debug('Getting security platform');
await this.fetchCurrentPlatform();
} catch (error) {
this.logger.error(
`Error fetching the current platform: ${error.message}`,
);
}

// Update the dashboard security account information based on server API token
updateData$.subscribe(({ token }: { token: string }) => {
const jwtPayload: {
rbac_roles?: number[];
} | null = token ? jwtDecode(token) : null;

this.account$.next(this.getAccountFromJWTAPIDecodedToken(jwtPayload));
});

return {
hooks,
hocs,
};
}

async start() {}

async stop() {}

private getAccountFromJWTAPIDecodedToken(decodedToken: {
rbac_roles?: number[];
}) {
const isAdministrator = decodedToken?.rbac_roles?.some?.(
role => role === WAZUH_ROLE_ADMINISTRATOR_ID,
);

return {
administrator: isAdministrator,
administrator_requirements: isAdministrator
? null
: 'User has no administrator role in the selected API connection.',
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './dashboard-security';
export * from './types';
Loading

0 comments on commit 3d754b2

Please sign in to comment.