From 412b5ae9a8804bff07e591e24a2358c5bb2f20b3 Mon Sep 17 00:00:00 2001 From: liugq Date: Mon, 9 May 2022 15:26:16 +0800 Subject: [PATCH] move rbac to framework --- internal/biz/account.go | 42 +++++++--------- internal/biz/context.go | 4 +- internal/biz/role.go | 36 +++----------- internal/biz/user.go | 10 ++-- internal/biz/validate.go | 2 +- main.go | 8 ++- plugin/api/account/account.go | 17 +++---- plugin/api/index_management/index.go | 74 +--------------------------- plugin/api/init.go | 1 - plugin/api/rbac/api.go | 31 ++++++------ plugin/api/rbac/permission.go | 2 +- plugin/api/rbac/role.go | 17 ++++--- 12 files changed, 68 insertions(+), 176 deletions(-) diff --git a/internal/biz/account.go b/internal/biz/account.go index 6513179f..23d9b4b4 100644 --- a/internal/biz/account.go +++ b/internal/biz/account.go @@ -16,29 +16,17 @@ import ( type UserClaims struct { *jwt.RegisteredClaims - *User + *ShortUser } -type User struct { +type ShortUser struct { Username string `json:"username"` UserId string `json:"user_id"` Roles []string `json:"roles"` } -type Account struct { - ID string `json:"id,omitempty" ` - Created string `json:"created,omitempty" ` - Updated string `json:"updated,omitempty" ` - Username string `json:"username" elastic_mapping:"username:{type:keyword}"` - Password string `json:"password" elastic_mapping:"password:{type:text}"` - Name string `json:"name" elastic_mapping:"name:{type:keyword}"` - Phone string `json:"phone" elastic_mapping:"phone:{type:keyword}"` - Email string `json:"email" elastic_mapping:"email:{type:keyword}"` - Tags []string `json:"tags" elastic_mapping:"tags:{type:text}"` - Roles []rbac.UserRole `json:"roles"` -} const Secret = "console" -func authenticateUser(username string, password string) (user Account, err error) { +func authenticateUser(username string, password string) (user rbac.User, err error) { err, result := orm.GetBy("name", username, rbac.User{}) if err != nil { @@ -49,6 +37,10 @@ func authenticateUser(username string, password string) (user Account, err error err = errors.New("user not found") return } + if row, ok := result.Result[0].(map[string]interface{}); ok { + delete(row, "created") + delete(row, "updated") + } err = mapstructure.Decode(result.Result[0], &user) if err != nil { @@ -62,7 +54,7 @@ func authenticateUser(username string, password string) (user Account, err error return } -func authenticateAdmin(username string, password string) (user Account, err error) { +func authenticateAdmin(username string, password string) (user rbac.User, err error) { u, _ := global.Env().GetConfig("bootstrap.username", "admin") p, _ := global.Env().GetConfig("bootstrap.password", "admin") @@ -72,13 +64,13 @@ func authenticateAdmin(username string, password string) (user Account, err erro return } user.ID = username - user.Username = username + user.Name = username user.Roles = []rbac.UserRole{{ ID: "admin", Name: "admin", }} return user, nil } -func authorize(user Account) (m map[string]interface{}, err error) { +func authorize(user rbac.User) (m map[string]interface{}, err error) { var roles, privilege []string for _, v := range user.Roles { @@ -87,8 +79,8 @@ func authorize(user Account) (m map[string]interface{}, err error) { privilege = append(privilege, role.Privilege.Platform...) } token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaims{ - User: &User{ - Username: user.Username, + ShortUser: &ShortUser{ + Username: user.Name, UserId: user.ID, Roles: roles, }, @@ -104,7 +96,7 @@ func authorize(user Account) (m map[string]interface{}, err error) { m = util.MapStr{ "access_token": tokenString, - "username": user.Username, + "username": user.Name, "id": user.ID, "expire_in": 86400, "roles": roles, @@ -113,7 +105,7 @@ func authorize(user Account) (m map[string]interface{}, err error) { return } func Login(username string, password string) (m map[string]interface{}, err error) { - var user Account + var user rbac.User if username == "admin" { user, err = authenticateAdmin(username, password) if err != nil { @@ -143,12 +135,12 @@ func Login(username string, password string) (m map[string]interface{}, err erro }, User: util.MapStr{ "id": user.ID, - "name": user.Username, + "name": user.Name, }, }, nil, nil)) return } -func UpdatePassword(localUser *User, req dto.UpdatePassword) (err error) { +func UpdatePassword(localUser *ShortUser, req dto.UpdatePassword) (err error) { user := rbac.User{} user.ID = localUser.UserId _, err = orm.Get(&user) @@ -186,7 +178,7 @@ func UpdatePassword(localUser *User, req dto.UpdatePassword) (err error) { }, nil, nil)) return } -func UpdateProfile(localUser *User, req dto.UpdateProfile) (err error) { +func UpdateProfile(localUser *ShortUser, req dto.UpdateProfile) (err error) { user := rbac.User{} user.ID = localUser.UserId _, err = orm.Get(&user) diff --git a/internal/biz/context.go b/internal/biz/context.go index 2d4a8e49..cc152225 100644 --- a/internal/biz/context.go +++ b/internal/biz/context.go @@ -10,7 +10,7 @@ const ctxUserKey = "user" func NewUserContext(ctx context.Context, clam *UserClaims) context.Context { return context.WithValue(ctx, ctxUserKey, clam) } -func FromUserContext(ctx context.Context) (*User, error) { +func FromUserContext(ctx context.Context) (*ShortUser, error) { ctxUser := ctx.Value(ctxUserKey) if ctxUser == nil { return nil, errors.New("user not found") @@ -19,5 +19,5 @@ func FromUserContext(ctx context.Context) (*User, error) { if !ok { return nil, errors.New("invalid context user") } - return reqUser.User, nil + return reqUser.ShortUser, nil } diff --git a/internal/biz/role.go b/internal/biz/role.go index b5d0de28..ec9807df 100644 --- a/internal/biz/role.go +++ b/internal/biz/role.go @@ -16,47 +16,23 @@ import ( type RoleType = string const ( - Platform RoleType = "platform" - Elastisearch RoleType = "elasticsearch" + Platform RoleType = "platform" + Elasticsearch RoleType = "elasticsearch" ) -func UpdateRole(localUser *User, role *rbac.Role) (err error) { +func UpdateRole(role *rbac.Role) (err error) { model, err := GetRole(role.ID) if err != nil { return err } role.Type = model.Type role.Created = model.Created - changeLog, _ := util.DiffTwoObject(model, role) role.Updated = time.Now() err = orm.Save(role) - if err != nil { - return - } - - RoleMap[model.Name] = model - - err = orm.Save(GenerateEvent(event.ActivityMetadata{ - Category: "platform", - Group: "rbac", - Name: "role", - Type: "update", - Labels: util.MapStr{ - "id": model.ID, - "description": model.Description, - "privilege": role.Privilege, - "updated": model.Updated, - }, - User: util.MapStr{ - "userid": localUser.UserId, - "username": localUser.Username, - }, - }, nil, changeLog)) - return } -func CreateRole(localUser *User, role *rbac.Role) (id string, err error) { +func CreateRole(localUser *ShortUser, role *rbac.Role) (id string, err error) { if role.Name == "" { err = errors.New("role name is require") return @@ -110,7 +86,7 @@ func CreateRole(localUser *User, role *rbac.Role) (id string, err error) { return } -func DeleteRole(localUser *User, id string) (err error) { +func DeleteRole(localUser *ShortUser, id string) (err error) { role := rbac.Role{} role.ID = id roleName := role.Name @@ -178,7 +154,7 @@ func SearchRole(keyword string, from, size int) (roles orm.Result, err error) { return } func IsAllowRoleType(roleType string) (err error) { - if roleType != Platform && roleType != Elastisearch { + if roleType != Platform && roleType != Elasticsearch { err = fmt.Errorf("invalid role type %s ", roleType) return } diff --git a/internal/biz/user.go b/internal/biz/user.go index 34a0e20c..667da8ac 100644 --- a/internal/biz/user.go +++ b/internal/biz/user.go @@ -15,7 +15,7 @@ import ( var ErrNotFound = fmt.Errorf("not found") -func DeleteUser(localUser *User, id string) (err error) { +func DeleteUser(localUser *ShortUser, id string) (err error) { user := rbac.User{} user.ID = id @@ -55,7 +55,7 @@ func DeleteUser(localUser *User, id string) (err error) { }, nil)) return } -func CreateUser(localUser *User, req dto.CreateUser) (id string, password string, err error) { +func CreateUser(localUser *ShortUser, req dto.CreateUser) (id string, password string, err error) { q := orm.Query{Size: 1000} q.Conds = orm.And(orm.Eq("name", req.Name)) @@ -123,7 +123,7 @@ func CreateUser(localUser *User, req dto.CreateUser) (id string, password string }, nil, nil)) return } -func UpdateUser(localUser *User, id string, req dto.UpdateUser) (err error) { +func UpdateUser(localUser *ShortUser, id string, req dto.UpdateUser) (err error) { user := rbac.User{} user.ID = id _, err = orm.Get(&user) @@ -171,7 +171,7 @@ func UpdateUser(localUser *User, id string, req dto.UpdateUser) (err error) { }, nil, changeLog)) return } -func UpdateUserRole(localUser *User, id string, req dto.UpdateUserRole) (err error) { +func UpdateUserRole(localUser *ShortUser, id string, req dto.UpdateUserRole) (err error) { user := rbac.User{} user.ID = id _, err = orm.Get(&user) @@ -239,7 +239,7 @@ func SearchUser(keyword string, from, size int) (users orm.Result, err error) { return } -func UpdateUserPassword(localUser *User, id string, password string) (err error) { +func UpdateUserPassword(localUser *ShortUser, id string, password string) (err error) { user := rbac.User{} user.ID = id _, err = orm.Get(&user) diff --git a/internal/biz/validate.go b/internal/biz/validate.go index d67943f1..86e8f0ff 100644 --- a/internal/biz/validate.go +++ b/internal/biz/validate.go @@ -234,7 +234,7 @@ func ValidateLogin(authorizationHeader string) (clams *UserClaims, err error) { } func ValidatePermission(claims *UserClaims, permissions []string) (err error) { - user := claims.User + user := claims.ShortUser if user.UserId == "" { err = errors.New("user id is empty") diff --git a/main.go b/main.go index ce11dd6f..7a773a18 100644 --- a/main.go +++ b/main.go @@ -7,9 +7,7 @@ import ( "infini.sh/console/model" "infini.sh/console/model/alerting" "infini.sh/console/model/gateway" - "infini.sh/console/model/rbac" _ "infini.sh/console/plugin" - rbacApi "infini.sh/console/plugin/api/rbac" alerting2 "infini.sh/console/service/alerting" "infini.sh/framework" "infini.sh/framework/core/elastic" @@ -24,6 +22,7 @@ import ( "infini.sh/framework/modules/pipeline" queue2 "infini.sh/framework/modules/queue/disk_queue" "infini.sh/framework/modules/redis" + "infini.sh/framework/modules/security" "infini.sh/framework/modules/stats" "infini.sh/framework/modules/task" "infini.sh/framework/modules/ui" @@ -77,6 +76,7 @@ func main() { module.RegisterSystemModule(&task.TaskModule{}) module.RegisterUserPlugin(&metrics.MetricsModule{}) + module.RegisterUserPlugin(&security.SecurityModule{}) api.RegisterAPI("") appConfig = &config.AppConfig{ @@ -129,8 +129,6 @@ func main() { orm.RegisterSchemaWithIndexName(gateway.Instance{}, "gateway-instance") orm.RegisterSchemaWithIndexName(alerting.Rule{}, "alert-rule") orm.RegisterSchemaWithIndexName(alerting.Alert{}, "alert-history") - orm.RegisterSchemaWithIndexName(rbac.Role{}, "rbac-role") - orm.RegisterSchemaWithIndexName(rbac.User{}, "rbac-user") api.RegisterSchema() go func() { @@ -139,7 +137,7 @@ func main() { log.Errorf("init alerting task error: %v", err) } }() - go rbacApi.Init() + //go rbacApi.Init() }, nil) { app.Run() diff --git a/plugin/api/account/account.go b/plugin/api/account/account.go index e82c627d..35c258f7 100644 --- a/plugin/api/account/account.go +++ b/plugin/api/account/account.go @@ -4,7 +4,6 @@ import ( "infini.sh/console/internal/biz" "infini.sh/console/internal/core" "infini.sh/console/internal/dto" - m "infini.sh/console/internal/middleware" "infini.sh/framework/core/api" "infini.sh/framework/core/api/router" "infini.sh/framework/core/util" @@ -16,14 +15,14 @@ type Account struct { } func init() { - account := Account{} - api.HandleAPIMethod(api.POST, "/account/login", account.Login) - - api.HandleAPIMethod(api.GET, "/account/current_user", account.CurrentUser) - - api.HandleAPIMethod(api.DELETE, "/account/logout", account.Logout) - api.HandleAPIMethod(api.GET, "/account/profile", m.LoginRequired(account.Profile)) - api.HandleAPIMethod(api.PUT, "/account/password", m.LoginRequired(account.UpdatePassword)) + //account := Account{} + //api.HandleAPIMethod(api.POST, "/account/login", account.Login) + // + //api.HandleAPIMethod(api.GET, "/account/current_user", account.CurrentUser) + // + //api.HandleAPIMethod(api.DELETE, "/account/logout", account.Logout) + //api.HandleAPIMethod(api.GET, "/account/profile", m.LoginRequired(account.Profile)) + //api.HandleAPIMethod(api.PUT, "/account/password", m.LoginRequired(account.UpdatePassword)) } const userInSession = "user_session:" diff --git a/plugin/api/index_management/index.go b/plugin/api/index_management/index.go index 6c659afd..99ee9422 100644 --- a/plugin/api/index_management/index.go +++ b/plugin/api/index_management/index.go @@ -1,8 +1,6 @@ package index_management import ( - "fmt" - "infini.sh/framework/core/elastic" "net/http" "strconv" "strings" @@ -117,74 +115,4 @@ func (handler APIHandler) UpdateDictItemAction(w http.ResponseWriter, req *http. resp["payload"] = dict handler.WriteJSON(w, resp, http.StatusOK) -} -func (h APIHandler) ListIndex(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { - clusterIds := h.GetParameterOrDefault(req, "ids", "") - keyword := h.GetParameterOrDefault(req, "keyword", "") - ids := strings.Split(clusterIds, ",") - for i := range ids { - if i < len(ids)-1 { - ids[i] = `"` + ids[i] + `",` - } else { - ids[i] = `"` + ids[i] + `"` - } - - } - if len(ids) == 0 { - h.Error400(w, "id is required") - return - } - var dsl = `{ - "_source": ["metadata.index_name"], - "collapse": { - "field": "metadata.index_name" - }, - "size": 100, - "query": { - "bool": { - "must": [ - { - "terms": { - "metadata.cluster_id": %s - } - }%s - ], - "must_not": [ - { - "term": { - "metadata.labels.state": { - "value": "delete" - } - } - } - ] - } - } - }` - - str := &strings.Builder{} - - if keyword != "" { - str.WriteString(fmt.Sprintf(`,{"wildcard":{"metadata.index_name":{"value":"*%s*"}}}`, keyword)) - } - dsl = fmt.Sprintf(dsl, ids, str) - - esClient := elastic.GetClient(h.Config.Elasticsearch) - resp, err := esClient.SearchWithRawQueryDSL(".infini_index", []byte(dsl)) - if err != nil { - - return - } - list := resp.Hits.Hits - var indexNames []string - for _, v := range list { - m := v.Source["metadata"].(map[string]interface{}) - indexNames = append(indexNames, m["index_name"].(string)) - - } - m := make(map[string]interface{}) - m["indexnames"] = indexNames - h.WriteOKJSON(w, m) - - return -} +} \ No newline at end of file diff --git a/plugin/api/init.go b/plugin/api/init.go index 0d66b36b..766b40e4 100644 --- a/plugin/api/init.go +++ b/plugin/api/init.go @@ -46,7 +46,6 @@ func Init(cfg *config.AppConfig) { api.HandleAPIMethod(api.PUT, path.Join(pathPrefix, "elasticsearch/command/:cid"), handler.HandleSaveCommonCommandAction) api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/command"), handler.HandleQueryCommonCommandAction) api.HandleAPIMethod(api.DELETE, path.Join(pathPrefix, "elasticsearch/command/:cid"), handler.HandleDeleteCommonCommandAction) - api.HandleAPIMethod(api.GET, path.Join(pathPrefix, "elasticsearch/indices"), handler.ListIndex) //task.RegisterScheduleTask(task.ScheduleTask{ // Description: "sync reindex task result", // Task: func() { diff --git a/plugin/api/rbac/api.go b/plugin/api/rbac/api.go index dccd061b..4a2e19d6 100644 --- a/plugin/api/rbac/api.go +++ b/plugin/api/rbac/api.go @@ -5,7 +5,6 @@ import ( "github.com/mitchellh/mapstructure" "infini.sh/console/internal/biz" "infini.sh/console/internal/biz/enum" - m "infini.sh/console/internal/middleware" "infini.sh/console/model/rbac" "infini.sh/framework/core/api" "infini.sh/framework/core/elastic" @@ -21,21 +20,21 @@ type Rbac struct { func init() { - r := Rbac{} - api.HandleAPIMethod(api.GET, "/permission/:type", r.ListPermission) - api.HandleAPIMethod(api.POST, "/role/:type", m.PermissionRequired(r.CreateRole, enum.RoleAllPermission...)) - api.HandleAPIMethod(api.GET, "/role/:id", m.PermissionRequired(r.GetRole, enum.RoleReadPermission...)) - api.HandleAPIMethod(api.DELETE, "/role/:id", m.PermissionRequired(r.DeleteRole, enum.RoleAllPermission...)) - api.HandleAPIMethod(api.PUT, "/role/:id", m.PermissionRequired(r.UpdateRole, enum.RoleAllPermission...)) - api.HandleAPIMethod(api.GET, "/role/_search", m.PermissionRequired(r.SearchRole, enum.RoleReadPermission...)) - - api.HandleAPIMethod(api.POST, "/user", m.PermissionRequired(r.CreateUser, enum.UserAllPermission...)) - api.HandleAPIMethod(api.GET, "/user/:id", m.PermissionRequired(r.GetUser, enum.UserReadPermission...)) - api.HandleAPIMethod(api.DELETE, "/user/:id", m.PermissionRequired(r.DeleteUser, enum.UserAllPermission...)) - api.HandleAPIMethod(api.PUT, "/user/:id", m.PermissionRequired(r.UpdateUser, enum.UserAllPermission...)) - api.HandleAPIMethod(api.PUT, "/user/:id/role", m.PermissionRequired(r.UpdateUserRole, enum.UserAllPermission...)) - api.HandleAPIMethod(api.GET, "/user/_search", m.PermissionRequired(r.SearchUser, enum.UserReadPermission...)) - api.HandleAPIMethod(api.PUT, "/user/:id/password", m.PermissionRequired(r.UpdateUserPassword, enum.UserAllPermission...)) + //r := Rbac{} + //api.HandleAPIMethod(api.GET, "/permission/:type", r.ListPermission) + //api.HandleAPIMethod(api.POST, "/role/:type", m.PermissionRequired(r.CreateRole, enum.RoleAllPermission...)) + //api.HandleAPIMethod(api.GET, "/role/:id", m.PermissionRequired(r.GetRole, enum.RoleReadPermission...)) + //api.HandleAPIMethod(api.DELETE, "/role/:id", m.PermissionRequired(r.DeleteRole, enum.RoleAllPermission...)) + //api.HandleAPIMethod(api.PUT, "/role/:id", m.PermissionRequired(r.UpdateRole, enum.RoleAllPermission...)) + //api.HandleAPIMethod(api.GET, "/role/_search", m.PermissionRequired(r.SearchRole, enum.RoleReadPermission...)) + // + //api.HandleAPIMethod(api.POST, "/user", m.PermissionRequired(r.CreateUser, enum.UserAllPermission...)) + //api.HandleAPIMethod(api.GET, "/user/:id", m.PermissionRequired(r.GetUser, enum.UserReadPermission...)) + //api.HandleAPIMethod(api.DELETE, "/user/:id", m.PermissionRequired(r.DeleteUser, enum.UserAllPermission...)) + //api.HandleAPIMethod(api.PUT, "/user/:id", m.PermissionRequired(r.UpdateUser, enum.UserAllPermission...)) + //api.HandleAPIMethod(api.PUT, "/user/:id/role", m.PermissionRequired(r.UpdateUserRole, enum.UserAllPermission...)) + //api.HandleAPIMethod(api.GET, "/user/_search", m.PermissionRequired(r.SearchUser, enum.UserReadPermission...)) + //api.HandleAPIMethod(api.PUT, "/user/:id/password", m.PermissionRequired(r.UpdateUserPassword, enum.UserAllPermission...)) } func loadJsonConfig() { diff --git a/plugin/api/rbac/permission.go b/plugin/api/rbac/permission.go index fc31eb02..69f2d00f 100644 --- a/plugin/api/rbac/permission.go +++ b/plugin/api/rbac/permission.go @@ -16,7 +16,7 @@ func (h Rbac) ListPermission(w http.ResponseWriter, r *http.Request, ps httprout return } var permissions interface{} - if typ == biz.Elastisearch { + if typ == biz.Elasticsearch { permissions = biz.ListElasticsearchPermission() } h.WriteOKJSON(w, permissions) diff --git a/plugin/api/rbac/role.go b/plugin/api/rbac/role.go index ffa6097b..eca29b20 100644 --- a/plugin/api/rbac/role.go +++ b/plugin/api/rbac/role.go @@ -125,20 +125,21 @@ func (h Rbac) DeleteRole(w http.ResponseWriter, r *http.Request, ps httprouter.P func (h Rbac) UpdateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { id := ps.MustGetParameter("id") - localUser, err := biz.FromUserContext(r.Context()) - if err != nil { - log.Error(err.Error()) - h.ErrorInternalServer(w, err.Error()) - return - } + //localUser, err := biz.FromUserContext(r.Context()) + //if err != nil { + // log.Error(err.Error()) + // h.ErrorInternalServer(w, err.Error()) + // return + //} role := &rbac.Role{} - err = h.DecodeJSON(r, role) + err := h.DecodeJSON(r, role) if err != nil { h.Error400(w, err.Error()) return } role.ID = id - err = biz.UpdateRole(localUser, role) + err = biz.UpdateRole(role) + biz.RoleMap[role.Name] = *role if err != nil { _ = log.Error(err.Error())