mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-10-29 17:23:13 +08:00
增加手工编写规则的方式
This commit is contained in:
+22
-10
@@ -396,19 +396,27 @@ func StartLocalServer() {
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var rule_code = uuid.NewV4().String()
|
||||
rule_info.RuleBase.RuleName = strings.Replace(rule_code, "-", "", -1)
|
||||
|
||||
var ruleContent = rule_tool.GenRuleInfo(rule_info, rulename)
|
||||
if waf_rule_add_req.IsManualRule == 1 {
|
||||
ruleContent = rule_info.RuleContent
|
||||
}
|
||||
|
||||
var waf_rule = &model.Rules{
|
||||
TenantId: global.GWAF_TENANT_ID,
|
||||
HostCode: rule_info.RuleBase.RuleDomainCode, //网站CODE
|
||||
RuleCode: rule_code,
|
||||
RuleName: rulename,
|
||||
RuleContent: rule_tool.GenRuleInfo(rule_info, rulename),
|
||||
RuleContent: ruleContent,
|
||||
RuleContentJSON: waf_rule_add_req.RuleJson, //TODO 后续考虑是否应该再从结构转一次
|
||||
RuleVersionName: "初版",
|
||||
RuleVersion: 1,
|
||||
UserCode: global.GWAF_USER_CODE,
|
||||
IsPublicRule: 0,
|
||||
IsManualRule: waf_rule_add_req.IsManualRule,
|
||||
RuleStatus: 1,
|
||||
}
|
||||
//waf_host_add_req.USER_CODE =
|
||||
@@ -436,8 +444,8 @@ func StartLocalServer() {
|
||||
err := c.ShouldBind(&waf_rule_edit_req)
|
||||
if err == nil {
|
||||
|
||||
var rule_tool = model.RuleTool{}
|
||||
rule_info, err := rule_tool.LoadRule(waf_rule_edit_req.RuleJson)
|
||||
var ruleTool = model.RuleTool{}
|
||||
ruleInfo, err := ruleTool.LoadRule(waf_rule_edit_req.RuleJson)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, response.Response{
|
||||
Code: -1,
|
||||
@@ -445,11 +453,11 @@ func StartLocalServer() {
|
||||
})
|
||||
return
|
||||
}
|
||||
var rule_name = rule_info.RuleBase.RuleName //中文名
|
||||
var ruleName = ruleInfo.RuleBase.RuleName //中文名
|
||||
|
||||
var rule model.Rules
|
||||
global.GWAF_LOCAL_DB.Debug().Where("rule_name = ? and host_code= ?",
|
||||
rule_name, rule_info.RuleBase.RuleDomainCode).Find(&rule)
|
||||
ruleName, ruleInfo.RuleBase.RuleDomainCode).Find(&rule)
|
||||
|
||||
if rule.Id != 0 && rule.RuleCode != waf_rule_edit_req.CODE {
|
||||
c.JSON(http.StatusOK, response.Response{
|
||||
@@ -461,17 +469,21 @@ func StartLocalServer() {
|
||||
|
||||
global.GWAF_LOCAL_DB.Debug().Where("rule_code=?", waf_rule_edit_req.CODE).Find(&rule)
|
||||
|
||||
rule_info.RuleBase.RuleName = strings.Replace(rule.RuleCode, "-", "", -1)
|
||||
|
||||
ruleInfo.RuleBase.RuleName = strings.Replace(rule.RuleCode, "-", "", -1)
|
||||
var ruleContent = ruleTool.GenRuleInfo(ruleInfo, ruleName)
|
||||
if waf_rule_edit_req.IsManualRule == 1 {
|
||||
ruleContent = ruleInfo.RuleContent
|
||||
}
|
||||
ruleMap := map[string]interface{}{
|
||||
"HostCode": rule_info.RuleBase.RuleDomainCode, //TODO 注意字典名称
|
||||
"RuleName": rule_name,
|
||||
"RuleContent": rule_tool.GenRuleInfo(rule_info, rule_name),
|
||||
"HostCode": ruleInfo.RuleBase.RuleDomainCode, //TODO 注意字典名称
|
||||
"RuleName": ruleName,
|
||||
"RuleContent": ruleContent,
|
||||
"RuleContentJSON": waf_rule_edit_req.RuleJson, //TODO 后续考虑是否应该再从结构转一次
|
||||
"RuleVersionName": "初版",
|
||||
"RuleVersion": rule.RuleVersion + 1,
|
||||
"User_code": global.GWAF_USER_CODE,
|
||||
"IsPublicRule": 0,
|
||||
"IsManualRule": waf_rule_edit_req.IsManualRule,
|
||||
"RuleStatus": "1",
|
||||
//"UPDATE_TIME": time.Now(),
|
||||
}
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
"nprogress": "^0.2.0",
|
||||
"qrcode.vue": "^1.7.0",
|
||||
"tdesign-icons-vue": "^0.1.4",
|
||||
"tdesign-vue": "^0.46.0",
|
||||
"tdesign-vue": "^0.49.0",
|
||||
"tvision-color": "~1.4.0",
|
||||
"typescript": "^4.2.4",
|
||||
"vue": "~2.6.14",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-codemirror": "^4.0.6",
|
||||
"vue-router": "^3.5.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
@@ -57,6 +58,7 @@
|
||||
"stylelint-order": "~4.1.0",
|
||||
"vite": "^2.7.10",
|
||||
"vite-plugin-mock": "^2.3.0",
|
||||
"vite-plugin-require-transform": "^1.0.4",
|
||||
"vite-plugin-theme": "^0.8.1",
|
||||
"vite-plugin-vue2": "^2.0.1",
|
||||
"vite-plugin-vue2-svg": "~0.3.0",
|
||||
@@ -86,4 +88,4 @@
|
||||
]
|
||||
},
|
||||
"description": "localwaf"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// bus.js
|
||||
import Vue from 'vue';
|
||||
const bus = new Vue();
|
||||
export default bus
|
||||
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="in-coder-panel">
|
||||
<textarea ref="mycode" v-model="code" class="text_cls" ></textarea>
|
||||
<input type="button" @click="send_msg_to_parent" value="测试向父组件传参"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
import 'codemirror/addon/hint/show-hint.css'
|
||||
const CodeMirror = require('codemirror/lib/codemirror')
|
||||
require('codemirror/addon/edit/matchbrackets')
|
||||
require('codemirror/addon/selection/active-line')
|
||||
require('codemirror/mode/sql/sql')
|
||||
require('codemirror/addon/hint/show-hint')
|
||||
require('codemirror/addon/hint/sql-hint')
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 外部传入的内容,用于实现双向绑定
|
||||
valuecontent:{
|
||||
type:String,
|
||||
|
||||
} ,
|
||||
// 外部传入的语法类型
|
||||
language: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
valuecontent(newVal) {
|
||||
//父组件传过来的值,这个需求需要传入点击的数据库表名,默认展示“SELECT * FROM student”
|
||||
this.editor.setValue('SELECT * FROM '+newVal)
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
code: '',
|
||||
editor: null,
|
||||
content: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化
|
||||
this._initialize()
|
||||
},
|
||||
methods: {
|
||||
send_msg_to_parent () {
|
||||
|
||||
|
||||
console.log(this.$parent)
|
||||
//this.$parent.edtinput("asdfadf")
|
||||
//this.$emit('edtinput',"sdsdsd" )
|
||||
console.log("ssss")
|
||||
},
|
||||
//父组件调用清空的方法
|
||||
resetData() {
|
||||
this.editor.setValue('')
|
||||
},
|
||||
// 初始化
|
||||
_initialize() {
|
||||
const mime = 'text/x-mariadb'
|
||||
// let theme = 'ambiance'//设置主题,不设置的会使用默认主题
|
||||
this.editor = CodeMirror.fromTextArea(this.$refs.mycode, {
|
||||
// 选择对应代码编辑器的语言,我这边选的是数据库,根据个人情况自行设置即可
|
||||
mode: mime,
|
||||
indentWithTabs: true,
|
||||
smartIndent: true,
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
extraKeys: {
|
||||
// 触发提示按键
|
||||
Ctrl: 'autocomplete',
|
||||
},
|
||||
hintOptions: {
|
||||
// 自定义提示选项
|
||||
completeSingle: false, // 当匹配只有一项的时候是否自动补全
|
||||
tables: {}, // 代码提示
|
||||
},
|
||||
})
|
||||
this.editor.setValue(this.value || this.code)
|
||||
// 支持双向绑定
|
||||
let that = this
|
||||
this.editor.on('change', (coder) => {
|
||||
this.code = coder.getValue()
|
||||
if (this.$emit) {
|
||||
// 通过监听Input事件可以拿到动态改变的code值
|
||||
//this.$emit('edtinput', this.code)
|
||||
console.log('在子组件里面edtinput', this.code)
|
||||
//this.$emit('update:valuecontent', this.code)
|
||||
/* setTimeout(() => {
|
||||
|
||||
}, 0) */ that.$emit('edtinput', this.code)
|
||||
console.log(that.$parent)
|
||||
that.$bus.$emit("codeedit",this.code)
|
||||
}
|
||||
})
|
||||
this.editor.on('inputRead', () => {
|
||||
this.editor.showHint()
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.CodeMirror {
|
||||
height: 180px !important;
|
||||
}
|
||||
.in-coder-panel {
|
||||
border-radius: 5px;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
position: relative;
|
||||
.text_cls {
|
||||
}
|
||||
.cm-variable {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
.CodeMirror {
|
||||
flex-grow: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
.CodeMirror-code {
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
.code-mode-select {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
max-width: 130px;
|
||||
}
|
||||
</style>
|
||||
@@ -8,6 +8,7 @@ import App from './App.vue';
|
||||
import router from './router';
|
||||
import zhConfig from 'tdesign-vue/es/locale/zh_CN';
|
||||
// import enConfig from 'tdesign-vue/es/locale/en_US'; // 英文多语言配置
|
||||
import bus from './bus/bus'
|
||||
|
||||
import 'tdesign-vue/es/style/index.css';
|
||||
import '@/style/index.less';
|
||||
@@ -18,6 +19,7 @@ import store from './store';
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(TDesign);
|
||||
Vue.use(VueClipboard);
|
||||
Vue.prototype.$bus = bus
|
||||
|
||||
Vue.component('t-page-header');
|
||||
|
||||
@@ -41,7 +43,7 @@ new Vue({
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
render: (h) => (
|
||||
<div>
|
||||
{/* 可以通过config-provider提供全局(多语言、全局属性)配置,如
|
||||
{/* 可以通过config-provider提供全局(多语言、全局属性)配置,如
|
||||
<t-config-provider globalConfig={enConfig}> */}
|
||||
<t-config-provider globalConfig={zhConfig}>
|
||||
<App />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="detail-base">
|
||||
|
||||
<t-form :data="formData" @submit="onSubmit"> <!--:rules="rules"-->
|
||||
<!--基本信息 开始-->
|
||||
<t-card title="基本信息">
|
||||
@@ -12,10 +13,21 @@
|
||||
<t-form-item label="防护级别" name="salience">
|
||||
<t-input placeholder="请输入内容" v-model="formData.rule_base.salience" />
|
||||
</t-form-item>
|
||||
<t-form-item label="防护编排方式" name="is_manual_rule">
|
||||
<t-select :style="{ width: '480px' }"
|
||||
v-model="formData.is_manual_rule">
|
||||
<t-option v-for="(item, index) in rule_manual_option" :value="item.value" :label="item.label"
|
||||
:key="index">
|
||||
{{ item.label }}
|
||||
</t-option>
|
||||
</t-select>
|
||||
</t-form-item>
|
||||
</t-card>
|
||||
<!--基本信息 结束-->
|
||||
|
||||
<!--规则编排 开始-->
|
||||
<!--手工编排-->
|
||||
<div v-if="formData.is_manual_rule=='0'">
|
||||
<!--规则编排 开始-->
|
||||
<t-card title="规则编排">
|
||||
<t-button theme="primary" @click="ruleDynAdd('cond')">
|
||||
新建
|
||||
@@ -242,6 +254,19 @@
|
||||
</t-card>
|
||||
<!--符合则执行部分 结束-->
|
||||
|
||||
</div>
|
||||
<!--界面编排 结束-->
|
||||
|
||||
<!--手工编排-->
|
||||
<div v-if="formData.is_manual_rule=='1'">
|
||||
<t-card title="规则编排">
|
||||
<writeRule>
|
||||
|
||||
@edtinput="edtinput"
|
||||
|
||||
></writeRule>
|
||||
</t-card>
|
||||
</div>
|
||||
|
||||
|
||||
<t-form-item style="margin-left: 100px">
|
||||
@@ -253,7 +278,7 @@
|
||||
</t-space>
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
|
||||
<t-button theme="default" variant="base" @click="getinfoClick">测试获取数据</t-button>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
@@ -265,14 +290,27 @@
|
||||
RULE,RULE_RELATION_DETAIL,RULE_DO_ASSIGNMENT,RULE_DO_METHOD,RULE_DO_METHOD_PARM
|
||||
} from '@/service/service-rule';
|
||||
import { copyObj } from '@/utils/usuallytool';
|
||||
import writeRule from "@/components/write-rule/index.vue";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'WafRuleEdit',
|
||||
components: {
|
||||
writeRule
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
op_type :"add",
|
||||
op_rule_no :"",//规则识别号
|
||||
prefix,
|
||||
detail_data: {},
|
||||
rule_manual_option: [{
|
||||
label: '界面编排',
|
||||
value: '0'
|
||||
}, {
|
||||
label: '手工代码编排',
|
||||
value: '1'
|
||||
}, ],
|
||||
rules: {
|
||||
rule_name: [{ required: true, message: '请输入规则名称', type: 'error' }],
|
||||
},
|
||||
@@ -362,9 +400,13 @@
|
||||
console.log('beforeRouteUpdate')
|
||||
},
|
||||
mounted() {
|
||||
let that = this
|
||||
console.log('----mounted----')
|
||||
console.log(RULE)
|
||||
|
||||
this.$bus.$on('codeedit', (e) => {
|
||||
console.log('消息总线 来自子组件e', e)
|
||||
this.formData.rule_content = e
|
||||
})
|
||||
//console.log(this.$route.params.req_uuid);
|
||||
if(this.$route.query.code != undefined){
|
||||
|
||||
@@ -404,6 +446,7 @@
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
getDetail(id) {
|
||||
let that = this
|
||||
this.$request
|
||||
@@ -515,7 +558,14 @@
|
||||
break;
|
||||
}
|
||||
},
|
||||
edtinput(e){
|
||||
console.log('来子组件',e)
|
||||
},
|
||||
getinfoClick(e){
|
||||
console.log(e)
|
||||
|
||||
console.log(this.$refs.changeSql)
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const RULE = {
|
||||
is_manual_rule:"1",
|
||||
rule_content:"zxcv",
|
||||
rule_base: {
|
||||
salience: 10,
|
||||
rule_name: "试试",
|
||||
@@ -7,14 +9,14 @@ export const RULE = {
|
||||
rule_condition: {
|
||||
relation_detail: [{
|
||||
fact_name: "MF",
|
||||
attr: "主机",
|
||||
attr: "HOST",
|
||||
attr_type: "string",
|
||||
attr_judge: "==",
|
||||
attr_val: "值"
|
||||
},
|
||||
{
|
||||
fact_name: "MF",
|
||||
attr: "端口",
|
||||
attr: "URL",
|
||||
attr_type: "int",
|
||||
attr_judge: "==",
|
||||
attr_val: "0"
|
||||
@@ -24,13 +26,13 @@ export const RULE = {
|
||||
},
|
||||
rule_do_assignment: [{
|
||||
fact_name: "MF",
|
||||
attr: "主机",
|
||||
attr: "HOST",
|
||||
attr_type: "string",
|
||||
attr_val: "值"
|
||||
},
|
||||
{
|
||||
fact_name: "MF",
|
||||
attr: "源端口",
|
||||
attr: "PORT",
|
||||
attr_type: "int",
|
||||
attr_val: "0"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import { loadEnv } from 'vite';
|
||||
import { viteMockServe } from 'vite-plugin-mock';
|
||||
import { createVuePlugin } from 'vite-plugin-vue2';
|
||||
import { createSvgPlugin } from 'vite-plugin-vue2-svg';
|
||||
import requireTransform from 'vite-plugin-require-transform';
|
||||
|
||||
import path from 'path';
|
||||
|
||||
@@ -36,6 +37,11 @@ export default ({ mode }) => {
|
||||
localEnabled: true,
|
||||
}),
|
||||
createSvgPlugin(),
|
||||
requireTransform(
|
||||
{
|
||||
fileRegex: /.js$|.vue$/
|
||||
}
|
||||
),
|
||||
],
|
||||
|
||||
build: {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package request
|
||||
|
||||
type WafRuleAddReq struct {
|
||||
RuleJson string
|
||||
RuleJson string
|
||||
IsManualRule int `json:"is_manual_rule"`
|
||||
RuleContent string `json:"rule_content"` //规则内容
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package request
|
||||
|
||||
type WafRuleEditReq struct {
|
||||
CODE string `json:"code"`
|
||||
RuleJson string `json:"rulejson"`
|
||||
CODE string `json:"code"`
|
||||
RuleJson string `json:"rulejson"`
|
||||
IsManualRule int `json:"is_manual_rule"`
|
||||
RuleContent string `json:"rule_content"` //规则内容
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ func IfCompare(condition bool, trueVal, falseVal interface{}) interface{} {
|
||||
}
|
||||
|
||||
type RuleInfo struct {
|
||||
IsManualRule int `json:"is_manual_rule"`
|
||||
RuleContent string `json:"rule_content"` //规则内容
|
||||
RuleBase RuleBase `json:"rule_base"`
|
||||
RuleCondition RuleCondition `json:"rule_condition"`
|
||||
RuleDoAssignment []RuleDoAssignment `json:"rule_do_assignment"`
|
||||
|
||||
@@ -12,5 +12,6 @@ type Rules struct {
|
||||
RuleVersion int `json:"rule_version"` //规则版本号
|
||||
UserCode string `json:"user_code"` //用户编码
|
||||
IsPublicRule int `json:"is_public_rule"` //是否为公共规则
|
||||
IsManualRule int `json:"is_manual_rule"` //是否为手工写规则 1:手工编写 0 :UI界面形式
|
||||
RuleStatus int `json:"rule_status"` //规则是否开启 1,开启 0,关闭不生效 999 删除
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user