自动检查管理员弱密码并提醒

This commit is contained in:
GoEdgeLab
2023-04-04 17:26:28 +08:00
parent 09a0846fb6
commit 5daa0d6108
9 changed files with 87 additions and 34 deletions

View File

@@ -45,6 +45,7 @@ func (this *AdminAction) RunGet(params struct {
"isOn": admin.IsOn, "isOn": admin.IsOn,
"isSuper": admin.IsSuper, "isSuper": admin.IsSuper,
"canLogin": admin.CanLogin, "canLogin": admin.CanLogin,
"hasWeakPassword": admin.HasWeakPassword,
"countAccessKeys": countAccessKeys, "countAccessKeys": countAccessKeys,
} }

View File

@@ -15,34 +15,46 @@ func (this *IndexAction) Init() {
this.Nav("", "", "") this.Nav("", "", "")
} }
func (this *IndexAction) RunGet(params struct{}) { func (this *IndexAction) RunGet(params struct {
countResp, err := this.RPC().AdminRPC().CountAllEnabledAdmins(this.AdminContext(), &pb.CountAllEnabledAdminsRequest{}) Keyword string
if err != nil { HasWeakPassword bool
this.ErrorPage(err) }) {
return this.Data["keyword"] = params.Keyword
} this.Data["hasWeakPassword"] = params.HasWeakPassword
page := this.NewPage(countResp.Count)
this.Data["page"] = page.AsHTML()
adminsResp, err := this.RPC().AdminRPC().ListEnabledAdmins(this.AdminContext(), &pb.ListEnabledAdminsRequest{ countResp, err := this.RPC().AdminRPC().CountAllEnabledAdmins(this.AdminContext(), &pb.CountAllEnabledAdminsRequest{
Offset: page.Offset, Keyword: params.Keyword,
Size: page.Size, HasWeakPassword: params.HasWeakPassword,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
adminMaps := []maps.Map{} var page = this.NewPage(countResp.Count)
this.Data["page"] = page.AsHTML()
adminsResp, err := this.RPC().AdminRPC().ListEnabledAdmins(this.AdminContext(), &pb.ListEnabledAdminsRequest{
Keyword: params.Keyword,
HasWeakPassword: params.HasWeakPassword,
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
var adminMaps = []maps.Map{}
for _, admin := range adminsResp.Admins { for _, admin := range adminsResp.Admins {
adminMaps = append(adminMaps, maps.Map{ adminMaps = append(adminMaps, maps.Map{
"id": admin.Id, "id": admin.Id,
"isOn": admin.IsOn, "isOn": admin.IsOn,
"isSuper": admin.IsSuper, "isSuper": admin.IsSuper,
"username": admin.Username, "username": admin.Username,
"fullname": admin.Fullname, "fullname": admin.Fullname,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", admin.CreatedAt), "createdTime": timeutil.FormatTime("Y-m-d H:i:s", admin.CreatedAt),
"otpLoginIsOn": admin.OtpLogin != nil && admin.OtpLogin.IsOn, "otpLoginIsOn": admin.OtpLogin != nil && admin.OtpLogin.IsOn,
"canLogin": admin.CanLogin, "canLogin": admin.CanLogin,
"hasWeakPassword": admin.HasWeakPassword,
}) })
} }
this.Data["admins"] = adminMaps this.Data["admins"] = adminMaps

View File

@@ -276,5 +276,13 @@ func (this *IndexAction) RunPost(params struct{}) {
} }
} }
// 弱密码提示
countWeakAdminsResp, err := this.RPC().AdminRPC().CountAllEnabledAdmins(this.AdminContext(), &pb.CountAllEnabledAdminsRequest{HasWeakPassword: true})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["countWeakAdmins"] = countWeakAdminsResp.Count
this.Success() this.Success()
} }

View File

@@ -33,17 +33,17 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>是否允许登录</td> <td>允许登录</td>
<td> <td>
<checkbox name="canLogin" value="1"></checkbox> <checkbox name="canLogin" value="1"></checkbox>
<p class="comment">选中后才可以登录当前的管理平台。</p> <p class="comment">选中后,当前管理员才可以登录当前的管理平台。</p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>是否为超级管理员</td> <td>超级管理员</td>
<td> <td>
<checkbox name="isSuper" v-model="isSuper"></checkbox> <checkbox name="isSuper" v-model="isSuper"></checkbox>
<p class="comment">超级管理员自动拥有所有的管理权限。</p> <p class="comment">选中后,表示当前管理员为超级管理员;超级管理员自动拥有所有的管理权限。</p>
</td> </td>
</tr> </tr>
<tr v-show="!isSuper"> <tr v-show="!isSuper">

View File

@@ -1,7 +1,30 @@
{$layout} {$layout}
{$template "menu"} {$template "menu"}
<table class="ui table selectable"> <div class="margin"></div>
<form class="ui form" method="get" action="/admins" v-show="!hasWeakPassword">
<div class="ui fields inline">
<div class="ui field">
<input type="text" name="keyword" placeholder="用户名、全名 ..." v-model="keyword"/>
</div>
<div class="ui field">
<button class="ui button" type="submit">搜索</button>
&nbsp;
<a href="/admins" v-if="keyword.length > 0">[清除条件]</a>
</div>
</div>
</form>
<div v-if="admins.length == 0">
<div class="margin"></div>
<p class="comment">暂时还没有<span v-if="keyword.length > 0">跟关键词匹配</span>管理员。</p>
</div>
<div v-if="hasWeakPassword">
<span class="ui label small basic blue">当前正在筛选弱密码管理员 <a href="/admins"><i class="icon remove small"></i></a></span>
</div>
<table class="ui table selectable" v-show="admins.length > 0">
<thead> <thead>
<tr> <tr>
<th>用户名</th> <th>用户名</th>
@@ -13,12 +36,13 @@
</tr> </tr>
</thead> </thead>
<tr v-for="admin in admins"> <tr v-for="admin in admins">
<td :class="{disabled:!admin.isOn}"><a :href="'/admins/admin?adminId=' + admin.id">{{admin.username}}</a> <td :class="{disabled:!admin.isOn}"><a :href="'/admins/admin?adminId=' + admin.id"><keyword :v-word="keyword">{{admin.username}}</keyword></a>
<div v-if="admin.isSuper" style="margin-top: 0.5em"> <div v-if="admin.isSuper || admin.hasWeakPassword" style="margin-top: 0.5em">
<tiny-basic-label class="olive">超级管理员</tiny-basic-label> <tiny-basic-label class="olive" v-if="admin.isSuper">超级管理员</tiny-basic-label>
<a :href="'/admins/update?adminId=' + admin.id" v-if="admin.hasWeakPassword"><tiny-basic-label class="red" title="当前管理员已设置密码为弱密码,有极大的安全风险,请及时修改">弱密码</tiny-basic-label></a>
</div> </div>
</td> </td>
<td :class="{disabled:!admin.isOn}">{{admin.fullname}}</td> <td :class="{disabled:!admin.isOn}"><keyword :v-word="keyword">{{admin.fullname}}</keyword></td>
<td> <td>
<span v-if="admin.canLogin" class="green">Y</span> <span v-if="admin.canLogin" class="green">Y</span>
<span v-else class="disabled">N</span> <span v-else class="disabled">N</span>

View File

@@ -1,7 +1,7 @@
Tea.context(function () { Tea.context(function () {
this.createAdmin = function () { this.createAdmin = function () {
teaweb.popup("/admins/createPopup", { teaweb.popup("/admins/createPopup", {
height: "22em", height: "30em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {
teaweb.reload() teaweb.reload()

View File

@@ -33,17 +33,17 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td>是否允许登录</td> <td>允许登录</td>
<td> <td>
<checkbox name="canLogin" value="1" v-model="admin.canLogin"></checkbox> <checkbox name="canLogin" value="1" v-model="admin.canLogin"></checkbox>
<p class="comment">选中后才可以登录当前的管理平台。</p> <p class="comment">选中后,当前管理员才可以登录当前的管理平台。</p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>是否为超级管理员</td> <td>超级管理员</td>
<td> <td>
<checkbox name="isSuper" v-model="admin.isSuper"></checkbox> <checkbox name="isSuper" v-model="admin.isSuper"></checkbox>
<p class="comment">超级管理员自动拥有所有的管理权限。</p> <p class="comment">选中后,表示当前管理员为超级管理员;超级管理员自动拥有所有的管理权限。</p>
</td> </td>
</tr> </tr>
<tr v-show="!admin.isSuper"> <tr v-show="!admin.isSuper">

View File

@@ -50,6 +50,13 @@
<a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a> <a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a>
</div> </div>
<!-- 弱密码提示 -->
<div class="ui icon message error" v-if="countWeakAdmins > 0">
<i class="icon warning circle"></i>
<a href="/admins?hasWeakPassword=1">安全提醒:有 {{countWeakAdmins}} 个管理员登录账号正在使用弱密码,请及时修改密码,避免产生安全风险。</a>
<a href="" title="关闭" @click.prevent="closeMessage"><i class="ui icon remove small"></i></a>
</div>
<!-- 统计图表 --> <!-- 统计图表 -->
<columns-grid v-if="!isLoading"> <columns-grid v-if="!isLoading">
<div class="ui column"> <div class="ui column">

View File

@@ -4,6 +4,7 @@ Tea.context(function () {
this.metricCharts = [] this.metricCharts = []
this.dashboard = {} this.dashboard = {}
this.localLowerVersionAPINode = null this.localLowerVersionAPINode = null
this.countWeakAdmins = 0
this.$delay(function () { this.$delay(function () {
this.$post("$") this.$post("$")