mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2025-12-06 14:59:18 +08:00
add:提供中心控制完善部分代码
This commit is contained in:
@@ -42,3 +42,29 @@ func (w *CenterApi) UpdateApi(c *gin.Context) {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *CenterApi) GetDetailApi(c *gin.Context) {
|
||||
var req request.CenterClientDetailReq
|
||||
err := c.ShouldBind(&req)
|
||||
if err == nil {
|
||||
bean := CenterService.GetDetailApi(req)
|
||||
response.OkWithDetailed(bean, "获取成功", c)
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
func (w *CenterApi) GetListApi(c *gin.Context) {
|
||||
var req request.CenterClientSearchReq
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err == nil {
|
||||
beans, total, _ := CenterService.GetListApi(req)
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: beans,
|
||||
Total: total,
|
||||
PageIndex: req.PageIndex,
|
||||
PageSize: req.PageSize,
|
||||
}, "获取成功", c)
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
SET CGO_ENABLED=1
|
||||
SET GOOS=windows
|
||||
SET GOARCH=amd64
|
||||
SET GIN_MODE=release
|
||||
go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20231128 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.0.128 -s -w" -o %cd%/release/SamWaf64.exe main.go
|
||||
@@ -1,16 +0,0 @@
|
||||
SET CGO_ENABLED=1
|
||||
SET GOOS=windows
|
||||
SET GOARCH=amd64
|
||||
SET GIN_MODE=release
|
||||
go build -o %cd%/release/SamWaf64.exe main.go
|
||||
|
||||
SET CGO_ENABLED=1
|
||||
SET GOOS=windows
|
||||
SET GOARCH=386
|
||||
go build -o %cd%/release/SamWaf32.exe main.go
|
||||
|
||||
SET CGO_ENABLED=1
|
||||
SET GOOS=linux
|
||||
SET GOARCH=amd64
|
||||
go build -o %cd%/release/SamWafLinux64 main.go
|
||||
|
||||
17
localwaf/src/apis/center.ts
Normal file
17
localwaf/src/apis/center.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import request from '@/utils/request'
|
||||
//查看控制中心列表
|
||||
export function centerListApi(params) {
|
||||
return request({
|
||||
url: '/center/list',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
//详细控制中心详情
|
||||
export function centerDetailApi(params) {
|
||||
return request({
|
||||
url: '/center/detail',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
@@ -44,6 +44,10 @@
|
||||
<help-circle-icon />
|
||||
</t-button>
|
||||
</t-tooltip>
|
||||
<t-button theme="warning" @click="changeServer" v-if="hasClientServer">
|
||||
<template #icon><add-icon /></template>
|
||||
当前 服务器{{ current_server.client_server_name }}
|
||||
</t-button>
|
||||
<t-dropdown :min-column-width="125" trigger="click">
|
||||
<template #dropdown>
|
||||
<t-dropdown-menu>
|
||||
@@ -166,6 +170,9 @@
|
||||
update_new_ver:"",
|
||||
update_desc:"",
|
||||
current_account:"not login",
|
||||
/**控制中心相关**/
|
||||
hasClientServer:false,
|
||||
current_server:"",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -196,11 +203,28 @@
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.current_account = localStorage.getItem("current_account")
|
||||
// 首次提示,每隔24小时 进行弹窗 ,其余实际不弹窗
|
||||
this.checkVersion("auto")
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
//init
|
||||
init(){
|
||||
//帐号初始化
|
||||
this.current_account = localStorage.getItem("current_account")
|
||||
//管控初始化
|
||||
if(localStorage.getItem("current_server")){
|
||||
this.hasClientServer = true
|
||||
this.current_server = JSON.parse(localStorage.getItem("current_server"))
|
||||
}else{
|
||||
this.hasClientServer = false
|
||||
}
|
||||
|
||||
},
|
||||
//切换服务器
|
||||
changeServer(){
|
||||
this.$router.push('/sys/CenterManager');
|
||||
},
|
||||
toggleSettingPanel() {
|
||||
this.$store.commit('setting/toggleSettingPanel', true);
|
||||
},
|
||||
|
||||
546
localwaf/src/pages/waf/center/index.vue
Normal file
546
localwaf/src/pages/waf/center/index.vue
Normal file
@@ -0,0 +1,546 @@
|
||||
<template>
|
||||
<div>
|
||||
<t-card class="list-card-container">
|
||||
<t-row justify="space-between">
|
||||
<div class="left-operation-container">
|
||||
<t-button @click="handleChangeLocalClear"> 切换本机(不进行远程访问) </t-button>
|
||||
<p v-if="!!selectedRowKeys.length" class="selected-count">已选{{ selectedRowKeys.length }}项</p>
|
||||
</div>
|
||||
<div class="right-operation-container">
|
||||
<t-form ref="form" :data="searchformData" :label-width="80" colon :style="{ marginBottom: '8px' }">
|
||||
|
||||
<t-row>
|
||||
<!-- <span>网站:</span>
|
||||
<t-select v-model="searchformData.host_code" clearable :style="{ width: '150px' }">
|
||||
<t-option v-for="(item, index) in host_dic" :value="index" :label="item" :key="index">
|
||||
{{ item }}
|
||||
</t-option>
|
||||
</t-select>
|
||||
<span>URL:</span>
|
||||
<t-input v-model="searchformData.url" class="search-input" placeholder="请输入" clearable>
|
||||
</t-input>-->
|
||||
<t-button theme="primary" :style="{ marginLeft: '8px' }" @click="getList('all')"> 查询</t-button>
|
||||
</t-row>
|
||||
</t-form>
|
||||
</div>
|
||||
</t-row>
|
||||
<t-alert theme="info" message="SamWaf管控中心" close>
|
||||
<template #operation>
|
||||
<span >在线文档</span>
|
||||
</template>
|
||||
</t-alert>
|
||||
<div class="table-container">
|
||||
<t-table :columns="columns" :data="data" :rowKey="rowKey" :verticalAlign="verticalAlign" :hover="hover"
|
||||
:pagination="pagination" :selected-row-keys="selectedRowKeys" :loading="dataLoading"
|
||||
@page-change="rehandlePageChange" @change="rehandleChange" @select-change="rehandleSelectChange"
|
||||
:headerAffixedTop="true" :headerAffixProps="{ offsetTop: offsetTop, container: getContainer }">
|
||||
|
||||
<template #host_code="{ row }">
|
||||
<span> {{ host_dic[row.host_code] }}</span>
|
||||
</template>
|
||||
|
||||
<template #op="slotProps">
|
||||
<a class="t-button-link" @click="handleClickChangeServer(slotProps)">切换服务器</a>
|
||||
<a class="t-button-link" @click="handleClickDelete(slotProps)">删除</a>
|
||||
</template>
|
||||
</t-table>
|
||||
</div>
|
||||
<div>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</t-card>
|
||||
|
||||
<!-- 新建CC防护弹窗 -->
|
||||
<t-dialog header="新建cc防护" :visible.sync="addFormVisible" :width="680" :footer="false">
|
||||
<div slot="body">
|
||||
<!-- 表单内容 -->
|
||||
<t-form :data="formData" ref="form" :rules="rules" @submit="onSubmit" :labelWidth="100">
|
||||
<t-form-item label="网站" name="host_code">
|
||||
<t-select v-model="formData.host_code" clearable :style="{ width: '480px' }">
|
||||
<t-option v-for="(item, index) in host_dic" :value="index" :label="item"
|
||||
:key="index">
|
||||
{{ item }}
|
||||
</t-option>
|
||||
</t-select>
|
||||
</t-form-item>
|
||||
<t-form-item label="Url" name="url">
|
||||
<t-input :style="{ width: '480px' }" v-model="formData.url" placeholder="请输入CC防护url(可不填)"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="速率" name="rate">
|
||||
<t-input-number :style="{ width: '480px' }" v-model="formData.rate" placeholder="请输入速率"></t-input-number>
|
||||
</t-form-item>
|
||||
<t-form-item label="限制次数" name="limit">
|
||||
<t-input-number :style="{ width: '480px' }" v-model="formData.limit" placeholder="请输入限制"></t-input-number>
|
||||
</t-form-item>
|
||||
<t-form-item label="备注" name="remarks">
|
||||
<t-textarea :style="{ width: '480px' }" v-model="formData.remarks" placeholder="请输入内容" name="remarks">
|
||||
</t-textarea>
|
||||
</t-form-item>
|
||||
<t-form-item style="float: right">
|
||||
<t-button variant="outline" @click="onClickCloseBtn">取消</t-button>
|
||||
<t-button theme="primary" type="submit">确定</t-button>
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</t-dialog>
|
||||
|
||||
<!-- 编辑CC防护弹窗 -->
|
||||
<t-dialog header="编辑CC防护" :visible.sync="editFormVisible" :width="680" :footer="false">
|
||||
<div slot="body">
|
||||
<!-- 表单内容 -->
|
||||
<t-form :data="formEditData" ref="form" :rules="rules" @submit="onSubmitEdit" :labelWidth="100">
|
||||
<t-form-item label="网站" name="host_code">
|
||||
<t-select v-model="formEditData.host_code" clearable :style="{ width: '480px' }">
|
||||
<t-option v-for="(item, index) in host_dic" :value="index" :label="item"
|
||||
:key="index">
|
||||
{{ item }}
|
||||
</t-option>
|
||||
</t-select>
|
||||
</t-form-item>
|
||||
<t-form-item label="速率" name="rate">
|
||||
<t-input-number :style="{ width: '480px' }" v-model="formEditData.rate"
|
||||
placeholder="请输入速率"></t-input-number>
|
||||
</t-form-item>
|
||||
<t-form-item label="限制次数" name="limit">
|
||||
<t-input-number :style="{ width: '480px' }" v-model="formEditData.limit"
|
||||
placeholder="请输入限制"></t-input-number>
|
||||
</t-form-item>
|
||||
<t-form-item label="Url" name="url">
|
||||
<t-input :style="{ width: '480px' }" v-model="formEditData.url" placeholder="请输入CC防护"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="备注" name="remarks">
|
||||
<t-textarea :style="{ width: '480px' }" v-model="formEditData.remarks" placeholder="请输入内容" name="remarks">
|
||||
</t-textarea>
|
||||
</t-form-item>
|
||||
<t-form-item style="float: right">
|
||||
<t-button variant="outline" @click="onClickCloseEditBtn">取消</t-button>
|
||||
<t-button theme="primary" type="submit">确定</t-button>
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</t-dialog>
|
||||
|
||||
<t-dialog header="确认删除当前所选Url?" :body="confirmBody" :visible.sync="confirmVisible" @confirm="onConfirmDelete"
|
||||
:onCancel="onCancel">
|
||||
</t-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import {SearchIcon} from 'tdesign-icons-vue';
|
||||
import Trend from '@/components/trend/index.vue';
|
||||
import {prefix, TOKEN_NAME} from '@/config/global';
|
||||
import {allhost} from '@/apis/host';
|
||||
import {centerListApi} from "../../../apis/center";
|
||||
|
||||
const INITIAL_DATA = {
|
||||
client_server_name: '',
|
||||
client_ip: '',
|
||||
client_port: '',
|
||||
client_new_version: '',
|
||||
client_new_version_desc: '',
|
||||
client_system_type: '',
|
||||
last_visit_time: '',
|
||||
};
|
||||
export default Vue.extend({
|
||||
name: 'ListBase',
|
||||
components: {
|
||||
SearchIcon,
|
||||
Trend,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
addFormVisible: false,
|
||||
editFormVisible: false,
|
||||
guardVisible: false,
|
||||
confirmVisible: false,
|
||||
formData: {
|
||||
...INITIAL_DATA
|
||||
},
|
||||
formEditData: {
|
||||
...INITIAL_DATA
|
||||
},
|
||||
rules: {
|
||||
host_code: [{
|
||||
required: true,
|
||||
message: '请输入网站名称',
|
||||
type: 'error'
|
||||
}],
|
||||
rate: [{
|
||||
required: true,
|
||||
message: '请输入速率',
|
||||
type: 'error'
|
||||
}],
|
||||
limit: [{
|
||||
required: true,
|
||||
message: '请输入访问次数限制',
|
||||
type: 'error'
|
||||
}],
|
||||
},
|
||||
textareaValue: '',
|
||||
prefix,
|
||||
dataLoading: false,
|
||||
data: [], //列表数据信息
|
||||
detail_data: [], //加载详情信息用于编辑
|
||||
selectedRowKeys: [],
|
||||
value: 'first',
|
||||
columns: [
|
||||
{
|
||||
title: '客户端名称',
|
||||
align: 'left',
|
||||
width: 250,
|
||||
ellipsis: true,
|
||||
colKey: 'client_server_name',
|
||||
},
|
||||
{
|
||||
title: '操作系统类型',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'client_system_type',
|
||||
}, {
|
||||
title: 'IP',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'client_ip',
|
||||
}, {
|
||||
title: '端口',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'client_port',
|
||||
},{
|
||||
title: '版本号',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'client_new_version',
|
||||
}, {
|
||||
title: '版本',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'client_new_version_desc',
|
||||
},
|
||||
{
|
||||
title: '最近访问时间',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'last_visit_time',
|
||||
},
|
||||
{
|
||||
title: '添加时间',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
colKey: 'create_time',
|
||||
},
|
||||
|
||||
{
|
||||
align: 'left',
|
||||
width: 200,
|
||||
colKey: 'op',
|
||||
title: '操作',
|
||||
},
|
||||
],
|
||||
rowKey: 'id',
|
||||
tableLayout: 'auto',
|
||||
verticalAlign: 'top',
|
||||
hover: true,
|
||||
rowClassName: (rowKey: string) => `${rowKey}-class`,
|
||||
// 与pagination对齐
|
||||
pagination: {
|
||||
total: 0,
|
||||
current: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
//顶部搜索
|
||||
searchformData: {
|
||||
},
|
||||
//索引区域
|
||||
deleteIdx: -1,
|
||||
guardStatusIdx: -1,
|
||||
//主机字典
|
||||
host_dic: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
confirmBody() {
|
||||
if (this.deleteIdx > -1) {
|
||||
const {
|
||||
url
|
||||
} = this.data?. [this.deleteIdx];
|
||||
return `确认要删除吗?`;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
offsetTop() {
|
||||
return this.$store.state.setting.isUseTabsRouter ? 48 : 0;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getList("")
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 切换本机不进行数据处理
|
||||
*/
|
||||
handleChangeLocalClear(){
|
||||
localStorage.removeItem("current_server");
|
||||
location.reload()
|
||||
},
|
||||
getList(keyword) {
|
||||
let that = this
|
||||
centerListApi({
|
||||
pageSize: that.pagination.pageSize,
|
||||
pageIndex: that.pagination.current
|
||||
})
|
||||
.then((res) => {
|
||||
let resdata = res
|
||||
console.log(resdata)
|
||||
if (resdata.code === 0) {
|
||||
|
||||
this.data = resdata.data.list;
|
||||
this.data_attach = []
|
||||
console.log('getList', this.data)
|
||||
this.pagination = {
|
||||
...this.pagination,
|
||||
total: resdata.data.total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
console.log(e);
|
||||
})
|
||||
.finally(() => {
|
||||
this.dataLoading = false;
|
||||
});
|
||||
this.dataLoading = true;
|
||||
},
|
||||
getContainer() {
|
||||
return document.querySelector('.tdesign-starter-layout');
|
||||
},
|
||||
rehandlePageChange(curr, pageInfo) {
|
||||
console.log('分页变化', curr, pageInfo);
|
||||
this.pagination.current = curr.current
|
||||
if (this.pagination.pageSize != curr.pageSize) {
|
||||
this.pagination.current = 1
|
||||
this.pagination.pageSize = curr.pageSize
|
||||
}
|
||||
this.getList("")
|
||||
},
|
||||
rehandleSelectChange(selectedRowKeys: number[]) {
|
||||
this.selectedRowKeys = selectedRowKeys;
|
||||
},
|
||||
rehandleChange(changeParams, triggerAndData) {
|
||||
console.log('统一Change', changeParams, triggerAndData);
|
||||
},
|
||||
handleClickChangeServer(e){
|
||||
console.log(e)
|
||||
const {
|
||||
id
|
||||
} = e.row
|
||||
console.log(id)
|
||||
localStorage.setItem("current_server",JSON.stringify(e.row))
|
||||
location.reload()
|
||||
},
|
||||
handleClickEdit(e) {
|
||||
console.log(e)
|
||||
const {
|
||||
id
|
||||
} = e.row
|
||||
console.log(id)
|
||||
this.editFormVisible = true
|
||||
this.getDetail(id)
|
||||
},
|
||||
handleAddAntiCC() {
|
||||
//添加CC防护
|
||||
this.addFormVisible = true
|
||||
this.formData = {
|
||||
host_code: '',
|
||||
url: '',
|
||||
remarks: '',
|
||||
rate: 1,
|
||||
limit: 30
|
||||
};
|
||||
},
|
||||
onSubmit({
|
||||
result,
|
||||
firstError
|
||||
}): void {
|
||||
let that = this
|
||||
if (!firstError) {
|
||||
|
||||
let postdata = {
|
||||
...that.formData
|
||||
}
|
||||
wafAntiCCAddApi({
|
||||
...postdata
|
||||
})
|
||||
.then((res) => {
|
||||
let resdata = res
|
||||
console.log(resdata)
|
||||
if (resdata.code === 0) {
|
||||
that.$message.success(resdata.msg);
|
||||
that.addFormVisible = false;
|
||||
that.pagination.current = 1
|
||||
that.getList("")
|
||||
} else {
|
||||
that.$message.warning(resdata.msg);
|
||||
}
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
console.log(e);
|
||||
})
|
||||
.finally(() => {
|
||||
});
|
||||
} else {
|
||||
console.log('Errors: ', result);
|
||||
that.$message.warning(firstError);
|
||||
}
|
||||
},
|
||||
onSubmitEdit({
|
||||
result,
|
||||
firstError
|
||||
}): void {
|
||||
let that = this
|
||||
if (!firstError) {
|
||||
|
||||
let postdata = {
|
||||
...that.formEditData
|
||||
}
|
||||
wafAntiCCEditApi({
|
||||
...postdata
|
||||
})
|
||||
.then((res) => {
|
||||
let resdata = res
|
||||
console.log(resdata)
|
||||
if (resdata.code === 0) {
|
||||
that.$message.success(resdata.msg);
|
||||
that.editFormVisible = false;
|
||||
that.pagination.current = 1
|
||||
that.getList("")
|
||||
} else {
|
||||
that.$message.warning(resdata.msg);
|
||||
}
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
console.log(e);
|
||||
})
|
||||
.finally(() => {
|
||||
});
|
||||
} else {
|
||||
console.log('Errors: ', result);
|
||||
that.$message.warning(firstError);
|
||||
}
|
||||
},
|
||||
onClickCloseBtn(): void {
|
||||
this.formVisible = false;
|
||||
this.formData = {};
|
||||
},
|
||||
onClickCloseEditBtn(): void {
|
||||
this.editFormVisible = false;
|
||||
this.formEditData = {};
|
||||
},
|
||||
handleClickDelete(row) {
|
||||
console.log(row)
|
||||
this.deleteIdx = row.rowIndex;
|
||||
this.confirmVisible = true;
|
||||
},
|
||||
onConfirmDelete() {
|
||||
this.confirmVisible = false;
|
||||
console.log('delete', this.data)
|
||||
console.log('delete', this.data[this.deleteIdx])
|
||||
let {
|
||||
id
|
||||
} = this.data[this.deleteIdx]
|
||||
let that = this
|
||||
wafAntiCCDelApi({
|
||||
id: id
|
||||
})
|
||||
.then((res) => {
|
||||
let resdata = res
|
||||
console.log(resdata)
|
||||
if (resdata.code === 0) {
|
||||
|
||||
that.pagination.current = 1
|
||||
that.getList("")
|
||||
that.$message.success(resdata.msg);
|
||||
} else {
|
||||
that.$message.warning(resdata.msg);
|
||||
}
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
console.log(e);
|
||||
})
|
||||
.finally(() => {
|
||||
});
|
||||
|
||||
|
||||
this.resetIdx();
|
||||
},
|
||||
onCancel() {
|
||||
this.resetIdx();
|
||||
},
|
||||
resetIdx() {
|
||||
this.deleteIdx = -1;
|
||||
},
|
||||
getDetail(id) {
|
||||
let that = this
|
||||
wafAntiCCDetailApi({
|
||||
id: id
|
||||
})
|
||||
.then((res) => {
|
||||
let resdata = res
|
||||
console.log(resdata)
|
||||
if (resdata.code === 0) {
|
||||
that.detail_data = resdata.data;
|
||||
that.formEditData = {
|
||||
...that.detail_data
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
console.log(e);
|
||||
})
|
||||
.finally(() => {
|
||||
});
|
||||
},
|
||||
//跳转界面
|
||||
handleJumpOnlineUrl() {
|
||||
window.open(this.samwafglobalconfig.getOnlineUrl() + "/guide/CC.html");
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import '@/style/variables';
|
||||
|
||||
.payment-col {
|
||||
display: flex;
|
||||
|
||||
.trend-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.left-operation-container {
|
||||
padding: 0 0 6px 0;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.selected-count {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
color: var(--td-text-color-secondary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.t-button + .t-button {
|
||||
margin-left: @spacer;
|
||||
}
|
||||
</style>
|
||||
@@ -168,6 +168,11 @@ export default [
|
||||
name: 'OneKeyMod',
|
||||
component: () => import('@/pages/waf/onekeymod/index.vue'),
|
||||
meta: { title: '一键修改' },
|
||||
},{
|
||||
path: 'CenterManager',
|
||||
name: 'CenterManager',
|
||||
component: () => import('@/pages/waf/center/index.vue'),
|
||||
meta: { title: '管控中心' },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import axios from 'axios';
|
||||
import proxy from '../config/host';
|
||||
import router from '../router/index';
|
||||
import {AesDecrypt,AesEncrypt,isObject} from './usuallytool'
|
||||
import {AesDecrypt,AesEncrypt,isObject,isInList} from './usuallytool'
|
||||
|
||||
const env = import.meta.env.MODE || 'development';
|
||||
|
||||
const API_HOST = env === 'mock' ? '/' : proxy[env].API; // 如果是mock模式 就不配置host 会走本地Mock拦截
|
||||
|
||||
const noVisitClientList = ["/center/list", "logout", "public/login"];
|
||||
const CODE = {
|
||||
LOGIN_TIMEOUT: 1000,
|
||||
REQUEST_SUCCESS: 0,
|
||||
@@ -50,6 +51,16 @@ instance.interceptors.request.use(
|
||||
config.headers['X-Token'] = token
|
||||
//config.headers.Authorization = + token
|
||||
}
|
||||
//如果有远控机器
|
||||
let remoteBean =localStorage.getItem("current_server")? localStorage.getItem("current_server"):"" //此处换成自己获取回来的token,通常存在在cookie或者store里面
|
||||
|
||||
if (remoteBean && !isInList(config.url,noVisitClientList) ) {
|
||||
console.log(config)
|
||||
remoteBean = JSON.parse(localStorage.getItem("current_server"))
|
||||
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
|
||||
config.headers['Remote-Waf-User-Id'] = remoteBean.client_tenant_id+"@"+remoteBean.client_user_code
|
||||
//config.headers.Authorization = + token
|
||||
}
|
||||
/*if(config.headers['Content-Type'] !=undefined && config.headers['Content-Type']=="application/json" ){
|
||||
data = JSON.stringify(config.data)
|
||||
|
||||
@@ -76,10 +87,20 @@ instance.interceptors.response.use(
|
||||
|
||||
//console.log("再加密后",AesEncrypt(tmpSrcContent))
|
||||
return data;
|
||||
}else if(data.code === CODE.AUTH_FAILURE){
|
||||
}else {
|
||||
//如果有远控机器
|
||||
let remoteBean =localStorage.getItem("current_server")? localStorage.getItem("current_server"):"" //此处换成自己获取回来的token,通常存在在cookie或者store里面
|
||||
|
||||
if(!remoteBean && data.code === CODE.AUTH_FAILURE){
|
||||
localStorage.clear(); //删除用户信息
|
||||
console.log("鉴权失败")
|
||||
router.replace({path: '/login'})
|
||||
}else if(remoteBean && data.code === CODE.AUTH_FAILURE){
|
||||
remoteBean = JSON.parse(localStorage.getItem("current_server"))
|
||||
data.code = -1
|
||||
data.msg = remoteBean.client_server_name + " 远端鉴权失败"
|
||||
console.log("远端鉴权失败")
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -61,3 +61,12 @@ export const isObject = (obj, isEffective = false) => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* value 是否在list中
|
||||
* @param value
|
||||
* @param list
|
||||
*/
|
||||
export const isInList=(value=string, list=Array)=> {
|
||||
return list.includes(value);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,57 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"SamWaf/service/waf_service"
|
||||
"SamWaf/utils/zlog"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
centerService = waf_service.CenterServiceApp
|
||||
)
|
||||
|
||||
// 中心管控 鉴权中间件
|
||||
func CenterApi() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 检查请求的URL是否包含需要代理的路径前缀
|
||||
if strings.HasPrefix(c.Request.URL.Path, "/samwaf/wafhost/host/allhost") && c.RemoteIP() == "127.0.0.1" {
|
||||
zlog.Debug("当前访问人IP" + c.RemoteIP())
|
||||
//1.读取标识,然后提取通信KEY
|
||||
//2.校验别是自己操作自己 可能会循环访问
|
||||
c.Request.Header.Set("X-Token", "f0661bb70075c66a4375ead94a204c67")
|
||||
for key, values := range c.Request.Header {
|
||||
fmt.Printf("Header key: %s\n", key)
|
||||
for _, value := range values {
|
||||
fmt.Printf(" Value: %s\n", value)
|
||||
}
|
||||
}
|
||||
|
||||
remoteWafUserId := c.Request.Header.Get("Remote-Waf-User-Id") //tencent@usercode
|
||||
if remoteWafUserId != "" {
|
||||
//拆分数据 tencent@usercode
|
||||
split := strings.Split(remoteWafUserId, "@")
|
||||
centerBean := centerService.GetDetailByTencentUserCode(split[0], split[1])
|
||||
if centerBean.Id != "" && c.RemoteIP() != centerBean.ClientIP {
|
||||
|
||||
c.Request.Header.Set("X-Token", centerBean.ClientToken) //TODO 调试时候用 到正式的时候 这个用下面的
|
||||
c.Request.Header.Set("OPEN-X-Token", centerBean.ClientToken)
|
||||
// 构建远程服务的URL
|
||||
remoteURL := "http://82.156.235.106:26666" + c.Request.URL.Path
|
||||
remoteURL := centerBean.ClientIP + ":" + centerBean.ClientPort + c.Request.URL.Path
|
||||
if c.Request.URL.RawQuery != "" {
|
||||
remoteURL = remoteURL + "?" + c.Request.URL.RawQuery
|
||||
}
|
||||
if centerBean.ClientSsl == "false" {
|
||||
remoteURL = "http://" + remoteURL
|
||||
} else {
|
||||
remoteURL = "https://" + remoteURL
|
||||
}
|
||||
// 发起代理请求
|
||||
proxyRequest(c, remoteURL)
|
||||
// 停止后续的处理
|
||||
c.Abort()
|
||||
return
|
||||
//1.读取标识,然后提取通信KEY
|
||||
//2.校验别是自己操作自己 可能会循环访问
|
||||
}
|
||||
}
|
||||
// 如果不需要代理,继续处理请求
|
||||
c.Next()
|
||||
|
||||
@@ -15,6 +15,7 @@ type Center struct {
|
||||
ClientUserCode string `json:"client_user_code"` // 客户端-用户码
|
||||
ClientTenantId string `json:"client_tenant_id"` // 客户端-租户ID
|
||||
ClientToken string `json:"client_token"` // 客户端-访问密钥
|
||||
ClientSsl string `json:"client_ssl"` // 客户端-是否https
|
||||
ClientIP string `json:"client_ip"` //客户端 ip
|
||||
ClientPort string `json:"client_port"` //客户端 port
|
||||
ClientNewVersion string `json:"client_new_version"` //客户端 版本号
|
||||
|
||||
@@ -7,6 +7,7 @@ type CenterClientUpdateReq struct {
|
||||
ClientUserCode string `json:"client_user_code"` // 客户端-用户码
|
||||
ClientTenantId string `json:"client_tenant_id"` // 客户端-租户ID
|
||||
ClientToken string `json:"client_token"` // 客户端-访问密钥
|
||||
ClientSsl string `json:"client_ssl"` // 客户端-是否https
|
||||
ClientIP string `json:"client_ip"` //客户端 ip
|
||||
ClientPort string `json:"client_port"` //客户端 port
|
||||
ClientNewVersion string `json:"client_new_version"` //客户端 版本号
|
||||
|
||||
16
router/center_public_router.go
Normal file
16
router/center_public_router.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"SamWaf/api"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// 不鉴权
|
||||
type CenterPublicRouter struct {
|
||||
}
|
||||
|
||||
func (receiver *CenterPublicRouter) InitCenterRouter(group *gin.RouterGroup) {
|
||||
api := api.APIGroupAPP.CenterApi
|
||||
router := group.Group("")
|
||||
router.POST("/samwaf/center/update", api.UpdateApi)
|
||||
}
|
||||
@@ -11,5 +11,6 @@ type CenterRouter struct {
|
||||
func (receiver *CenterRouter) InitCenterRouter(group *gin.RouterGroup) {
|
||||
api := api.APIGroupAPP.CenterApi
|
||||
router := group.Group("")
|
||||
router.POST("/samwaf/center/update", api.UpdateApi)
|
||||
router.POST("/samwaf/center/list", api.GetListApi)
|
||||
router.POST("/samwaf/center/detail", api.GetDetailApi)
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@ type ApiGroup struct {
|
||||
SystemConfigRouter
|
||||
WafCommonRouter
|
||||
OneKeyModRouter
|
||||
CenterRouter
|
||||
}
|
||||
type PublicApiGroup struct {
|
||||
LoginRouter
|
||||
CenterRouter
|
||||
CenterPublicRouter
|
||||
}
|
||||
|
||||
var ApiGroupApp = new(ApiGroup)
|
||||
|
||||
@@ -27,6 +27,7 @@ func (receiver *CenterService) AddApi(req request.CenterClientUpdateReq) error {
|
||||
ClientUserCode: req.ClientUserCode,
|
||||
ClientTenantId: req.ClientTenantId,
|
||||
ClientToken: req.ClientToken,
|
||||
ClientSsl: req.ClientSsl,
|
||||
ClientIP: req.ClientIP,
|
||||
ClientPort: req.ClientPort,
|
||||
ClientNewVersion: req.ClientNewVersion,
|
||||
@@ -49,6 +50,7 @@ func (receiver *CenterService) ModifyApi(req request.CenterClientUpdateReq) erro
|
||||
req.ClientUserCode, req.ClientTenantId).Find(&bean)
|
||||
beanMap := map[string]interface{}{
|
||||
"ClientServerName": req.ClientServerName,
|
||||
"ClientSsl": req.ClientSsl,
|
||||
"ClientToken": req.ClientToken,
|
||||
"ClientIP": req.ClientIP,
|
||||
"ClientPort": req.ClientPort,
|
||||
@@ -72,6 +74,12 @@ func (receiver *CenterService) GetDetailByIdApi(id string) model.Center {
|
||||
global.GWAF_LOCAL_DB.Where("id=?", id).Find(&bean)
|
||||
return bean
|
||||
}
|
||||
func (receiver *CenterService) GetDetailByTencentUserCode(clientTenantId, clientUserCode string) model.Center {
|
||||
var bean model.Center
|
||||
global.GWAF_LOCAL_DB.Where("client_tenant_id = ? and client_user_code= ?", clientTenantId, clientUserCode).Find(&bean)
|
||||
return bean
|
||||
}
|
||||
|
||||
func (receiver *CenterService) GetListApi(req request.CenterClientSearchReq) ([]model.Center, int64, error) {
|
||||
var list []model.Center
|
||||
var total int64 = 0
|
||||
|
||||
4
vue/dist/index.html
vendored
4
vue/dist/index.html
vendored
@@ -6,8 +6,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>SamWaf网站防火墙系统(Web Application Firewall)</title>
|
||||
<script type="module" crossorigin src="./assets/index.2a784df4.js"></script>
|
||||
<link rel="stylesheet" href="./assets/style.559a5c8f.css">
|
||||
<script type="module" crossorigin src="./assets/index.0c85779c.js"></script>
|
||||
<link rel="stylesheet" href="./assets/style.7029ad6e.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -28,7 +28,7 @@ func (web *WafWebManager) initRouter(r *gin.Engine) {
|
||||
router.PublicApiGroupApp.InitCenterRouter(PublicRouterGroup) //注册中心接收接口
|
||||
|
||||
RouterGroup := r.Group("")
|
||||
RouterGroup.Use(middleware.Auth(), middleware.SecApi(), middleware.CenterApi()) //TODO 中心管控 特定
|
||||
RouterGroup.Use(middleware.Auth(), middleware.CenterApi(), middleware.SecApi()) //TODO 中心管控 特定
|
||||
{
|
||||
router.ApiGroupApp.InitHostRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitLogRouter(RouterGroup)
|
||||
@@ -50,6 +50,7 @@ func (web *WafWebManager) initRouter(r *gin.Engine) {
|
||||
router.ApiGroupApp.InitSystemConfigRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafCommonRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitOneKeyModRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitCenterRouter(RouterGroup)
|
||||
|
||||
}
|
||||
//TODO 中心管控 特定
|
||||
@@ -66,7 +67,7 @@ func (web *WafWebManager) cors() gin.HandlerFunc {
|
||||
// 将该域添加到allow-origin中
|
||||
c.Header("Access-Control-Allow-Origin", origin) //
|
||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
|
||||
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization,X-Token")
|
||||
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization,X-Token,Remote-Waf-User-Id,OPEN-X-Token")
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
|
||||
//允许客户端传递校验信息比如 cookie
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
@@ -37,6 +37,7 @@ func TaskClientToCenter() {
|
||||
ClientUserCode: global.GWAF_USER_CODE,
|
||||
ClientTenantId: global.GWAF_TENANT_ID,
|
||||
ClientToken: tokenInfo.AccessToken,
|
||||
ClientSsl: "false",
|
||||
ClientPort: strconv.Itoa(global.GWAF_LOCAL_SERVER_PORT),
|
||||
ClientNewVersion: global.GWAF_RELEASE_VERSION,
|
||||
ClientNewVersionDesc: global.GWAF_RELEASE_VERSION_NAME,
|
||||
|
||||
Reference in New Issue
Block a user