[系统用户]实现基础的权限校验

This commit is contained in:
GoEdgeLab
2020-12-02 23:47:50 +08:00
parent 02f6638963
commit 47335d2894
16 changed files with 191 additions and 53 deletions

View File

@@ -1,6 +1,11 @@
package configloaders
import "github.com/iwind/TeaGo/maps"
import (
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
"github.com/iwind/TeaGo/maps"
)
type AdminModuleCode = string
@@ -13,60 +18,115 @@ const (
AdminModuleCodeSetting AdminModuleCode = "setting"
)
var adminModuleMapping = map[int64]*AdminModuleList{} // adminId => AdminModuleList
var sharedAdminModuleMapping = map[int64]*AdminModuleList{} // adminId => AdminModuleList
func LoadAdminModuleMapping() (map[int64]*AdminModuleList, error) {
locker.Lock()
defer locker.Unlock()
if len(adminModuleMapping) > 0 {
return adminModuleMapping, nil
func loadAdminModuleMapping() (map[int64]*AdminModuleList, error) {
if len(sharedAdminModuleMapping) > 0 {
return sharedAdminModuleMapping, nil
}
// TODO
rpcClient, err := rpc.SharedRPC()
if err != nil {
return nil, err
}
modulesResp, err := rpcClient.AdminRPC().FindAllAdminModules(rpcClient.Context(0), &pb.FindAllAdminModulesRequest{})
if err != nil {
return nil, err
}
mapping := map[int64]*AdminModuleList{}
for _, m := range modulesResp.AdminModules {
list := &AdminModuleList{
IsSuper: m.IsSuper,
}
return nil, nil
for _, pbModule := range m.Modules {
list.Modules = append(list.Modules, &systemconfigs.AdminModule{
Code: pbModule.Code,
AllowAll: pbModule.AllowAll,
Actions: pbModule.Actions,
})
}
mapping[m.AdminId] = list
}
sharedAdminModuleMapping = mapping
return sharedAdminModuleMapping, nil
}
func NotifyAdminModuleMappingChange() error {
locker.Lock()
adminModuleMapping = map[int64]*AdminModuleList{}
locker.Unlock() // 这里结束是为了避免和LoadAdminModuleMapping()造成死锁
_, err := LoadAdminModuleMapping()
defer locker.Unlock()
sharedAdminModuleMapping = map[int64]*AdminModuleList{}
_, err := loadAdminModuleMapping()
return err
}
func IsAllowModule(adminId int64, module string) bool {
// TODO
// 检查模块是否允许访问
func AllowModule(adminId int64, module string) bool {
locker.Lock()
defer locker.Unlock()
if len(sharedAdminModuleMapping) == 0 {
_, _ = loadAdminModuleMapping()
}
list, ok := sharedAdminModuleMapping[adminId]
if ok {
return list.Allow(module)
}
return false
}
// 获取管理员第一个可访问模块
func FindFirstAdminModule(adminId int64) (module AdminModuleCode, ok bool) {
locker.Lock()
defer locker.Unlock()
list, ok2 := sharedAdminModuleMapping[adminId]
if ok2 {
if list.IsSuper {
return AdminModuleCodeServer, true
} else if len(list.Modules) > 0 {
return list.Modules[0].Code, true
}
}
return
}
// 所有权限列表
func AllModuleMaps() []maps.Map {
return []maps.Map{
{
"name": "网站服务",
"code": AdminModuleCodeServer,
"url": "/servers",
},
{
"name": "边缘节点",
"code": AdminModuleCodeNode,
"url": "/clusters",
},
{
"name": "域名解析",
"code": AdminModuleCodeDNS,
"url": "/dns",
},
{
"name": "系统用户",
"code": AdminModuleCodeAdmin,
"url": "/admins",
},
{
"name": "日志审计",
"code": AdminModuleCodeLog,
"url": "/log",
},
{
"name": "系统设置",
"code": AdminModuleCodeSetting,
"url": "/settings",
},
}
}

View File

@@ -6,3 +6,15 @@ type AdminModuleList struct {
IsSuper bool
Modules []*systemconfigs.AdminModule
}
func (this *AdminModuleList) Allow(module string) bool {
if this.IsSuper {
return true
}
for _, m := range this.Modules {
if m.Code == module {
return true
}
}
return false
}

View File

@@ -0,0 +1,14 @@
package configloaders
import (
"github.com/iwind/TeaGo/logs"
"testing"
)
func TestLoadAdminModuleMapping(t *testing.T) {
m, err := LoadAdminModuleMapping()
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(m, t)
}

View File

@@ -88,7 +88,16 @@ func (this *CreatePopupAction) RunPost(params struct {
return
}
defer this.CreateLogInfo("创建系统用户 %d", createResp.AdminId)
// 通知更改
err = configloaders.NotifyAdminModuleMappingChange()
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -1,6 +1,7 @@
package admins
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
@@ -20,5 +21,12 @@ func (this *DeleteAction) RunPost(params struct {
return
}
// 通知更改
err = configloaders.NotifyAdminModuleMappingChange()
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -10,12 +10,12 @@ func init() {
server.
Helper(helpers.NewUserMustAuth()).
Data("teaMenu", "admins").
Data("teaModule", "admin").
Prefix("/admins").
Get("", new(IndexAction)).
GetPost("/createPopup", new(CreatePopupAction)).
GetPost("/updatePopup", new(UpdatePopupAction)).
Post("/delete", new(DeleteAction)).
Post("/updateOn", new(UpdateOnAction)).
EndAll()
})
}

View File

@@ -1,11 +0,0 @@
package admins
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
type UpdateOnAction struct {
actionutils.ParentAction
}
func (this *UpdateOnAction) RunPost(params struct{}) {
this.Success()
}

View File

@@ -125,5 +125,12 @@ func (this *UpdatePopupAction) RunPost(params struct {
return
}
// 通知更改
err = configloaders.NotifyAdminModuleMappingChange()
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -11,6 +11,7 @@ func init() {
server.
Helper(helpers.NewUserMustAuth()).
Helper(clusterutils.NewClustersHelper()).
Data("teaModule", "node").
Prefix("/clusters").
Get("", new(IndexAction)).
GetPost("/create", new(CreateAction)).

View File

@@ -1,6 +1,9 @@
package dashboard
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
)
type IndexAction struct {
actionutils.ParentAction
@@ -11,5 +14,14 @@ func (this *IndexAction) Init() {
}
func (this *IndexAction) RunGet(params struct{}) {
this.RedirectURL("/servers")
// 取得用户的权限
module, ok := configloaders.FindFirstAdminModule(this.AdminId())
if ok {
for _, m := range configloaders.AllModuleMaps() {
if m.GetString("code") == module {
this.RedirectURL(m.GetString("url"))
return
}
}
}
}

View File

@@ -14,6 +14,7 @@ func init() {
server.
Helper(new(helpers.UserMustAuth)).
Helper(new(Helper)).
Data("teaModule", "dns").
Prefix("/dns").
Get("", new(IndexAction)).
GetPost("/updateClusterPopup", new(UpdateClusterPopupAction)).

View File

@@ -10,6 +10,7 @@ func init() {
server.
Helper(new(helpers.UserMustAuth)).
Helper(new(Helper)).
Data("teaModule", "log").
Prefix("/log").
Get("", new(IndexAction)).
Get("/exportExcel", new(ExportExcelAction)).

View File

@@ -10,6 +10,7 @@ func init() {
server.
Helper(helpers.NewUserMustAuth()).
Helper(NewHelper()).
Data("teaModule", "server").
Prefix("/servers").
Get("", new(IndexAction)).
GetPost("/create", new(CreateAction)).

View File

@@ -10,6 +10,7 @@ func init() {
server.
Helper(helpers.NewUserMustAuth()).
Helper(NewHelper()).
Data("teaModule", "setting").
Prefix("/settings").
Get("", new(IndexAction)).
EndAll()

View File

@@ -15,7 +15,7 @@ import (
// 认证拦截
type UserMustAuth struct {
AdminId int
AdminId int64
Grant string
}
@@ -48,12 +48,19 @@ func (this *UserMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
}
var session = action.Session()
var adminId = session.GetInt("adminId")
var adminId = session.GetInt64("adminId")
if adminId <= 0 {
this.login(action)
return false
}
// 检查用户权限
teaModule := action.Data.GetString("teaModule")
if len(teaModule) > 0 && !configloaders.AllowModule(adminId, teaModule) {
action.WriteString("Permission Denied.")
return false
}
// 检查用户是否存在
rpc, err := nodes.SharedRPC()
if err != nil {
@@ -111,7 +118,7 @@ func (this *UserMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
if !action.Data.Has("teaMenu") {
action.Data["teaMenu"] = ""
}
action.Data["teaModules"] = this.modules()
action.Data["teaModules"] = this.modules(adminId)
action.Data["teaSubMenus"] = []map[string]interface{}{}
action.Data["teaTabbar"] = []map[string]interface{}{}
if len(config.Version) == 0 {
@@ -142,12 +149,13 @@ func (this *UserMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
}
// 菜单配置
func (this *UserMustAuth) modules() []maps.Map {
return []maps.Map{
func (this *UserMustAuth) modules(adminId int64) []maps.Map {
allMaps := []maps.Map{
{
"code": "servers",
"name": "网站服务",
"icon": "clone outsize",
"code": "servers",
"module": configloaders.AdminModuleCodeServer,
"name": "网站服务",
"icon": "clone outsize",
"subItems": []maps.Map{
{
"name": "通用设置",
@@ -177,9 +185,10 @@ func (this *UserMustAuth) modules() []maps.Map {
},
},
{
"code": "clusters",
"name": "边缘节点",
"icon": "cloud",
"code": "clusters",
"module": configloaders.AdminModuleCodeNode,
"name": "边缘节点",
"icon": "cloud",
"subItems": []maps.Map{
{
"name": "SSH认证",
@@ -189,9 +198,10 @@ func (this *UserMustAuth) modules() []maps.Map {
},
},
{
"code": "dns",
"name": "域名解析",
"icon": "globe",
"code": "dns",
"module": configloaders.AdminModuleCodeDNS,
"name": "域名解析",
"icon": "globe",
"subItems": []maps.Map{
{
"name": "问题修复",
@@ -206,21 +216,33 @@ func (this *UserMustAuth) modules() []maps.Map {
},
},
{
"code": "admins",
"name": "系统用户",
"icon": "users",
"code": "admins",
"module": configloaders.AdminModuleCodeAdmin,
"name": "系统用户",
"icon": "users",
},
{
"code": "log",
"name": "日志审计",
"icon": "history",
"code": "log",
"module": configloaders.AdminModuleCodeLog,
"name": "日志审计",
"icon": "history",
},
{
"code": "settings",
"name": "系统设置",
"icon": "setting",
"code": "settings",
"module": configloaders.AdminModuleCodeSetting,
"name": "系统设置",
"icon": "setting",
},
}
result := []maps.Map{}
for _, m := range allMaps {
module := m.GetString("module")
if configloaders.AllowModule(adminId, module) {
result = append(result, m)
}
}
return result
}
// 跳转到登录页

View File

@@ -23,7 +23,7 @@
<label-on :v-is-on="admin.isOn"></label-on>
</td>
<td>
<a href="" @click.prevent="updateAdmin(admin.id)">修改</a> &nbsp; <a href="" v-if="!admin.isSuper" @click.prevent="deleteAdmin(admin.id)">删除</a>
<a href="" @click.prevent="updateAdmin(admin.id)" v-if="!admin.isSuper">修改</a> &nbsp; <a href="" v-if="!admin.isSuper" @click.prevent="deleteAdmin(admin.id)">删除</a>
</td>
</tr>
</table>