From 90caf06e393844b1ab007b23b1f689ea73c0beb1 Mon Sep 17 00:00:00 2001 From: Mathieu Ancelin Date: Mon, 4 Sep 2023 16:20:09 +0200 Subject: [PATCH] move extension to javascript bundle --- otoroshi/app/wasm/proxywasm/coraza.scala | 10 +- otoroshi/conf/schemas/openapi.json | 2 +- otoroshi/javascript/src/backoffice.js | 2 + .../javascript/src/components/inputs/Table.js | 13 ++- .../src/extensions/coraza/index.js} | 102 +++++++++--------- otoroshi/public/openapi.json | 2 +- 6 files changed, 71 insertions(+), 60 deletions(-) rename otoroshi/{public/javascripts/extensions/coraza-extension.js => javascript/src/extensions/coraza/index.js} (62%) diff --git a/otoroshi/app/wasm/proxywasm/coraza.scala b/otoroshi/app/wasm/proxywasm/coraza.scala index 697260261b..09b1f29aad 100644 --- a/otoroshi/app/wasm/proxywasm/coraza.scala +++ b/otoroshi/app/wasm/proxywasm/coraza.scala @@ -693,11 +693,11 @@ class CorazaWafAdminExtension(val env: Env) extends AdminExtension { } } - override def frontendExtensions(): Seq[AdminExtensionFrontendExtension] = { - Seq( - AdminExtensionFrontendExtension("/__otoroshi_assets/javascripts/extensions/coraza-extension.js") - ) - } + // override def frontendExtensions(): Seq[AdminExtensionFrontendExtension] = { + // Seq( + // AdminExtensionFrontendExtension("/__otoroshi_assets/javascripts/extensions/coraza-extension.js") + // ) + // } override def entities(): Seq[AdminExtensionEntity[EntityLocationSupport]] = { Seq( diff --git a/otoroshi/conf/schemas/openapi.json b/otoroshi/conf/schemas/openapi.json index a467b0fcb0..bd52ca8f8b 100644 --- a/otoroshi/conf/schemas/openapi.json +++ b/otoroshi/conf/schemas/openapi.json @@ -3,7 +3,7 @@ "info" : { "title" : "Otoroshi Admin API", "description" : "Admin API of the Otoroshi reverse proxy", - "version" : "16.7.0-dev", + "version" : "16.8.0-dev", "contact" : { "name" : "Otoroshi Team", "email" : "oss@maif.fr" diff --git a/otoroshi/javascript/src/backoffice.js b/otoroshi/javascript/src/backoffice.js index a9fb266fb4..a8dafe702a 100644 --- a/otoroshi/javascript/src/backoffice.js +++ b/otoroshi/javascript/src/backoffice.js @@ -28,6 +28,7 @@ import { v4 as uuid } from 'uuid'; import { registerAlert, registerConfirm, registerPrompt, registerPopup } from './components/window'; import { setupGreenScoreExtension } from './extensions/greenscore'; +import { setupCorazaExtension } from './extensions/coraza'; import * as Forms from './forms/ng_plugins/index'; @@ -249,4 +250,5 @@ export function getExtension(name) { function setupLocalExtensions() { setupGreenScoreExtension(registerExtension); + setupCorazaExtension(registerExtension); } diff --git a/otoroshi/javascript/src/components/inputs/Table.js b/otoroshi/javascript/src/components/inputs/Table.js index 2f3fa476ec..cd17082725 100644 --- a/otoroshi/javascript/src/components/inputs/Table.js +++ b/otoroshi/javascript/src/components/inputs/Table.js @@ -6,6 +6,7 @@ import debounce from 'lodash/debounce'; import { createTooltip } from '../../tooltips'; import ReactTable from 'react-table'; import { NgSelectRenderer } from '../nginputs'; +import _ from 'lodash'; function urlTo(url) { window.history.replaceState({}, '', url); @@ -360,6 +361,14 @@ export class Table extends Component { isAnObject = (variable) => typeof variable === 'object' && !Array.isArray(variable) && variable !== null; + actualFlow = () => { + if (_.isFunction(this.props.formFlow)) { + return this.props.formFlow(this.state.currentItem); + } else { + return this.props.formFlow; + } + } + exportYaml = (e) => { if (e && e.preventDefault) e.preventDefault(); const name = (this.state.currentItem.name || this.state.currentItem.clientName) @@ -692,7 +701,7 @@ export class Table extends Component { ]} {!this.props.formComponent && !this.props.formFunction && - (this.props.formFlow.find((item) => this.isAnObject(item)) ? ( + (this.actualFlow().find((item) => this.isAnObject(item)) ? ( this.setState({ currentItem })} @@ -767,7 +776,7 @@ export class Table extends Component { ]} {!this.props.formComponent && !this.props.formFunction && - (this.props.formFlow.find((item) => this.isAnObject(item)) ? ( + (this.actualFlow().find((item) => this.isAnObject(item)) ? ( this.setState({ currentItem })} diff --git a/otoroshi/public/javascripts/extensions/coraza-extension.js b/otoroshi/javascript/src/extensions/coraza/index.js similarity index 62% rename from otoroshi/public/javascripts/extensions/coraza-extension.js rename to otoroshi/javascript/src/extensions/coraza/index.js index 81040c73c4..1c73219f35 100644 --- a/otoroshi/public/javascripts/extensions/coraza-extension.js +++ b/otoroshi/javascript/src/extensions/coraza/index.js @@ -1,60 +1,60 @@ -(function() { - const extensionId = "otoroshi.extensions.CorazaWAF"; - Otoroshi.registerExtension(extensionId, (ctx) => { +import React, { Component } from 'react'; +import { v4 as uuid } from 'uuid'; +import * as BackOfficeServices from '../../services/BackOfficeServices'; +import { nextClient } from '../../services/BackOfficeServices'; +import { Table } from '../../components/inputs/Table'; - const dependencies = ctx.dependencies; - - const React = dependencies.react; - const Component = React.Component; - const uuid = dependencies.uuid; - const Table = dependencies.Components.Inputs.Table; - const BackOfficeServices = dependencies.BackOfficeServices; +const extensionId = "otoroshi.extensions.CorazaWAF"; + +export function setupCorazaExtension(registerExtension) { + + registerExtension(extensionId, (ctx) => { class CorazaWafConfigsPage extends Component { - + formSchema = { _loc: { - type: 'location', - props: {}, + type: 'location', + props: {}, }, id: { type: 'string', disabled: true, props: { label: 'Id', placeholder: '---' } }, name: { - type: 'string', - props: { label: 'Name', placeholder: 'My Awesome WAF' }, + type: 'string', + props: { label: 'Name', placeholder: 'My Awesome WAF' }, }, description: { - type: 'string', - props: { label: 'Description', placeholder: 'Description of the WAF config' }, + type: 'string', + props: { label: 'Description', placeholder: 'Description of the WAF config' }, }, metadata: { - type: 'object', - props: { label: 'Metadata' }, + type: 'object', + props: { label: 'Metadata' }, }, tags: { - type: 'array', - props: { label: 'Tags' }, + type: 'array', + props: { label: 'Tags' }, }, inspect_body: { - type: 'bool', - props: { label: 'Inspect req/res body' } + type: 'bool', + props: { label: 'Inspect req/res body' } }, pool_capacity: { - type: 'number', - props: { label: 'Number of coraza instances' } + type: 'number', + props: { label: 'Number of coraza instances' } }, config: { - type: 'jsonobjectcode', - props: { + type: 'jsonobjectcode', + props: { label: 'Coraza config.' - } + } } }; columns = [ { - title: 'Name', - filterId: 'name', - content: (item) => item.name, + title: 'Name', + filterId: 'name', + content: (item) => item.name, }, { title: 'Description', filterId: 'description', content: (item) => item.description }, ]; @@ -64,7 +64,7 @@ componentDidMount() { this.props.setTitle(`All Coraza WAF configs.`); } - + client = BackOfficeServices.apisClient('coraza-waf.extensions.otoroshi.io', 'v1', 'coraza-configs'); render() { @@ -74,25 +74,25 @@ selfUrl: "extensions/coraza-waf/coraza-configs", defaultTitle: "All Coraza WAF configs.", defaultValue: () => ({ - id: 'coraza-waf-config_' + uuid(), - name: 'My WAF', - description: 'An awesome WAF', - tags: [], - metadata: {}, - inspect_body: true, - config: { + id: 'coraza-waf-config_' + uuid(), + name: 'My WAF', + description: 'An awesome WAF', + tags: [], + metadata: {}, + inspect_body: true, + config: { "directives_map": { "default": [ - "Include @recommended-conf", - "Include @crs-setup-conf", - "Include @owasp_crs/*.conf", - "SecRuleEngine DetectionOnly" + "Include @recommended-conf", + "Include @crs-setup-conf", + "Include @owasp_crs/*.conf", + "SecRuleEngine DetectionOnly" ] }, "default_directives": "default", "metric_labels": {}, "per_authority_directives": {} - } + } }), itemName: "Coraza WAF config", formSchema: this.formSchema, @@ -104,7 +104,7 @@ deleteItem: this.client.delete, createItem: this.client.create, navigateTo: (item) => { - window.location = `/bo/dashboard/extensions/coraza-waf/coraza-configs/edit/${item.id}` + window.location = `/bo/dashboard/extensions/coraza-waf/coraza-configs/edit/${item.id}` }, itemUrl: (item) => `/bo/dashboard/extensions/coraza-waf/coraza-configs/edit/${item.id}`, showActions: true, @@ -113,7 +113,7 @@ extractKey: (item) => item.id, export: true, kubernetesKind: "CorazaConfig" - }, null) + }, null) ); } } @@ -138,7 +138,7 @@ action: () => { window.location.href = `/bo/dashboard/extensions/coraza-waf/coraza-configs` }, - env: React.createElement('span', { className: "fas fa-cubes" }, null), + env: , label: 'Coraza WAF configs.', value: 'coraza-configs', } @@ -147,22 +147,22 @@ { path: '/extensions/coraza-waf/coraza-configs/:taction/:titem', component: (props) => { - return React.createElement(CorazaWafConfigsPage, props, null) + return } }, { path: '/extensions/coraza-waf/coraza-configs/:taction', component: (props) => { - return React.createElement(CorazaWafConfigsPage, props, null) + return } }, { path: '/extensions/coraza-waf/coraza-configs', component: (props) => { - return React.createElement(CorazaWafConfigsPage, props, null) + return } } ], } }); -})(); \ No newline at end of file +} \ No newline at end of file diff --git a/otoroshi/public/openapi.json b/otoroshi/public/openapi.json index a467b0fcb0..bd52ca8f8b 100644 --- a/otoroshi/public/openapi.json +++ b/otoroshi/public/openapi.json @@ -3,7 +3,7 @@ "info" : { "title" : "Otoroshi Admin API", "description" : "Admin API of the Otoroshi reverse proxy", - "version" : "16.7.0-dev", + "version" : "16.8.0-dev", "contact" : { "name" : "Otoroshi Team", "email" : "oss@maif.fr"