实现IP名单管理

This commit is contained in:
刘祥超
2020-11-07 19:40:18 +08:00
parent f3e3bffa2b
commit edd0c27262
19 changed files with 692 additions and 8 deletions
@@ -0,0 +1,150 @@
Vue.component("datetime-input", {
props: ["v-name", "v-timestamp"],
data: function () {
let timestamp = this.vTimestamp
if (timestamp != null) {
timestamp = parseInt(timestamp)
if (isNaN(timestamp)) {
timestamp = 0
}
} else {
timestamp = 0
}
let day = ""
let hour = ""
let minute = ""
let second = ""
if (timestamp > 0) {
let date = new Date()
date.setTime(timestamp * 1000)
let year = date.getFullYear().toString()
let month = this.leadingZero((date.getMonth() + 1).toString(), 2)
day = year + "-" + month + "-" + this.leadingZero(date.getDate().toString(), 2)
hour = this.leadingZero(date.getHours().toString(), 2)
minute = this.leadingZero(date.getMinutes().toString(), 2)
second = this.leadingZero(date.getSeconds().toString(), 2)
}
return {
timestamp: timestamp,
day: day,
hour: hour,
minute: minute,
second: second,
hasDayError: false,
hasHourError: false,
hasMinuteError: false,
hasSecondError: false
}
},
methods: {
change: function () {
let date = new Date()
// day
if (!/^\d{4}-\d{1,2}-\d{1,2}$/.test(this.day)) {
this.hasDayError = true
return
}
let pieces = this.day.split("-")
let year = parseInt(pieces[0])
date.setFullYear(year)
let month = parseInt(pieces[1])
if (month < 1 || month > 12) {
this.hasDayError = true
return
}
date.setMonth(month - 1)
let day = parseInt(pieces[2])
if (day < 1 || day > 32) {
this.hasDayError = true
return
}
date.setDate(day)
this.hasDayError = false
// hour
if (!/^\d+$/.test(this.hour)) {
this.hasHourError = true
return
}
let hour = parseInt(this.hour)
if (isNaN(hour)) {
this.hasHourError = true
return
}
if (hour < 0 || hour >= 24) {
this.hasHourError = true
return
}
this.hasHourError = false
date.setHours(hour)
// minute
if (!/^\d+$/.test(this.minute)) {
this.hasMinuteError = true
return
}
let minute = parseInt(this.minute)
if (isNaN(minute)) {
this.hasMinuteError = true
return
}
if (minute < 0 || minute >= 60) {
this.hasMinuteError = true
return
}
this.hasMinuteError = false
date.setMinutes(minute)
// second
if (!/^\d+$/.test(this.second)) {
this.hasSecondError = true
return
}
let second = parseInt(this.second)
if (isNaN(second)) {
this.hasSecondError = true
return
}
if (second < 0 || second >= 60) {
this.hasSecondError = true
return
}
this.hasSecondError = false
date.setSeconds(second)
this.timestamp = Math.ceil(date.getTime() / 1000)
},
leadingZero: function (s, l) {
if (l <= s.length) {
return s
}
for (let i = 0; i < l - s.length; i++) {
s = "0" + s
}
return s
}
},
template: `<div>
<input type="hidden" :name="vName" :value="timestamp"/>
<div class="ui fields inline" style="padding: 0; margin:0">
<div class="ui field" :class="{error: hasDayError}">
<input type="text" v-model="day" placeholder="YYYY-mm-dd" style="width:8em" maxlength="10" @input="change"/>
</div>
<div class="ui field" :class="{error: hasHourError}"><input type="text" v-model="hour" maxlength="2" style="width:4em" placeholder="时" @input="change"/></div>
<div class="ui field">:</div>
<div class="ui field" :class="{error: hasMinuteError}"><input type="text" v-model="minute" maxlength="2" style="width:4em" placeholder="分" @input="change"/></div>
<div class="ui field">:</div>
<div class="ui field" :class="{error: hasSecondError}"><input type="text" v-model="second" maxlength="2" style="width:4em" placeholder="秒" @input="change"/></div>
</div>
</div>`
})
@@ -35,7 +35,7 @@ Vue.component("time-duration-box", {
this.$emit("change", this.duration)
}
},
template: `<div class="ui fields inline">
template: `<div class="ui fields inline" style="padding-bottom: 0; margin-bottom: 0">
<input type="hidden" :name="vName" :value="JSON.stringify(duration)"/>
<div class="ui field">
<input type="text" v-model="countString" maxlength="11" size="11"/>
@@ -1,5 +1,10 @@
<second-menu style="margin-top:-1em">
<menu-item :href="'/servers/components/waf/ipadmin?firewallPolicyId=' + firewallPolicyId" :active="subMenuItem == 'region'">国家/地区封禁</menu-item>
<menu-item :href="'/servers/components/waf/ipadmin/provinces?firewallPolicyId=' + firewallPolicyId" :active="subMenuItem == 'province'">省份封禁</menu-item>
<menu-item :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + firewallPolicyId" :active="subMenuItem == 'list'">IP名单</menu-item>
<span class="item">|</span>
<menu-item :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + firewallPolicyId + '&type=white'" :active="subMenuItem == 'white'">白名单</menu-item>
<a href="" class="item" @click.prevent="createIP('white')"><span style="font-size: 0.9em">[添加IP]</span></a>
<span class="item">|</span>
<menu-item :href="'/servers/components/waf/ipadmin/lists?firewallPolicyId=' + firewallPolicyId + '&type=black'" :active="subMenuItem == 'black'">黑名单</menu-item>
<a href="" class="item" @click.prevent="createIP('black')"><span style="font-size: 0.9em">[添加IP]</span></a>
</second-menu>
@@ -0,0 +1,41 @@
{$layout "layout_popup"}
<h3 v-if="type == 'white'">添加IP到白名单</h3>
<h3 v-if="type == 'black'">添加IP到黑名单</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="listId" :value="listId"/>
<csrf-token></csrf-token>
<table class="ui table definition selectable">
<tr>
<td class="title">开始IP *</td>
<td>
<input type="text" name="ipFrom" maxlength="64" placeholder="x.x.x.x" ref="focus"/>
</td>
</tr>
<tr>
<td>结束IP</td>
<td>
<input type="text" name="ipTo" maxlength="64" placeholder="x.x.x.x"/>
<p class="comment">表示IP段的时候需要填写此项。</p>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>过期时间</td>
<td>
<datetime-input :v-name="'expiredAt'"></datetime-input>
<p class="comment">在加入名单某一段时间后会失效,留空表示永久有效。</p>
</td>
</tr>
<tr>
<td>备注</td>
<td><input type="text" name="reason" maxlength="100"/></td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>
@@ -0,0 +1,3 @@
Tea.context(function () {
this.success = NotifyPopup
})
@@ -36,4 +36,17 @@ Tea.context(function () {
this.success = function () {
teaweb.successToast("保存成功")
}
/**
* 添加IP名单菜单
*/
this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em",
callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
}
})
}
})
@@ -4,4 +4,34 @@
<div class="right-box">
{$template "../waf_menu"}
{$template "menu"}
<p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
<table class="ui table selectable" v-if="items.length > 0">
<thead>
<tr>
<th>IP</th>
<th>过期时间</th>
<th>备注</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="item in items">
<td>{{item.ipFrom}}<span v-if="item.ipTo.length > 0"> - {{item.ipTo}}</span></td>
<td>
<span v-if="item.expiredTime.length > 0">{{item.expiredTime}}</span>
<span v-else class="disabled">不过期</span>
</td>
<td>
<span v-if="item.reason.length > 0">{{item.reason}}</span>
<span v-else class="disabled">-</span>
</td>
<td>
<a href="" @click.prevent="updateItem(item.id)">修改</a> &nbsp;
<a href="" @click.prevent="deleteItem(item.id)">删除</a>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>
</div>
@@ -0,0 +1,35 @@
Tea.context(function () {
this.updateItem = function (itemId) {
teaweb.popup(Tea.url(".updateIPPopup", {itemId: itemId}), {
height: "23em",
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
}
})
}
this.deleteItem = function (itemId) {
let that = this
teaweb.confirm("确定要删除这个IP吗?", function () {
that.$post(".deleteIP")
.params({
"itemId": itemId
})
.refresh()
})
}
/**
* 添加IP名单菜单
*/
this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em",
callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
}
})
}
})
@@ -22,7 +22,7 @@
<td>
<more-options-indicator>选择省份/自治区</more-options-indicator>
<div class="province-list" v-show="moreOptionsVisible">
<div class="province-list" v-show="moreOptionsVisible" style="margin-top:0.5em">
<div class="item" v-for="province in provinces">
<div class="ui checkbox" @click.prevent="selectProvince(province)">
<input type="checkbox" v-model="province.isChecked"/>
@@ -20,4 +20,16 @@ Tea.context(function () {
this.success = function () {
teaweb.successToast("保存成功")
}
/**
* 添加IP名单菜单
*/
this.createIP = function (type) {
teaweb.popup("/servers/components/waf/ipadmin/createIPPopup?firewallPolicyId=" + this.firewallPolicyId + '&type=' + type, {
height: "23em",
callback: function () {
window.location = "/servers/components/waf/ipadmin/lists?firewallPolicyId=" + this.firewallPolicyId + "&type=" + type
}
})
}
})
@@ -0,0 +1,40 @@
{$layout "layout_popup"}
<h3>修改IP</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="itemId" :value="item.id"/>
<csrf-token></csrf-token>
<table class="ui table definition selectable">
<tr>
<td class="title">开始IP *</td>
<td>
<input type="text" name="ipFrom" maxlength="64" placeholder="x.x.x.x" ref="focus" v-model="item.ipFrom"/>
</td>
</tr>
<tr>
<td>结束IP</td>
<td>
<input type="text" name="ipTo" maxlength="64" placeholder="x.x.x.x" v-model="item.ipTo"/>
<p class="comment">表示IP段的时候需要填写此项。</p>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>过期时间</td>
<td>
<datetime-input :v-name="'expiredAt'" :v-timestamp="item.expiredAt"></datetime-input>
<p class="comment">在加入名单某一段时间后会失效,留空表示永久有效。</p>
</td>
</tr>
<tr>
<td>备注</td>
<td><input type="text" name="reason" maxlength="100" v-model="item.reason"/></td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>
@@ -0,0 +1,3 @@
Tea.context(function () {
this.success = NotifyPopup
})