From fb7ef7f309401bf886508da371be338d745ccc6a Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Tue, 14 Jan 2025 20:12:24 +0100
Subject: [PATCH 01/30] Plugin created
---
docker/osd-dev/dev.yml | 1 +
plugins/wazuh-security-policies/.i18nrc.json | 7 ++
plugins/wazuh-security-policies/README.md | 22 ++++
.../wazuh-security-policies/common/index.ts | 2 +
.../opensearch_dashboards.json | 9 ++
plugins/wazuh-security-policies/package.json | 10 ++
.../public/application.tsx | 23 ++++
.../public/components/app.tsx | 116 ++++++++++++++++++
.../wazuh-security-policies/public/index.scss | 1 +
.../wazuh-security-policies/public/index.ts | 13 ++
.../wazuh-security-policies/public/plugin.ts | 64 ++++++++++
.../wazuh-security-policies/public/types.ts | 11 ++
.../wazuh-security-policies/server/index.ts | 14 +++
.../wazuh-security-policies/server/plugin.ts | 41 +++++++
.../server/routes/index.ts | 16 +++
.../wazuh-security-policies/server/types.ts | 5 +
.../translations/ja-JP.json | 81 ++++++++++++
plugins/wazuh-security-policies/tsconfig.json | 16 +++
plugins/wazuh-security-policies/yarn.lock | 4 +
19 files changed, 456 insertions(+)
create mode 100644 plugins/wazuh-security-policies/.i18nrc.json
create mode 100755 plugins/wazuh-security-policies/README.md
create mode 100644 plugins/wazuh-security-policies/common/index.ts
create mode 100644 plugins/wazuh-security-policies/opensearch_dashboards.json
create mode 100644 plugins/wazuh-security-policies/package.json
create mode 100644 plugins/wazuh-security-policies/public/application.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/app.tsx
create mode 100644 plugins/wazuh-security-policies/public/index.scss
create mode 100644 plugins/wazuh-security-policies/public/index.ts
create mode 100644 plugins/wazuh-security-policies/public/plugin.ts
create mode 100644 plugins/wazuh-security-policies/public/types.ts
create mode 100644 plugins/wazuh-security-policies/server/index.ts
create mode 100644 plugins/wazuh-security-policies/server/plugin.ts
create mode 100644 plugins/wazuh-security-policies/server/routes/index.ts
create mode 100644 plugins/wazuh-security-policies/server/types.ts
create mode 100644 plugins/wazuh-security-policies/translations/ja-JP.json
create mode 100644 plugins/wazuh-security-policies/tsconfig.json
create mode 100644 plugins/wazuh-security-policies/yarn.lock
diff --git a/docker/osd-dev/dev.yml b/docker/osd-dev/dev.yml
index c07d2b6c6d..fdf249c453 100755
--- a/docker/osd-dev/dev.yml
+++ b/docker/osd-dev/dev.yml
@@ -244,6 +244,7 @@ services:
- '${SRC}/main:/home/node/kbn/plugins/main'
- '${SRC}/wazuh-core:/home/node/kbn/plugins/wazuh-core'
- '${SRC}/wazuh-check-updates:/home/node/kbn/plugins/wazuh-check-updates'
+ - '${SRC}/wazuh-security-policies:/home/node/kbn/plugins/wazuh-security-policies'
- '${SRC}/wazuh-engine:/home/node/kbn/plugins/wazuh-engine'
- '${SRC}/wazuh-fleet:/home/node/kbn/plugins/wazuh-fleet'
- wd_certs:/home/node/kbn/certs/
diff --git a/plugins/wazuh-security-policies/.i18nrc.json b/plugins/wazuh-security-policies/.i18nrc.json
new file mode 100644
index 0000000000..5e344386a4
--- /dev/null
+++ b/plugins/wazuh-security-policies/.i18nrc.json
@@ -0,0 +1,7 @@
+{
+ "prefix": "wazuhSecurityPolicies",
+ "paths": {
+ "wazuhSecurityPolicies": "."
+ },
+ "translations": ["translations/ja-JP.json"]
+}
diff --git a/plugins/wazuh-security-policies/README.md b/plugins/wazuh-security-policies/README.md
new file mode 100755
index 0000000000..4e213dc5f0
--- /dev/null
+++ b/plugins/wazuh-security-policies/README.md
@@ -0,0 +1,22 @@
+# wazuhSecurityPolicies
+
+A OpenSearch Dashboards plugin
+
+---
+
+## Development
+
+See the [OpenSearch Dashboards contributing
+guide](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/main/CONTRIBUTING.md) for instructions
+setting up your development environment.
+
+ ## Scripts
+
+ yarn osd bootstrap
+ - Execute this to install node_modules and setup the dependencies in your plugin and in OpenSearch Dashboards
+
+
+ yarn plugin-helpers build
+ - Execute this to create a distributable version of this plugin that can be installed in OpenSearch Dashboards
+
+
diff --git a/plugins/wazuh-security-policies/common/index.ts b/plugins/wazuh-security-policies/common/index.ts
new file mode 100644
index 0000000000..2ede64bf71
--- /dev/null
+++ b/plugins/wazuh-security-policies/common/index.ts
@@ -0,0 +1,2 @@
+export const PLUGIN_ID = 'wazuhSecurityPolicies';
+export const PLUGIN_NAME = 'Ruleset';
diff --git a/plugins/wazuh-security-policies/opensearch_dashboards.json b/plugins/wazuh-security-policies/opensearch_dashboards.json
new file mode 100644
index 0000000000..2637c18a03
--- /dev/null
+++ b/plugins/wazuh-security-policies/opensearch_dashboards.json
@@ -0,0 +1,9 @@
+{
+ "id": "wazuhSecurityPolicies",
+ "version": "1.0.0",
+ "opensearchDashboardsVersion": "opensearchDashboards",
+ "server": true,
+ "ui": true,
+ "requiredPlugins": ["navigation"],
+ "optionalPlugins": []
+}
diff --git a/plugins/wazuh-security-policies/package.json b/plugins/wazuh-security-policies/package.json
new file mode 100644
index 0000000000..e0dd122d44
--- /dev/null
+++ b/plugins/wazuh-security-policies/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "wazuhSecurityPolicies",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "build": "yarn plugin-helpers build",
+ "plugin-helpers": "../../scripts/use_node ../../scripts/plugin_helpers",
+ "osd": "../../scripts/use_node ../../scripts/osd"
+ }
+}
diff --git a/plugins/wazuh-security-policies/public/application.tsx b/plugins/wazuh-security-policies/public/application.tsx
new file mode 100644
index 0000000000..803dd71fdb
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/application.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { AppMountParameters, CoreStart } from '../../../src/core/public';
+import { AppPluginStartDependencies } from './types';
+import { WazuhSecurityPoliciesApp } from './components/app';
+
+export const renderApp = (
+ { notifications, http }: CoreStart,
+ { navigation }: AppPluginStartDependencies,
+ { appBasePath, element }: AppMountParameters,
+) => {
+ ReactDOM.render(
+ ,
+ element,
+ );
+
+ return () => ReactDOM.unmountComponentAtNode(element);
+};
diff --git a/plugins/wazuh-security-policies/public/components/app.tsx b/plugins/wazuh-security-policies/public/components/app.tsx
new file mode 100644
index 0000000000..526b7dd2a7
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/app.tsx
@@ -0,0 +1,116 @@
+import React, { useState } from 'react';
+import { i18n } from '@osd/i18n';
+import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
+import { BrowserRouter as Router } from 'react-router-dom';
+import {
+ EuiHorizontalRule,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentBody,
+ EuiPageContentHeader,
+ EuiPageHeader,
+ EuiTitle,
+ EuiText,
+ EuiButton,
+} from '@elastic/eui';
+import { CoreStart } from '../../../../src/core/public';
+import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public';
+import { PLUGIN_ID, PLUGIN_NAME } from '../../common';
+
+interface WazuhSecurityPoliciesAppDeps {
+ basename: string;
+ notifications: CoreStart['notifications'];
+ http: CoreStart['http'];
+ navigation: NavigationPublicPluginStart;
+}
+
+export const WazuhSecurityPoliciesApp = ({
+ basename,
+ notifications,
+ http,
+ navigation,
+}: WazuhSecurityPoliciesAppDeps) => {
+ // Use React hooks to manage state.
+ const [timestamp, setTimestamp] = useState();
+
+ const onClickHandler = () => {
+ // Use the core http service to make a response to the server API.
+ http.get('/api/wazuh_security_policies/example').then(res => {
+ setTimestamp(res.time);
+ // Use the core notifications service to display a success message.
+ notifications.toasts.addSuccess(
+ i18n.translate('wazuhSecurityPolicies.dataUpdated', {
+ defaultMessage: 'Data updated',
+ }),
+ );
+ });
+ };
+
+ // Render the application DOM.
+ // Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract.
+ return (
+
+
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+
+
+ );
+};
diff --git a/plugins/wazuh-security-policies/public/index.scss b/plugins/wazuh-security-policies/public/index.scss
new file mode 100644
index 0000000000..ff7112406e
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/index.scss
@@ -0,0 +1 @@
+/* stylelint-disable no-empty-source */
diff --git a/plugins/wazuh-security-policies/public/index.ts b/plugins/wazuh-security-policies/public/index.ts
new file mode 100644
index 0000000000..1c695634f4
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/index.ts
@@ -0,0 +1,13 @@
+import './index.scss';
+import { WazuhSecurityPoliciesPlugin } from './plugin';
+
+// This exports static code and TypeScript types,
+// as well as, OpenSearch Dashboards Platform `plugin()` initializer.
+export function plugin() {
+ return new WazuhSecurityPoliciesPlugin();
+}
+
+export {
+ WazuhSecurityPoliciesPluginSetup,
+ WazuhSecurityPoliciesPluginStart,
+} from './types';
diff --git a/plugins/wazuh-security-policies/public/plugin.ts b/plugins/wazuh-security-policies/public/plugin.ts
new file mode 100644
index 0000000000..8b6bbd6023
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/plugin.ts
@@ -0,0 +1,64 @@
+import { i18n } from '@osd/i18n';
+import {
+ AppMountParameters,
+ CoreSetup,
+ Plugin,
+} from '../../../src/core/public';
+import { PLUGIN_NAME } from '../common';
+import {
+ WazuhSecurityPoliciesPluginSetup,
+ WazuhSecurityPoliciesPluginStart,
+ AppPluginStartDependencies,
+} from './types';
+
+export class WazuhSecurityPoliciesPlugin
+ implements
+ Plugin
+{
+ public setup(core: CoreSetup): WazuhSecurityPoliciesPluginSetup {
+ // Register an application into the side navigation menu
+ core.application.register({
+ id: 'wazuhSecurityPolicies',
+ title: PLUGIN_NAME,
+ category: {
+ id: 'wz-category-security-policies',
+ label: i18n.translate('wz-app-category-security-policies', {
+ defaultMessage: 'Security Policies',
+ }),
+ order: 200,
+ euiIconType: 'indexRollupApp',
+ },
+ async mount(params: AppMountParameters) {
+ // Load application bundle
+ const { renderApp } = await import('./application');
+ // Get start services as specified in opensearch_dashboards.json
+ const [coreStart, depsStart] = await core.getStartServices();
+
+ // Render the application
+ return renderApp(
+ coreStart,
+ depsStart as AppPluginStartDependencies,
+ params,
+ );
+ },
+ });
+
+ // Return methods that should be available to other plugins
+ return {
+ getGreeting() {
+ return i18n.translate('wazuhSecurityPolicies.greetingText', {
+ defaultMessage: 'Hello from {name}!',
+ values: {
+ name: PLUGIN_NAME,
+ },
+ });
+ },
+ };
+ }
+
+ public start(): WazuhSecurityPoliciesPluginStart {
+ return {};
+ }
+
+ public stop() {}
+}
diff --git a/plugins/wazuh-security-policies/public/types.ts b/plugins/wazuh-security-policies/public/types.ts
new file mode 100644
index 0000000000..54154e6226
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/types.ts
@@ -0,0 +1,11 @@
+import { NavigationPublicPluginStart } from '../../../src/plugins/navigation/public';
+
+export interface WazuhSecurityPoliciesPluginSetup {
+ getGreeting: () => string;
+}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type
+export interface WazuhSecurityPoliciesPluginStart {}
+
+export interface AppPluginStartDependencies {
+ navigation: NavigationPublicPluginStart;
+}
diff --git a/plugins/wazuh-security-policies/server/index.ts b/plugins/wazuh-security-policies/server/index.ts
new file mode 100644
index 0000000000..2f7147a9b1
--- /dev/null
+++ b/plugins/wazuh-security-policies/server/index.ts
@@ -0,0 +1,14 @@
+import { PluginInitializerContext } from '../../../src/core/server';
+import { WazuhSecurityPoliciesPlugin } from './plugin';
+
+// This exports static code and TypeScript types,
+// as well as, OpenSearch Dashboards Platform `plugin()` initializer.
+
+export function plugin(initializerContext: PluginInitializerContext) {
+ return new WazuhSecurityPoliciesPlugin(initializerContext);
+}
+
+export {
+ WazuhSecurityPoliciesPluginSetup,
+ WazuhSecurityPoliciesPluginStart,
+} from './types';
diff --git a/plugins/wazuh-security-policies/server/plugin.ts b/plugins/wazuh-security-policies/server/plugin.ts
new file mode 100644
index 0000000000..c5537b5113
--- /dev/null
+++ b/plugins/wazuh-security-policies/server/plugin.ts
@@ -0,0 +1,41 @@
+import {
+ PluginInitializerContext,
+ CoreSetup,
+ Plugin,
+ Logger,
+} from '../../../src/core/server';
+import {
+ WazuhSecurityPoliciesPluginSetup,
+ WazuhSecurityPoliciesPluginStart,
+} from './types';
+import { defineRoutes } from './routes';
+
+export class WazuhSecurityPoliciesPlugin
+ implements
+ Plugin
+{
+ private readonly logger: Logger;
+
+ constructor(initializerContext: PluginInitializerContext) {
+ this.logger = initializerContext.logger.get();
+ }
+
+ public setup(core: CoreSetup) {
+ this.logger.debug('wazuhSecurityPolicies: Setup');
+
+ const router = core.http.createRouter();
+
+ // Register server side APIs
+ defineRoutes(router);
+
+ return {};
+ }
+
+ public start() {
+ this.logger.debug('wazuhSecurityPolicies: Started');
+
+ return {};
+ }
+
+ public stop() {}
+}
diff --git a/plugins/wazuh-security-policies/server/routes/index.ts b/plugins/wazuh-security-policies/server/routes/index.ts
new file mode 100644
index 0000000000..920b406851
--- /dev/null
+++ b/plugins/wazuh-security-policies/server/routes/index.ts
@@ -0,0 +1,16 @@
+import { IRouter } from '../../../../src/core/server';
+
+export function defineRoutes(router: IRouter) {
+ router.get(
+ {
+ path: '/api/wazuh_security_policies/example',
+ validate: false,
+ },
+ async (context, request, response) =>
+ response.ok({
+ body: {
+ time: new Date().toISOString(),
+ },
+ }),
+ );
+}
diff --git a/plugins/wazuh-security-policies/server/types.ts b/plugins/wazuh-security-policies/server/types.ts
new file mode 100644
index 0000000000..4bdc1abf41
--- /dev/null
+++ b/plugins/wazuh-security-policies/server/types.ts
@@ -0,0 +1,5 @@
+/* eslint-disable @typescript-eslint/no-empty-object-type */
+// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type
+export interface WazuhSecurityPoliciesPluginSetup {}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface WazuhSecurityPoliciesPluginStart {}
diff --git a/plugins/wazuh-security-policies/translations/ja-JP.json b/plugins/wazuh-security-policies/translations/ja-JP.json
new file mode 100644
index 0000000000..60cb8f9ed6
--- /dev/null
+++ b/plugins/wazuh-security-policies/translations/ja-JP.json
@@ -0,0 +1,81 @@
+{
+ "formats": {
+ "number": {
+ "currency": {
+ "style": "currency"
+ },
+ "percent": {
+ "style": "percent"
+ }
+ },
+ "date": {
+ "short": {
+ "month": "numeric",
+ "day": "numeric",
+ "year": "2-digit"
+ },
+ "medium": {
+ "month": "short",
+ "day": "numeric",
+ "year": "numeric"
+ },
+ "long": {
+ "month": "long",
+ "day": "numeric",
+ "year": "numeric"
+ },
+ "full": {
+ "weekday": "long",
+ "month": "long",
+ "day": "numeric",
+ "year": "numeric"
+ }
+ },
+ "time": {
+ "short": {
+ "hour": "numeric",
+ "minute": "numeric"
+ },
+ "medium": {
+ "hour": "numeric",
+ "minute": "numeric",
+ "second": "numeric"
+ },
+ "long": {
+ "hour": "numeric",
+ "minute": "numeric",
+ "second": "numeric",
+ "timeZoneName": "short"
+ },
+ "full": {
+ "hour": "numeric",
+ "minute": "numeric",
+ "second": "numeric",
+ "timeZoneName": "short"
+ }
+ },
+ "relative": {
+ "years": {
+ "units": "year"
+ },
+ "months": {
+ "units": "month"
+ },
+ "days": {
+ "units": "day"
+ },
+ "hours": {
+ "units": "hour"
+ },
+ "minutes": {
+ "units": "minute"
+ },
+ "seconds": {
+ "units": "second"
+ }
+ }
+ },
+ "messages": {
+ "wazuhSecurityPolicies.buttonText": "Translate me to Japanese"
+ }
+}
diff --git a/plugins/wazuh-security-policies/tsconfig.json b/plugins/wazuh-security-policies/tsconfig.json
new file mode 100644
index 0000000000..7fa0373911
--- /dev/null
+++ b/plugins/wazuh-security-policies/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./target",
+ "skipLibCheck": true
+ },
+ "include": [
+ "index.ts",
+ "common/**/*.ts",
+ "public/**/*.ts",
+ "public/**/*.tsx",
+ "server/**/*.ts",
+ "../../typings/**/*"
+ ],
+ "exclude": []
+}
diff --git a/plugins/wazuh-security-policies/yarn.lock b/plugins/wazuh-security-policies/yarn.lock
new file mode 100644
index 0000000000..fb57ccd13a
--- /dev/null
+++ b/plugins/wazuh-security-policies/yarn.lock
@@ -0,0 +1,4 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
From 3236353f21429e7889fe5fcbbb2692367cf10616 Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Tue, 14 Jan 2025 21:19:37 +0100
Subject: [PATCH 02/30] Add navigation
---
.../opensearch_dashboards.json | 2 +-
.../public/components/app.tsx | 184 +++++++++---------
.../public/plugin-services.tsx | 5 +
.../wazuh-security-policies/public/plugin.ts | 8 +-
4 files changed, 105 insertions(+), 94 deletions(-)
create mode 100644 plugins/wazuh-security-policies/public/plugin-services.tsx
diff --git a/plugins/wazuh-security-policies/opensearch_dashboards.json b/plugins/wazuh-security-policies/opensearch_dashboards.json
index 2637c18a03..77ac702ffd 100644
--- a/plugins/wazuh-security-policies/opensearch_dashboards.json
+++ b/plugins/wazuh-security-policies/opensearch_dashboards.json
@@ -4,6 +4,6 @@
"opensearchDashboardsVersion": "opensearchDashboards",
"server": true,
"ui": true,
- "requiredPlugins": ["navigation"],
+ "requiredPlugins": ["navigation", "opensearchDashboardsUtils"],
"optionalPlugins": []
}
diff --git a/plugins/wazuh-security-policies/public/components/app.tsx b/plugins/wazuh-security-policies/public/components/app.tsx
index 526b7dd2a7..14549c69cf 100644
--- a/plugins/wazuh-security-policies/public/components/app.tsx
+++ b/plugins/wazuh-security-policies/public/components/app.tsx
@@ -1,112 +1,112 @@
-import React, { useState } from 'react';
-import { i18n } from '@osd/i18n';
+import React, { useState, useEffect } from 'react';
import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
-import { BrowserRouter as Router } from 'react-router-dom';
import {
- EuiHorizontalRule,
EuiPage,
EuiPageBody,
- EuiPageContent,
- EuiPageContentBody,
- EuiPageContentHeader,
- EuiPageHeader,
- EuiTitle,
- EuiText,
- EuiButton,
+ EuiSideNav,
+ EuiPageSideBar,
+ EuiPanel,
} from '@elastic/eui';
-import { CoreStart } from '../../../../src/core/public';
-import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public';
-import { PLUGIN_ID, PLUGIN_NAME } from '../../common';
+import { Router, Route, Switch, Redirect } from 'react-router-dom';
+import { getCore, getHistory } from '../plugin-services';
-interface WazuhSecurityPoliciesAppDeps {
- basename: string;
- notifications: CoreStart['notifications'];
- http: CoreStart['http'];
- navigation: NavigationPublicPluginStart;
+interface ViewInterface {
+ name: string;
+ id: string;
+ render: () => React.ReactNode;
}
-export const WazuhSecurityPoliciesApp = ({
- basename,
- notifications,
- http,
- navigation,
-}: WazuhSecurityPoliciesAppDeps) => {
- // Use React hooks to manage state.
- const [timestamp, setTimestamp] = useState();
+const views: ViewInterface[] = [
+ {
+ name: 'Integrations',
+ id: 'integrations',
+ render: () => Integrations
,
+ },
+ {
+ name: 'Rules',
+ id: 'rules',
+ render: () => Rules
,
+ },
+ {
+ name: 'Decoders',
+ id: 'decoders',
+ render: () => Decoders
,
+ },
+ {
+ name: 'KVDB',
+ id: 'kvdb',
+ render: () => KVDBs
,
+ },
+];
- const onClickHandler = () => {
- // Use the core http service to make a response to the server API.
- http.get('/api/wazuh_security_policies/example').then(res => {
- setTimestamp(res.time);
- // Use the core notifications service to display a success message.
- notifications.toasts.addSuccess(
- i18n.translate('wazuhSecurityPolicies.dataUpdated', {
- defaultMessage: 'Data updated',
- }),
- );
- });
- };
+export const WazuhSecurityPoliciesApp = () => {
+ const history = getHistory();
+ const [currentTab, setCurrentTab] = useState('');
+
+ useEffect(() => {
+ setCurrentTab(history.location.pathname);
+ }, []);
+
+ const sideNav = [
+ {
+ name: 'Ruleset',
+ id: 'wazuhRuleset',
+ items: views.map(item => ({
+ id: item.id,
+ name: item.name,
+ onClick: () => {
+ history.push(`${item.id}`);
+ setCurrentTab(item.id);
+ },
+ isSelected:
+ item.id === currentTab || history.location.pathname === `/${item.id}`,
+ })),
+ },
+ ];
// Render the application DOM.
// Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract.
return (
-
+
<>
-
-
+ {/* */}
+
+
+
+
-
-
-
-
+
+ {views.map(view => (
+ {
+ getCore().chrome.setBreadcrumbs([
+ {
+ className: 'osdBreadcrumbs',
+ text: (
+
+ ),
+ },
+ ]);
+
+ return view.render();
+ }}
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ ))}
+
+
+
>
diff --git a/plugins/wazuh-security-policies/public/plugin-services.tsx b/plugins/wazuh-security-policies/public/plugin-services.tsx
new file mode 100644
index 0000000000..c95d9cca28
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/plugin-services.tsx
@@ -0,0 +1,5 @@
+import { CoreStart } from 'opensearch-dashboards/public';
+import { createGetterSetter } from '../../../src/plugins/opensearch_dashboards_utils/common';
+
+export const [getCore, setCore] = createGetterSetter('Core');
+export const [getHistory, setHistory] = createGetterSetter('History');
diff --git a/plugins/wazuh-security-policies/public/plugin.ts b/plugins/wazuh-security-policies/public/plugin.ts
index 8b6bbd6023..4d689f7bbc 100644
--- a/plugins/wazuh-security-policies/public/plugin.ts
+++ b/plugins/wazuh-security-policies/public/plugin.ts
@@ -1,7 +1,9 @@
import { i18n } from '@osd/i18n';
+import { createHashHistory } from 'history';
import {
AppMountParameters,
CoreSetup,
+ CoreStart,
Plugin,
} from '../../../src/core/public';
import { PLUGIN_NAME } from '../common';
@@ -10,6 +12,7 @@ import {
WazuhSecurityPoliciesPluginStart,
AppPluginStartDependencies,
} from './types';
+import { setCore, setHistory } from './plugin-services';
export class WazuhSecurityPoliciesPlugin
implements
@@ -34,6 +37,8 @@ export class WazuhSecurityPoliciesPlugin
// Get start services as specified in opensearch_dashboards.json
const [coreStart, depsStart] = await core.getStartServices();
+ setHistory(createHashHistory());
+
// Render the application
return renderApp(
coreStart,
@@ -56,7 +61,8 @@ export class WazuhSecurityPoliciesPlugin
};
}
- public start(): WazuhSecurityPoliciesPluginStart {
+ public start(core: CoreStart): WazuhSecurityPoliciesPluginStart {
+ setCore(core);
return {};
}
From 1d43c48145554f0fb49e699d79cb600402b155ad Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Tue, 14 Jan 2025 21:20:09 +0100
Subject: [PATCH 03/30] Fix lint
---
plugins/wazuh-security-policies/public/plugin.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/plugins/wazuh-security-policies/public/plugin.ts b/plugins/wazuh-security-policies/public/plugin.ts
index 4d689f7bbc..20597720f5 100644
--- a/plugins/wazuh-security-policies/public/plugin.ts
+++ b/plugins/wazuh-security-policies/public/plugin.ts
@@ -63,6 +63,7 @@ export class WazuhSecurityPoliciesPlugin
public start(core: CoreStart): WazuhSecurityPoliciesPluginStart {
setCore(core);
+
return {};
}
From 39cd36bed70f132eed3e4c553114c7a5a2a420b6 Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Wed, 15 Jan 2025 18:08:39 +0100
Subject: [PATCH 04/30] Add integrations view
---
.../public/components/app.tsx | 8 +-
.../public/components/common/popover.tsx | 34 +++
.../components/card-integration.tsx | 72 ++++++
.../components/integretions/integrations.scss | 4 +
.../components/integretions/overview.tsx | 212 ++++++++++++++++++
5 files changed, 326 insertions(+), 4 deletions(-)
create mode 100644 plugins/wazuh-security-policies/public/components/common/popover.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/integrations.scss
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/overview.tsx
diff --git a/plugins/wazuh-security-policies/public/components/app.tsx b/plugins/wazuh-security-policies/public/components/app.tsx
index 14549c69cf..63e4e3c08f 100644
--- a/plugins/wazuh-security-policies/public/components/app.tsx
+++ b/plugins/wazuh-security-policies/public/components/app.tsx
@@ -9,6 +9,7 @@ import {
} from '@elastic/eui';
import { Router, Route, Switch, Redirect } from 'react-router-dom';
import { getCore, getHistory } from '../plugin-services';
+import { IntegrationOverview } from './integretions/overview';
interface ViewInterface {
name: string;
@@ -20,7 +21,7 @@ const views: ViewInterface[] = [
{
name: 'Integrations',
id: 'integrations',
- render: () => Integrations
,
+ render: () => ,
},
{
name: 'Rules',
@@ -70,14 +71,13 @@ export const WazuhSecurityPoliciesApp = () => {
<>
- {/* */}
-
+
{
+ const { children, styles, color = 'text' } = props;
+ const [isPopoverOpen, setIsPopoverOpen] = useState(false);
+ const onButtonClick = () => setIsPopoverOpen(isPopoverOpen => !isPopoverOpen);
+ const closePopover = () => setIsPopoverOpen(false);
+
+ return (
+
+ }
+ isOpen={isPopoverOpen}
+ closePopover={closePopover}
+ >
+ {children}
+
+ );
+};
diff --git a/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx b/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
new file mode 100644
index 0000000000..17dc7d4201
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
@@ -0,0 +1,72 @@
+import React from 'react';
+import {
+ EuiCard,
+ EuiIcon,
+ EuiButtonEmpty,
+ EuiHorizontalRule,
+} from '@elastic/eui';
+import { PopoverIconButton } from '../../common/popover';
+
+interface CardIntegrationProps {
+ image: string;
+ title: string;
+ description: string;
+ isEnable: boolean;
+}
+
+export const CardIntegration = (props: CardIntegrationProps) => {
+ const { image = 'logoOpenSearch', title, description, isEnable } = props;
+ const buttonIntegrations = [
+ {
+ id: 'goToDecoder',
+ label: 'Go to Decoder',
+ color: 'text',
+ },
+ {
+ id: 'goToRules',
+ label: 'Go to Rules',
+ color: 'text',
+ },
+ {
+ id: 'goToKVDB',
+ label: 'Go to KVDB',
+ color: 'text',
+ },
+ {
+ id: 'enable/disable',
+ label: isEnable ? 'Disable' : 'Enable',
+ color: isEnable ? 'danger' : 'primary',
+ },
+ ];
+
+ return (
+
+
}
+ paddingSize='m'
+ />
+
+
+ {buttonIntegrations.map((button, index) => (
+
+
+ {button.label}
+
+ {index < buttonIntegrations.length - 1 && (
+
+ )}
+
+ ))}
+
+
+
+ );
+};
diff --git a/plugins/wazuh-security-policies/public/components/integretions/integrations.scss b/plugins/wazuh-security-policies/public/components/integretions/integrations.scss
new file mode 100644
index 0000000000..7bac981f40
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/integretions/integrations.scss
@@ -0,0 +1,4 @@
+.integration-title-header {
+ display: flex;
+ align-items: center;
+}
diff --git a/plugins/wazuh-security-policies/public/components/integretions/overview.tsx b/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
new file mode 100644
index 0000000000..ac7cc590e7
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
@@ -0,0 +1,212 @@
+import React, { useState } from 'react';
+import {
+ EuiPageHeader,
+ EuiLink,
+ EuiButton,
+ EuiHealth,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiSearchBar,
+ EuiCallOut,
+ EuiText,
+} from '@elastic/eui';
+import './integrations.scss';
+import { CardIntegration } from './components/card-integration';
+
+const integrations = [
+ {
+ image: 'advancedSettingsApp',
+ title: 'Integration 1',
+ description: 'Description for integration 1',
+ isEnable: true,
+ },
+ {
+ image: 'grokApp',
+ title: 'Integration 2',
+ description: 'Description for integration 2',
+ isEnable: false,
+ },
+ {
+ image: 'grokApp',
+ title: 'Integration 3',
+ description: 'Description for integration 3',
+ isEnable: true,
+ },
+ {
+ image: 'reportingApp',
+ title: 'Integration 4',
+ description: 'Description for integration 4',
+ isEnable: false,
+ },
+ {
+ image: 'heartbeatApp',
+ title: 'Integration 5',
+ description: 'Description for integration 5',
+ isEnable: true,
+ },
+ {
+ image: 'appSearchApp',
+ title: 'Integration 6',
+ description: 'Description for integration 6',
+ isEnable: false,
+ },
+ {
+ image: 'indexRollupApp',
+ title: 'Integration 7',
+ description: 'Description for integration 7',
+ isEnable: true,
+ },
+ {
+ image: 'canvasApp',
+ title: 'Integration 8',
+ description: 'Description for integration 8',
+ isEnable: false,
+ },
+ {
+ image: 'securityApp',
+ title: 'Integration 9',
+ description: 'Description for integration 9',
+ isEnable: true,
+ },
+ {
+ image: 'lensApp',
+ title: 'Integration 10',
+ description: 'Description for integration 10',
+ isEnable: false,
+ },
+];
+
+export const IntegrationOverview = () => {
+ const [lastUpdate, setLastUpdate] = useState({
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ });
+ const titleHeader = (
+
+ Integrations
+
+ Updated
+
+
+ );
+
+ const updateContentManager = () => {
+ const currentDate = new Date().toLocaleString();
+
+ setLastUpdate({
+ lastUpdateDate: currentDate,
+ status: 'Success',
+ });
+ };
+
+ // Search bar
+
+ const initialQuery = EuiSearchBar.Query.MATCH_ALL;
+ const [query, setQuery] = useState(initialQuery);
+ const [error, setError] = useState(null);
+
+ const onChange = ({ query, error }) => {
+ if (error) {
+ setError(error);
+ } else {
+ setError(null);
+ setQuery(query);
+ }
+ };
+
+ const filters = [
+ {
+ type: 'field_value_selection',
+ field: 'integration',
+ name: 'Integrations',
+ multiSelect: 'and',
+ operator: 'exact',
+ cache: 10000, // will cache the loaded tags for 10 sec
+ options: integrations.map(integration => ({
+ value: integration.title,
+ view: {integration.title},
+ })),
+ },
+ ];
+ const schema = {
+ strict: true,
+ fields: {
+ integration: {
+ type: 'string',
+ },
+ },
+ };
+
+ const renderError = () => {
+ if (!error) {
+ return;
+ }
+
+ return (
+ <>
+
+ >
+ );
+ };
+
+ return (
+ <>
+
+ Last update of the content manager was {lastUpdate.lastUpdateDate} (
+ {lastUpdate.status}).{' '}
+
+ Learn more
+
+ >
+ }
+ rightSideItems={[
+
+ Update
+ ,
+ ]}
+ />
+
+
+
+ {renderError()}
+
+ {query.text === ''
+ ? integrations.map((integration, index) => (
+
+
+
+ ))
+ : integrations
+ .filter(integration =>
+ query.text
+ .toLocaleLowerCase()
+ .includes(integration.title.toLocaleLowerCase()),
+ )
+ .map((integration, index) => (
+
+
+
+ ))}
+
+ >
+ );
+};
From 7cf84e619a2fb3a9d19b1a52e5914f2b51976d5e Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Wed, 15 Jan 2025 21:54:23 +0100
Subject: [PATCH 05/30] Add navigation integration
---
.../public/components/app.tsx | 44 ++++++++++++++++---
.../components/card-integration.tsx | 7 +++
.../components/integretions/integration.tsx | 7 +++
3 files changed, 53 insertions(+), 5 deletions(-)
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/integration.tsx
diff --git a/plugins/wazuh-security-policies/public/components/app.tsx b/plugins/wazuh-security-policies/public/components/app.tsx
index 63e4e3c08f..30b7d6e256 100644
--- a/plugins/wazuh-security-policies/public/components/app.tsx
+++ b/plugins/wazuh-security-policies/public/components/app.tsx
@@ -7,7 +7,7 @@ import {
EuiPageSideBar,
EuiPanel,
} from '@elastic/eui';
-import { Router, Route, Switch, Redirect } from 'react-router-dom';
+import { Router, Route, Switch, Redirect, useParams } from 'react-router-dom';
import { getCore, getHistory } from '../plugin-services';
import { IntegrationOverview } from './integretions/overview';
@@ -15,6 +15,7 @@ interface ViewInterface {
name: string;
id: string;
render: () => React.ReactNode;
+ renderDetails?: () => React.ReactNode;
}
const views: ViewInterface[] = [
@@ -22,6 +23,7 @@ const views: ViewInterface[] = [
name: 'Integrations',
id: 'integrations',
render: () => ,
+ renderDetails: () => Details
,
},
{
name: 'Rules',
@@ -56,7 +58,7 @@ export const WazuhSecurityPoliciesApp = () => {
id: item.id,
name: item.name,
onClick: () => {
- history.push(`${item.id}`);
+ history.push(`/${item.id}`);
setCurrentTab(item.id);
},
isSelected:
@@ -83,7 +85,39 @@ export const WazuhSecurityPoliciesApp = () => {
hasBorder={false}
>
- {views.map(view => (
+ {views.map(view => [
+ view.renderDetails && (
+ {
+ const { id } = useParams();
+
+ getCore().chrome.setBreadcrumbs([
+ {
+ text: (
+
+ ),
+ href: getCore().application.getUrlForApp(
+ 'wazuhSecurityPolicies',
+ {
+ path: `#/${view.id}`,
+ },
+ ),
+ },
+ {
+ className: 'osdBreadcrumbs',
+ text: id,
+ },
+ ]);
+
+ return view.renderDetails();
+ }}
+ />
+ ),
{
return view.render();
}}
- />
- ))}
+ />,
+ ])}
diff --git a/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx b/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
index 17dc7d4201..2a8a0976a4 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
+++ b/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
@@ -6,6 +6,7 @@ import {
EuiHorizontalRule,
} from '@elastic/eui';
import { PopoverIconButton } from '../../common/popover';
+import { getHistory } from '../../../plugin-services';
interface CardIntegrationProps {
image: string;
@@ -15,6 +16,7 @@ interface CardIntegrationProps {
}
export const CardIntegration = (props: CardIntegrationProps) => {
+ const history = getHistory();
const { image = 'logoOpenSearch', title, description, isEnable } = props;
const buttonIntegrations = [
{
@@ -39,6 +41,10 @@ export const CardIntegration = (props: CardIntegrationProps) => {
},
];
+ const handleNavigation = (path: string) => {
+ history.push(path);
+ };
+
return (
{
description={description}
icon={}
paddingSize='m'
+ onClick={() => handleNavigation(`/integrations/${title}`)}
/>
(
+
+
Integration
+
+);
From 70c36c14b72188d24f1eea54d5d8f05b0c443f7d Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Thu, 16 Jan 2025 22:32:32 +0100
Subject: [PATCH 06/30] Add integration view
---
.../public/components/app.tsx | 3 +-
.../public/components/common/header-page.tsx | 20 ++
.../public/components/common/searchbar.tsx | 43 ++++
.../components/card-integration.tsx | 4 +-
.../components/integration-description.tsx | 45 ++++
.../components/integretions/integration.tsx | 141 +++++++++++-
.../components/integretions/integrations.scss | 10 +
.../integretions/mock-data-integrations.tsx | 214 ++++++++++++++++++
.../components/integretions/overview.tsx | 177 +++++----------
9 files changed, 528 insertions(+), 129 deletions(-)
create mode 100644 plugins/wazuh-security-policies/public/components/common/header-page.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/common/searchbar.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/components/integration-description.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/mock-data-integrations.tsx
diff --git a/plugins/wazuh-security-policies/public/components/app.tsx b/plugins/wazuh-security-policies/public/components/app.tsx
index 30b7d6e256..f5663fe469 100644
--- a/plugins/wazuh-security-policies/public/components/app.tsx
+++ b/plugins/wazuh-security-policies/public/components/app.tsx
@@ -10,6 +10,7 @@ import {
import { Router, Route, Switch, Redirect, useParams } from 'react-router-dom';
import { getCore, getHistory } from '../plugin-services';
import { IntegrationOverview } from './integretions/overview';
+import { IntegrationView } from './integretions/integration';
interface ViewInterface {
name: string;
@@ -23,7 +24,7 @@ const views: ViewInterface[] = [
name: 'Integrations',
id: 'integrations',
render: () => ,
- renderDetails: () => Details
,
+ renderDetails: () => ,
},
{
name: 'Rules',
diff --git a/plugins/wazuh-security-policies/public/components/common/header-page.tsx b/plugins/wazuh-security-policies/public/components/common/header-page.tsx
new file mode 100644
index 0000000000..44f32dccb7
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/common/header-page.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { EuiPageHeader } from '@elastic/eui';
+
+interface HeaderPageProps {
+ titleHeader: React.ReactNode | string;
+ descriptionHeader: React.ReactNode | string;
+ rightSideItems?: React.ReactNode[];
+}
+
+export const HeaderPage = (props: HeaderPageProps) => {
+ const { titleHeader, descriptionHeader, rightSideItems } = props;
+
+ return (
+
+ );
+};
diff --git a/plugins/wazuh-security-policies/public/components/common/searchbar.tsx b/plugins/wazuh-security-policies/public/components/common/searchbar.tsx
new file mode 100644
index 0000000000..8a296fe861
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/common/searchbar.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import { EuiCallOut, EuiSearchBar, EuiSearchBarProps } from '@elastic/eui';
+
+const initialQuery = EuiSearchBar.Query.MATCH_ALL;
+
+export const SearchBar = (props: EuiSearchBarProps) => {
+ const { schema, filters, onChange, error } = props;
+
+ const renderError = () => {
+ if (!error) {
+ return;
+ }
+
+ return (
+ <>
+
+ >
+ );
+ };
+
+ return (
+ <>
+
+
+
+ {renderError()}
+ >
+ );
+};
diff --git a/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx b/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
index 2a8a0976a4..43bd2a043a 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
+++ b/plugins/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
@@ -46,7 +46,7 @@ export const CardIntegration = (props: CardIntegrationProps) => {
};
return (
-
+ <>
{
))}
-
+ >
);
};
diff --git a/plugins/wazuh-security-policies/public/components/integretions/components/integration-description.tsx b/plugins/wazuh-security-policies/public/components/integretions/components/integration-description.tsx
new file mode 100644
index 0000000000..61e9eb256b
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/integretions/components/integration-description.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import {
+ EuiDescriptionListTitle,
+ EuiDescriptionListDescription,
+} from '@elastic/eui';
+
+interface IntegrationDescriptionProps {
+ keyValue: string;
+ value: any;
+}
+
+export const IntegrationDescription = (props: IntegrationDescriptionProps) => {
+ const { keyValue, value } = props;
+ const renderTitleDescription = (key: string, value: string) => (
+
+ {key}
+
+ {value}
+
+
+ );
+
+ const renderObjectValue = (keyObject: string, valueObject: object) => {
+ const subList = Object.entries(valueObject).map(([key, value]) => ({
+ key: `${keyObject}.${key}`,
+ value: value,
+ }));
+
+ return subList.map(item => renderTitleDescription(item.key, item.value));
+ };
+
+ const renderValue = (key: string, value: any) => {
+ if (Array.isArray(value)) {
+ return renderTitleDescription(key, value.join(', '));
+ } else if (typeof value === 'object') {
+ return renderObjectValue(key, value);
+ } else if (typeof value === 'boolean') {
+ return renderTitleDescription(key, value ? 'Enable' : 'Disable');
+ } else {
+ return renderTitleDescription(key, value);
+ }
+ };
+
+ return renderValue(keyValue, value);
+};
diff --git a/plugins/wazuh-security-policies/public/components/integretions/integration.tsx b/plugins/wazuh-security-policies/public/components/integretions/integration.tsx
index bf3b6f2f94..37852da382 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/integration.tsx
+++ b/plugins/wazuh-security-policies/public/components/integretions/integration.tsx
@@ -1,7 +1,136 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
+import {
+ EuiHealth,
+ EuiIcon,
+ EuiLink,
+ EuiButton,
+ EuiDescriptionList,
+ EuiPanel,
+} from '@elastic/eui';
+import { useParams } from 'react-router-dom';
+import { HeaderPage } from '../common/header-page';
+import { integrations } from './mock-data-integrations';
+import './integrations.scss';
+import { IntegrationDescription } from './components/integration-description';
-export const Integration = () => (
-
-
Integration
-
-);
+export const IntegrationView = () => {
+ const id = useParams().id;
+ const [integrationData, setIntegrationData] = useState<{
+ image: string;
+ title: string;
+ description: string;
+ isEnable: boolean;
+ lastUpdate: {
+ lastUpdateDate: string;
+ status: string;
+ };
+ versions: string[];
+ compatibility: string;
+ author: {
+ name: string;
+ date: string;
+ };
+ references: string[];
+ }>({
+ image: '',
+ title: '',
+ description: '',
+ isEnable: false,
+ lastUpdate: { lastUpdateDate: '', status: '' },
+ versions: [],
+ compatibility: '',
+ author: {
+ name: '',
+ date: '',
+ },
+ references: [],
+ });
+
+ useEffect(() => {
+ const integration = integrations.find(
+ integration => integration.title === id,
+ );
+
+ if (integration) {
+ setIntegrationData(integration);
+ }
+ }, [id]);
+
+ // Header page start
+
+ const headerTitle = (
+
+
+ {integrationData?.title}
+
+ {integrationData.isEnable ? 'Enabled' : 'Disabled'}
+
+
+ );
+ const descriptionHeader = (
+ <>
+ Last update of the content manager was{' '}
+ {integrationData.lastUpdate.lastUpdateDate} (
+ {integrationData.lastUpdate.status}).{' '}
+
+ Learn more
+
+ >
+ );
+
+ const toggleEnableOrDisable = () => {
+ setIntegrationData({
+ ...integrationData,
+ isEnable: !integrationData.isEnable,
+ });
+ };
+
+ const rightSideItems = [
+
+ {integrationData.isEnable ? 'Disable' : 'Enable'}
+ ,
+ ];
+ // Header page end
+ // Description list start
+ const list = Object.entries(integrationData).map(([key, value]) => ({
+ key,
+ value,
+ }));
+
+ // Description list end
+
+ return (
+ <>
+
+
+
+ {list
+ .filter(item => item.key !== 'image')
+ .map(item => (
+
+ ))}
+
+
+ >
+ );
+};
diff --git a/plugins/wazuh-security-policies/public/components/integretions/integrations.scss b/plugins/wazuh-security-policies/public/components/integretions/integrations.scss
index 7bac981f40..585394ae7c 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/integrations.scss
+++ b/plugins/wazuh-security-policies/public/components/integretions/integrations.scss
@@ -2,3 +2,13 @@
display: flex;
align-items: center;
}
+
+.integration-icon-header {
+ margin-right: 10px;
+}
+
+.data-integration-card {
+ display: flex;
+ margin: 10px;
+ flex-wrap: wrap;
+}
diff --git a/plugins/wazuh-security-policies/public/components/integretions/mock-data-integrations.tsx b/plugins/wazuh-security-policies/public/components/integretions/mock-data-integrations.tsx
new file mode 100644
index 0000000000..602465befd
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/integretions/mock-data-integrations.tsx
@@ -0,0 +1,214 @@
+export const integrations = [
+ {
+ image: 'advancedSettingsApp',
+ module: 'syslog',
+ title: 'Linux Doas Conf File Creation',
+ description:
+ 'Detects the creation of doas.conf file in linux host platform',
+ isEnable: true,
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'grokApp',
+ title: 'Integration 2',
+ description: 'Description for integration 2',
+ isEnable: false,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'grokApp',
+ title: 'Integration 3',
+ description: 'Description for integration 3',
+ isEnable: true,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'reportingApp',
+ title: 'Integration 4',
+ description: 'Description for integration 4',
+ isEnable: false,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'heartbeatApp',
+ title: 'Integration 5',
+ description: 'Description for integration 5',
+ isEnable: true,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'appSearchApp',
+ title: 'Integration 6',
+ description: 'Description for integration 6',
+ isEnable: false,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'indexRollupApp',
+ title: 'Integration 7',
+ description: 'Description for integration 7',
+ isEnable: true,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'canvasApp',
+ title: 'Integration 8',
+ description: 'Description for integration 8',
+ isEnable: false,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'securityApp',
+ title: 'Integration 9',
+ description: 'Description for integration 9',
+ isEnable: true,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+ {
+ image: 'lensApp',
+ title: 'Integration 10',
+ description: 'Description for integration 10',
+ isEnable: false,
+ lastUpdate: {
+ lastUpdateDate: '12/18/2024',
+ status: 'Success',
+ },
+ versions: ['1.3.1', '1.3.2', '1.3.3'],
+ compatibility: 'This integration was tested on Ubuntu 20.04',
+ author: {
+ name: 'Wazuh, Inc.',
+ date: '2024/09/09',
+ },
+ references: [
+ 'https://research.splunk.com/endpoint/linux_doas_conf_file_creation/',
+ 'https://www.makeuseof.com/how-to-install-and-use-doas/',
+ 'https://github.com/SigmaHQ/sigma/blob/master/rules/linux/file_event/file_event_lnx_doas_conf_creation.yml',
+ ],
+ },
+];
diff --git a/plugins/wazuh-security-policies/public/components/integretions/overview.tsx b/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
index ac7cc590e7..e3f06cfe6b 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
+++ b/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
@@ -1,86 +1,27 @@
import React, { useState } from 'react';
import {
- EuiPageHeader,
EuiLink,
EuiButton,
EuiHealth,
EuiFlexGroup,
EuiFlexItem,
- EuiSearchBar,
- EuiCallOut,
EuiText,
+ Query,
} from '@elastic/eui';
import './integrations.scss';
+import { SearchBar } from '../common/searchbar';
+import { HeaderPage } from '../common/header-page';
import { CardIntegration } from './components/card-integration';
-
-const integrations = [
- {
- image: 'advancedSettingsApp',
- title: 'Integration 1',
- description: 'Description for integration 1',
- isEnable: true,
- },
- {
- image: 'grokApp',
- title: 'Integration 2',
- description: 'Description for integration 2',
- isEnable: false,
- },
- {
- image: 'grokApp',
- title: 'Integration 3',
- description: 'Description for integration 3',
- isEnable: true,
- },
- {
- image: 'reportingApp',
- title: 'Integration 4',
- description: 'Description for integration 4',
- isEnable: false,
- },
- {
- image: 'heartbeatApp',
- title: 'Integration 5',
- description: 'Description for integration 5',
- isEnable: true,
- },
- {
- image: 'appSearchApp',
- title: 'Integration 6',
- description: 'Description for integration 6',
- isEnable: false,
- },
- {
- image: 'indexRollupApp',
- title: 'Integration 7',
- description: 'Description for integration 7',
- isEnable: true,
- },
- {
- image: 'canvasApp',
- title: 'Integration 8',
- description: 'Description for integration 8',
- isEnable: false,
- },
- {
- image: 'securityApp',
- title: 'Integration 9',
- description: 'Description for integration 9',
- isEnable: true,
- },
- {
- image: 'lensApp',
- title: 'Integration 10',
- description: 'Description for integration 10',
- isEnable: false,
- },
-];
+import { integrations } from './mock-data-integrations';
export const IntegrationOverview = () => {
+ const [query, setQuery] = useState({ text: '' });
+ const [error, setError] = useState(null);
const [lastUpdate, setLastUpdate] = useState({
lastUpdateDate: '12/18/2024',
status: 'Success',
});
+ // Header page start
const titleHeader = (
Integrations
@@ -99,13 +40,29 @@ export const IntegrationOverview = () => {
});
};
- // Search bar
+ const descriptionHeader = (
+ <>
+ Last update of the content manager was {lastUpdate.lastUpdateDate} (
+ {lastUpdate.status}).{' '}
+
+ Learn more
+
+ >
+ );
+ const rightSideItems = [
+
+ Update
+ ,
+ ];
- const initialQuery = EuiSearchBar.Query.MATCH_ALL;
- const [query, setQuery] = useState(initialQuery);
- const [error, setError] = useState(null);
+ // Header page end
+ // Search bar start
- const onChange = ({ query, error }) => {
+ const onChange = ({ query, error }: { query: Query; error: Error }) => {
if (error) {
setError(error);
} else {
@@ -137,61 +94,33 @@ export const IntegrationOverview = () => {
},
};
- const renderError = () => {
- if (!error) {
- return;
- }
-
- return (
- <>
-
- >
- );
- };
+ // Search bar end
return (
<>
-
- Last update of the content manager was {lastUpdate.lastUpdateDate} (
- {lastUpdate.status}).{' '}
-
- Learn more
-
- >
- }
- rightSideItems={[
-
- Update
- ,
- ]}
+
+
-
-
-
- {renderError()}
{query.text === ''
? integrations.map((integration, index) => (
-
+
))
@@ -202,7 +131,15 @@ export const IntegrationOverview = () => {
.includes(integration.title.toLocaleLowerCase()),
)
.map((integration, index) => (
-
+
))}
From 1143229c75f110d57521acf2b761318d4697dae9 Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Fri, 17 Jan 2025 15:48:54 +0100
Subject: [PATCH 07/30] Add tty:true on osd service dev.yml
---
docker/osd-dev/dev.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/docker/osd-dev/dev.yml b/docker/osd-dev/dev.yml
index fdf249c453..2dcc8a56d5 100755
--- a/docker/osd-dev/dev.yml
+++ b/docker/osd-dev/dev.yml
@@ -239,6 +239,7 @@ services:
- ${OSD_PORT}:5601
environment:
- 'LOGS=/proc/1/fd/1'
+ tty: true
volumes:
- osd_cache:/home/node/.cache
- '${SRC}/main:/home/node/kbn/plugins/main'
From 7ec4a22fb9f2395eb2fcd563016f83083ac3ecc1 Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Fri, 17 Jan 2025 22:19:52 +0100
Subject: [PATCH 08/30] Add no-results.tsx
---
.../public/components/common/no-results.tsx | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 plugins/wazuh-security-policies/public/components/common/no-results.tsx
diff --git a/plugins/wazuh-security-policies/public/components/common/no-results.tsx b/plugins/wazuh-security-policies/public/components/common/no-results.tsx
new file mode 100644
index 0000000000..8e8f5dbce7
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/common/no-results.tsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import { EuiEmptyPrompt } from '@elastic/eui';
+
+export const NoResultsData = (props: { query: { text: string } }) => {
+ const { query } = props;
+
+ return (
+ No results found}
+ body={
+ <>
+
+ No results found for the search with the value '{query.text}
+ '.
+
+ >
+ }
+ />
+ );
+};
From 2c59f77030aaad2c61b88a057c53be22f52249e7 Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Fri, 17 Jan 2025 22:22:22 +0100
Subject: [PATCH 09/30] Add category new menu
---
.../wazuh-security-policies/public/plugin.ts | 32 ++++++++++++-------
.../wazuh-security-policies/public/types.ts | 5 ++-
2 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/plugins/wazuh-security-policies/public/plugin.ts b/plugins/wazuh-security-policies/public/plugin.ts
index 20597720f5..98039ebe47 100644
--- a/plugins/wazuh-security-policies/public/plugin.ts
+++ b/plugins/wazuh-security-policies/public/plugin.ts
@@ -4,6 +4,7 @@ import {
AppMountParameters,
CoreSetup,
CoreStart,
+ DEFAULT_NAV_GROUPS,
Plugin,
} from '../../../src/core/public';
import { PLUGIN_NAME } from '../common';
@@ -19,16 +20,18 @@ export class WazuhSecurityPoliciesPlugin
Plugin
{
public setup(core: CoreSetup): WazuhSecurityPoliciesPluginSetup {
+ const pluginId = 'wazuhSecurityPolicies';
+
// Register an application into the side navigation menu
core.application.register({
- id: 'wazuhSecurityPolicies',
+ id: pluginId,
title: PLUGIN_NAME,
category: {
id: 'wz-category-security-policies',
label: i18n.translate('wz-app-category-security-policies', {
defaultMessage: 'Security Policies',
}),
- order: 200,
+ order: 1000,
euiIconType: 'indexRollupApp',
},
async mount(params: AppMountParameters) {
@@ -48,17 +51,22 @@ export class WazuhSecurityPoliciesPlugin
},
});
- // Return methods that should be available to other plugins
- return {
- getGreeting() {
- return i18n.translate('wazuhSecurityPolicies.greetingText', {
- defaultMessage: 'Hello from {name}!',
- values: {
- name: PLUGIN_NAME,
- },
- });
+ core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.all, [
+ {
+ id: pluginId,
+ category: {
+ id: 'wz-category-security-policies',
+ label: i18n.translate('wz-app-category-security-policies', {
+ defaultMessage: 'Security Policies',
+ }),
+ order: 1000,
+ euiIconType: 'indexRollupApp',
+ },
},
- };
+ ]);
+
+ // Return methods that should be available to other plugins
+ return {};
}
public start(core: CoreStart): WazuhSecurityPoliciesPluginStart {
diff --git a/plugins/wazuh-security-policies/public/types.ts b/plugins/wazuh-security-policies/public/types.ts
index 54154e6226..1ea2b0bf0f 100644
--- a/plugins/wazuh-security-policies/public/types.ts
+++ b/plugins/wazuh-security-policies/public/types.ts
@@ -1,8 +1,7 @@
import { NavigationPublicPluginStart } from '../../../src/plugins/navigation/public';
-export interface WazuhSecurityPoliciesPluginSetup {
- getGreeting: () => string;
-}
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
+export interface WazuhSecurityPoliciesPluginSetup {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type
export interface WazuhSecurityPoliciesPluginStart {}
From b7185393a98481a5d778c6104138e70171fcc367 Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Fri, 17 Jan 2025 22:26:54 +0100
Subject: [PATCH 10/30] Refactors
---
.../last-update-content-manager-text.tsx.tsx | 15 +++
.../public/components/common/searchbar.tsx | 21 +++-
...ntegration.tsx => integration-details.tsx} | 15 +--
.../components/integretions/overview.tsx | 105 +++++++-----------
4 files changed, 81 insertions(+), 75 deletions(-)
create mode 100644 plugins/wazuh-security-policies/public/components/common/last-update-content-manager-text.tsx.tsx
rename plugins/wazuh-security-policies/public/components/integretions/{integration.tsx => integration-details.tsx} (90%)
diff --git a/plugins/wazuh-security-policies/public/components/common/last-update-content-manager-text.tsx.tsx b/plugins/wazuh-security-policies/public/components/common/last-update-content-manager-text.tsx.tsx
new file mode 100644
index 0000000000..44733ff087
--- /dev/null
+++ b/plugins/wazuh-security-policies/public/components/common/last-update-content-manager-text.tsx.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import { EuiLink } from '@elastic/eui';
+
+export const LastUpdateContentManagerText = (lastUpdate: {
+ lastUpdateDate: string;
+ status: string;
+}) => (
+ <>
+ Last update of the content manager was {lastUpdate.lastUpdateDate} (
+ {lastUpdate.status}).{' '}
+
+ Learn more
+
+ >
+);
diff --git a/plugins/wazuh-security-policies/public/components/common/searchbar.tsx b/plugins/wazuh-security-policies/public/components/common/searchbar.tsx
index 8a296fe861..7b5f858290 100644
--- a/plugins/wazuh-security-policies/public/components/common/searchbar.tsx
+++ b/plugins/wazuh-security-policies/public/components/common/searchbar.tsx
@@ -1,10 +1,25 @@
-import React from 'react';
-import { EuiCallOut, EuiSearchBar, EuiSearchBarProps } from '@elastic/eui';
+import React, { useState } from 'react';
+import {
+ EuiCallOut,
+ EuiSearchBar,
+ EuiSearchBarProps,
+ Query,
+} from '@elastic/eui';
const initialQuery = EuiSearchBar.Query.MATCH_ALL;
export const SearchBar = (props: EuiSearchBarProps) => {
- const { schema, filters, onChange, error } = props;
+ const { schema, filters, setQuery } = props;
+ const [error, setError] = useState(null);
+
+ const onChange = ({ query, error }: { query: Query; error: Error }) => {
+ if (error) {
+ setError(error);
+ } else {
+ setError(null);
+ setQuery(query);
+ }
+ };
const renderError = () => {
if (!error) {
diff --git a/plugins/wazuh-security-policies/public/components/integretions/integration.tsx b/plugins/wazuh-security-policies/public/components/integretions/integration-details.tsx
similarity index 90%
rename from plugins/wazuh-security-policies/public/components/integretions/integration.tsx
rename to plugins/wazuh-security-policies/public/components/integretions/integration-details.tsx
index 37852da382..656cf442dc 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/integration.tsx
+++ b/plugins/wazuh-security-policies/public/components/integretions/integration-details.tsx
@@ -2,13 +2,13 @@ import React, { useEffect, useState } from 'react';
import {
EuiHealth,
EuiIcon,
- EuiLink,
EuiButton,
EuiDescriptionList,
EuiPanel,
} from '@elastic/eui';
import { useParams } from 'react-router-dom';
import { HeaderPage } from '../common/header-page';
+import { LastUpdateContentManagerText } from '../common/last-update-content-manager-text.tsx';
import { integrations } from './mock-data-integrations';
import './integrations.scss';
import { IntegrationDescription } from './components/integration-description';
@@ -31,9 +31,11 @@ export const IntegrationView = () => {
date: string;
};
references: string[];
+ module: string;
}>({
image: '',
title: '',
+ module: '',
description: '',
isEnable: false,
lastUpdate: { lastUpdateDate: '', status: '' },
@@ -74,15 +76,8 @@ export const IntegrationView = () => {
);
- const descriptionHeader = (
- <>
- Last update of the content manager was{' '}
- {integrationData.lastUpdate.lastUpdateDate} (
- {integrationData.lastUpdate.status}).{' '}
-
- Learn more
-
- >
+ const descriptionHeader = LastUpdateContentManagerText(
+ integrationData.lastUpdate,
);
const toggleEnableOrDisable = () => {
diff --git a/plugins/wazuh-security-policies/public/components/integretions/overview.tsx b/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
index e3f06cfe6b..5f3c4d3a33 100644
--- a/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
+++ b/plugins/wazuh-security-policies/public/components/integretions/overview.tsx
@@ -1,22 +1,21 @@
import React, { useState } from 'react';
import {
- EuiLink,
EuiButton,
EuiHealth,
EuiFlexGroup,
EuiFlexItem,
EuiText,
- Query,
} from '@elastic/eui';
import './integrations.scss';
import { SearchBar } from '../common/searchbar';
import { HeaderPage } from '../common/header-page';
+import { LastUpdateContentManagerText } from '../common/last-update-content-manager-text.tsx';
+import { NoResultsData } from '../common/no-results';
import { CardIntegration } from './components/card-integration';
import { integrations } from './mock-data-integrations';
export const IntegrationOverview = () => {
const [query, setQuery] = useState({ text: '' });
- const [error, setError] = useState(null);
const [lastUpdate, setLastUpdate] = useState({
lastUpdateDate: '12/18/2024',
status: 'Success',
@@ -40,14 +39,8 @@ export const IntegrationOverview = () => {
});
};
- const descriptionHeader = (
- <>
- Last update of the content manager was {lastUpdate.lastUpdateDate} (
- {lastUpdate.status}).{' '}
-
- Learn more
-
- >
+ const descriptionHeader = LastUpdateContentManagerText(
+ integrations[0].lastUpdate,
);
const rightSideItems = [
{
Update
,
];
-
// Header page end
// Search bar start
-
- const onChange = ({ query, error }: { query: Query; error: Error }) => {
- if (error) {
- setError(error);
- } else {
- setError(null);
- setQuery(query);
- }
- };
-
const filters = [
{
type: 'field_value_selection',
@@ -93,8 +75,39 @@ export const IntegrationOverview = () => {
},
},
};
-
// Search bar end
+ const listAllIntegrationsComponent = integrations.map(
+ (integration, index) => (
+
+
+
+ ),
+ );
+ const integrationFilter = integrations
+ .filter(integration =>
+ query.text
+ .toLocaleLowerCase()
+ .includes(integration.title.toLocaleLowerCase()),
+ )
+ .map((integration, index) => (
+
+
+
+ ));
return (
<>
@@ -103,46 +116,14 @@ export const IntegrationOverview = () => {
descriptionHeader={descriptionHeader}
rightSideItems={rightSideItems}
/>
-
+
- {query.text === ''
- ? integrations.map((integration, index) => (
-
-
-
- ))
- : integrations
- .filter(integration =>
- query.text
- .toLocaleLowerCase()
- .includes(integration.title.toLocaleLowerCase()),
- )
- .map((integration, index) => (
-
-
-
- ))}
+ {!query.text && listAllIntegrationsComponent}
+ {query.text && integrationFilter.length === 0 ? (
+
+ ) : (
+ integrationFilter
+ )}
>
);
From c78abd97ddf69159936c0f075442aac99f044e8a Mon Sep 17 00:00:00 2001
From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com>
Date: Fri, 17 Jan 2025 22:28:54 +0100
Subject: [PATCH 11/30] Add rules views
---
.../public/components/app.tsx | 20 +-
.../integretions/mock-data-rules.tsx | 746 ++++++++++++++++++
.../public/components/rules/overview.tsx | 90 +++
.../public/components/rules/rule-details.tsx | 7 +
4 files changed, 860 insertions(+), 3 deletions(-)
create mode 100644 plugins/wazuh-security-policies/public/components/integretions/mock-data-rules.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/rules/overview.tsx
create mode 100644 plugins/wazuh-security-policies/public/components/rules/rule-details.tsx
diff --git a/plugins/wazuh-security-policies/public/components/app.tsx b/plugins/wazuh-security-policies/public/components/app.tsx
index f5663fe469..135546d068 100644
--- a/plugins/wazuh-security-policies/public/components/app.tsx
+++ b/plugins/wazuh-security-policies/public/components/app.tsx
@@ -10,7 +10,9 @@ import {
import { Router, Route, Switch, Redirect, useParams } from 'react-router-dom';
import { getCore, getHistory } from '../plugin-services';
import { IntegrationOverview } from './integretions/overview';
-import { IntegrationView } from './integretions/integration';
+import { IntegrationView } from './integretions/integration-details';
+import { RulesOverview } from './rules/overview';
+import { RuleDetails } from './rules/rule-details';
interface ViewInterface {
name: string;
@@ -29,7 +31,8 @@ const views: ViewInterface[] = [
{
name: 'Rules',
id: 'rules',
- render: () => Rules
,
+ render: () => ,
+ renderDetails: () => ,
},
{
name: 'Decoders',
@@ -46,6 +49,11 @@ const views: ViewInterface[] = [
export const WazuhSecurityPoliciesApp = () => {
const history = getHistory();
const [currentTab, setCurrentTab] = useState('');
+ const [isSideNavOpenOnMobile, setIsSideNavOpenOnMobile] = useState(false);
+
+ const toggleOpenOnMobile = () => {
+ setIsSideNavOpenOnMobile(!isSideNavOpenOnMobile);
+ };
useEffect(() => {
setCurrentTab(history.location.pathname);
@@ -76,7 +84,13 @@ export const WazuhSecurityPoliciesApp = () => {
<>
-
+ toggleOpenOnMobile()}
+ isOpenOnMobile={isSideNavOpenOnMobile}
+ aria-label='Ruleset'
+ items={sideNav}
+ />
[]:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/1',
+ provider: 'native',
+ status: 'disable',
+ metadata: {
+ module: 'syslog2',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/2',
+ provider: 'native',
+ status: 'disable',
+ metadata: {
+ module: 'syslog3',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/0',
+ provider: 'native',
+ status: 'disable',
+ metadata: {
+ module: 'syslog4',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/1',
+ provider: 'native',
+ status: 'disable',
+ metadata: {
+ module: 'syslog5',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/2',
+ provider: 'native',
+ status: 'draft',
+ metadata: {
+ module: 'syslog6',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/0',
+ provider: 'custom',
+ status: 'enable',
+ metadata: {
+ module: 'syslog',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/1',
+ provider: 'custom',
+ status: 'enable',
+ metadata: {
+ module: 'syslog',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ ' []: ',
+ description: 'BSD Syslog RFC 3164 standard ISO8601',
+ },
+ {
+ pattern:
+ ' : ',
+ description: 'BSD Syslog RFC 3164 no pid ISO8601',
+ },
+ {
+ pattern: ' ',
+ description: 'RFC3164 example 2 section 5.4',
+ },
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'RFC3164 example 4 section 5.4',
+ },
+ ],
+ normalize: [
+ {
+ map: [
+ { 'event.kind': 'event' },
+ { 'wazuh.decoders': 'array_append(syslog)' },
+ { 'related.hosts': 'array_append($host.hostname)' },
+ { 'process.name': 'rename($TAG)' },
+ { 'host.ip': 'array_append($tmp.host_ip)' },
+ ],
+ },
+ ],
+ },
+ {
+ name: 'decoder/syslog/2',
+ provider: 'custom',
+ status: 'enable',
+ metadata: {
+ module: 'syslog',
+ title: 'Syslog Decoder event',
+ description: 'Syslog header',
+ compatibility: 'This decoder has been tested on Wazuh version 4.3',
+ author: {
+ name: 'Wazuh, Inc.',
+ url: 'https://wazuh.com',
+ date: '2022/11/08',
+ },
+ references: [
+ 'https://www.ietf.org/rfc/rfc3164.txt',
+ 'https://www.ietf.org/rfc/rfc5424.txt',
+ ],
+ },
+ 'parse|event.original': [
+ {
+ pattern:
+ ' []:<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 standard',
+ },
+ {
+ pattern:
+ ' :<~/ignore/ >',
+ description: 'BSD Syslog RFC 3164 no pid',
+ },
+ {
+ pattern:
+ '