remove rbac from console

This commit is contained in:
liugq 2022-05-09 20:45:39 +08:00
parent 412b5ae9a8
commit fcd52923c2
21 changed files with 1 additions and 2068 deletions

View File

@ -1,211 +0,0 @@
package biz
import (
"errors"
"github.com/golang-jwt/jwt"
"github.com/mitchellh/mapstructure"
"golang.org/x/crypto/bcrypt"
"infini.sh/console/internal/dto"
"infini.sh/console/model/rbac"
"infini.sh/framework/core/event"
"infini.sh/framework/core/global"
"infini.sh/framework/core/orm"
"infini.sh/framework/core/util"
"time"
)
type UserClaims struct {
*jwt.RegisteredClaims
*ShortUser
}
type ShortUser struct {
Username string `json:"username"`
UserId string `json:"user_id"`
Roles []string `json:"roles"`
}
const Secret = "console"
func authenticateUser(username string, password string) (user rbac.User, err error) {
err, result := orm.GetBy("name", username, rbac.User{})
if err != nil {
err = ErrNotFound
return
}
if result.Total == 0 {
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 {
return
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
if err == bcrypt.ErrMismatchedHashAndPassword {
err = errors.New("password incorrect")
return
}
return
}
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")
if u != username || p != password {
err = errors.New("invalid username or password")
return
}
user.ID = username
user.Name = username
user.Roles = []rbac.UserRole{{
ID: "admin", Name: "admin",
}}
return user, nil
}
func authorize(user rbac.User) (m map[string]interface{}, err error) {
var roles, privilege []string
for _, v := range user.Roles {
role := RoleMap[v.Name]
roles = append(roles, v.Name)
privilege = append(privilege, role.Privilege.Platform...)
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserClaims{
ShortUser: &ShortUser{
Username: user.Name,
UserId: user.ID,
Roles: roles,
},
RegisteredClaims: &jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
},
})
tokenString, err := token.SignedString([]byte(Secret))
if err != nil {
return
}
m = util.MapStr{
"access_token": tokenString,
"username": user.Name,
"id": user.ID,
"expire_in": 86400,
"roles": roles,
"privilege": privilege,
}
return
}
func Login(username string, password string) (m map[string]interface{}, err error) {
var user rbac.User
if username == "admin" {
user, err = authenticateAdmin(username, password)
if err != nil {
return nil, err
}
} else {
user, err = authenticateUser(username, password)
if err != nil {
return nil, err
}
}
m, err = authorize(user)
if err != nil {
return
}
TokenMap[user.ID] = Token{ExpireIn: time.Now().Unix() + 86400}
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "login",
Type: "create",
Labels: util.MapStr{
"username": username,
"password": password,
},
User: util.MapStr{
"id": user.ID,
"name": user.Name,
},
}, nil, nil))
return
}
func UpdatePassword(localUser *ShortUser, req dto.UpdatePassword) (err error) {
user := rbac.User{}
user.ID = localUser.UserId
_, err = orm.Get(&user)
if err != nil {
return
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.OldPassword))
if err == bcrypt.ErrMismatchedHashAndPassword {
err = errors.New("old password is not correct")
return
}
hash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
if err != nil {
return
}
user.Password = string(hash)
err = orm.Save(&user)
if err != nil {
return
}
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "update",
Labels: util.MapStr{
"old_password": req.OldPassword,
"new_password": req.NewPassword,
},
User: util.MapStr{
"id": user.ID,
"name": user.Name,
},
}, nil, nil))
return
}
func UpdateProfile(localUser *ShortUser, req dto.UpdateProfile) (err error) {
user := rbac.User{}
user.ID = localUser.UserId
_, err = orm.Get(&user)
if err != nil {
return
}
user.Name = req.Name
user.Email = req.Email
user.Phone = req.Phone
err = orm.Save(&user)
if err != nil {
return
}
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "update",
Labels: util.MapStr{
"name": req.Name,
"email": req.Email,
"phone": req.Phone,
},
User: util.MapStr{
"id": user.ID,
"name": user.Name,
},
}, nil, nil))
return
}

View File

@ -1,23 +0,0 @@
package biz
import (
"context"
"errors"
)
const ctxUserKey = "user"
func NewUserContext(ctx context.Context, clam *UserClaims) context.Context {
return context.WithValue(ctx, ctxUserKey, clam)
}
func FromUserContext(ctx context.Context) (*ShortUser, error) {
ctxUser := ctx.Value(ctxUserKey)
if ctxUser == nil {
return nil, errors.New("user not found")
}
reqUser, ok := ctxUser.(*UserClaims)
if !ok {
return nil, errors.New("invalid context user")
}
return reqUser.ShortUser, nil
}

View File

@ -1,192 +0,0 @@
package enum
import (
"time"
)
var PermissionMap = make(map[string][]string)
const (
UserRead = "system.user:read"
UserAll = "system.user:all"
RoleRead = "system.role:read"
RoleAll = "system.role:all"
ClusterAll = "system.cluster:all"
ClusterRead = "system.cluster:read"
CommandAll = "system.command:all"
CommandRead = "system.command:read"
InstanceRead = "gateway.instance:read"
InstanceAll = "gateway.instance:all"
EntryAll = "gateway.entry:all"
EntryRead = "gateway.entry:read"
RouterRead = "gateway.router:read"
RouterAll = "gateway.router:all"
FlowRead = "gateway.flow:read"
FlowAll = "gateway.flow:all"
IndexAll = "data.index:all"
IndexRead = "data.index:read"
ViewsAll = "data.view:all"
ViewsRead = "data.view:read"
DiscoverAll = "data.discover:all"
DiscoverRead = "data.discover:read"
RuleRead = "alerting.rule:read"
RuleAll = "alerting.rule:all"
AlertRead = "alerting.alert:read"
AlertAll = "alerting.alert:all"
ChannelRead = "alerting.channel:read"
ChannelAll = "alerting.channel:all"
ClusterOverviewRead = "cluster.overview:read"
ClusterOverviewAll = "cluster.overview:all"
MonitoringRead = "cluster.monitoring:read"
MonitoringAll = "cluster.monitoring:all"
ActivitiesRead = "cluster.activities:read"
ActivitiesAll = "cluster.activities:all"
)
const (
PermissionUserRead string = "user:read"
PermissionUserWrite = "user:write"
PermissionRoleRead = "role:read"
PermissionRoleWrite = "role:write"
PermissionCommandRead = "command:read"
PermissionCommandWrite = "command:write"
PermissionElasticsearchClusterRead = "es.cluster:read"
PermissionElasticsearchClusterWrite = "es.cluster:write" // es cluster
PermissionElasticsearchIndexRead = "es.index:read"
PermissionElasticsearchIndexWrite = "es.index:write" // es index metadata
PermissionElasticsearchNodeRead = "es.node:read" //es node metadata
PermissionActivityRead = "activity:read"
PermissionActivityWrite = "activity:write"
PermissionAlertRuleRead = "alert.rule:read"
PermissionAlertRuleWrite = "alert.rule:write"
PermissionAlertHistoryRead = "alert.history:read"
PermissionAlertHistoryWrite = "alert.history:write"
PermissionAlertChannelRead = "alert.channel:read"
PermissionAlertChannelWrite = "alert.channel:write"
PermissionViewRead = "view:read"
PermissionViewWrite = "view:write"
PermissionGatewayInstanceRead = "gateway.instance:read"
PermissionGatewayInstanceWrite = "gateway.instance:write"
PermissionGatewayEntryRead = "gateway.entry:read"
PermissionGatewayEntryWrite = "gateway.entry:write"
PermissionGatewayRouterRead = "gateway.router:read"
PermissionGatewayRouterWrite = "gateway.router:write"
PermissionGatewayFlowRead = "gateway.flow:read"
PermissionGatewayFlowWrite = "gateway.flow:write"
PermissionElasticsearchMetricRead = "es.metric:read"
)
var (
UserReadPermission = []string{PermissionUserRead}
UserAllPermission = []string{PermissionUserRead, PermissionUserWrite,PermissionRoleRead}
RoleReadPermission = []string{PermissionRoleRead}
RoleAllPermission = []string{PermissionRoleRead, PermissionRoleWrite}
ClusterReadPermission = []string{PermissionElasticsearchClusterRead}
ClusterAllPermission = []string{PermissionElasticsearchClusterRead, PermissionElasticsearchClusterWrite}
CommandReadPermission = []string{PermissionCommandRead}
CommandAllPermission = []string{PermissionCommandRead, PermissionCommandWrite}
InstanceReadPermission = []string{PermissionGatewayInstanceRead}
InstanceAllPermission = []string{PermissionGatewayInstanceRead,PermissionGatewayInstanceWrite}
EntryReadPermission = []string{PermissionGatewayEntryRead}
EntryAllPermission = []string{PermissionGatewayEntryRead, PermissionGatewayEntryWrite}
RouterReadPermission = []string{PermissionGatewayRouterRead}
RouterAllPermission = []string{PermissionGatewayRouterRead, PermissionGatewayRouterWrite}
FlowReadPermission = []string{PermissionGatewayFlowRead}
FlowAllPermission = []string{PermissionGatewayFlowRead, PermissionGatewayFlowWrite}
IndexAllPermission = []string{"index:read"}
IndexReadPermission = []string{"index:read", "index:write"}
ViewsAllPermission = []string{PermissionViewRead}
ViewsReadPermission = []string{PermissionViewRead, PermissionViewWrite}
DiscoverReadPermission = []string{PermissionViewRead}
DiscoverAllPermission = []string{PermissionViewRead}
RuleReadPermission = []string{PermissionAlertRuleRead}
RuleAllPermission = []string{PermissionAlertRuleRead, PermissionAlertRuleWrite}
AlertReadPermission = []string{PermissionAlertHistoryRead}
AlertAllPermission = []string{PermissionAlertHistoryRead, PermissionAlertHistoryWrite}
ChannelReadPermission = []string{PermissionAlertChannelRead}
ChannelAllPermission = []string{PermissionAlertChannelRead, PermissionAlertChannelWrite}
ClusterOverviewReadPermission = []string{PermissionElasticsearchClusterRead, PermissionElasticsearchIndexRead, PermissionElasticsearchNodeRead, PermissionElasticsearchMetricRead}
ClusterOverviewAllPermission = ClusterOverviewReadPermission
MonitoringReadPermission = ClusterOverviewAllPermission
ActivitiesReadPermission = []string{PermissionActivityRead}
ActivitiesAllPermission = []string{PermissionActivityRead, PermissionActivityWrite}
)
var AdminPrivilege = []string{
UserAll, RoleAll, ClusterAll, CommandAll,
InstanceAll, EntryAll, RouterAll, FlowAll,
IndexAll, ViewsAll, DiscoverAll,
RuleAll, AlertAll, ChannelAll,
ClusterOverviewAll, MonitoringAll, ActivitiesAll,
}
var BuildRoles = make(map[string]map[string]interface{}, 0)
func init() {
BuildRoles["admin"] = map[string]interface{}{
"id": "admin",
"name": "管理员",
"type": "platform",
"platform": AdminPrivilege,
"builtin": true,
"description": "is admin",
"created": time.Now(),
}
PermissionMap = map[string][]string{
UserRead: UserReadPermission,
UserAll: UserAllPermission,
RoleRead: RoleReadPermission,
RoleAll: RoleAllPermission,
ClusterRead: ClusterReadPermission,
ClusterAll: ClusterAllPermission,
CommandRead: CommandReadPermission,
CommandAll: CommandAllPermission,
InstanceRead: InstanceReadPermission,
InstanceAll: InstanceAllPermission,
EntryRead: EntryReadPermission,
EntryAll: EntryAllPermission,
RouterRead: RouterReadPermission,
RouterAll: RouterAllPermission,
FlowRead: FlowReadPermission,
FlowAll: FlowAllPermission,
IndexAll: IndexAllPermission,
IndexRead: IndexReadPermission,
ViewsAll: ViewsAllPermission,
ViewsRead: ViewsReadPermission,
DiscoverRead: DiscoverReadPermission,
DiscoverAll: DiscoverAllPermission,
RuleRead: RuleReadPermission,
RuleAll: RuleAllPermission,
AlertRead: AlertReadPermission,
AlertAll: AlertAllPermission,
ChannelRead: ChannelReadPermission,
ChannelAll: ChannelAllPermission,
ClusterOverviewRead: ClusterOverviewReadPermission,
ClusterOverviewAll: ClusterOverviewAllPermission,
MonitoringAll: MonitoringReadPermission,
MonitoringRead: MonitoringReadPermission,
ActivitiesAll: ActivitiesAllPermission,
ActivitiesRead: ActivitiesReadPermission,
}
}

View File

@ -1,18 +0,0 @@
package biz
import (
"infini.sh/framework/core/event"
"infini.sh/framework/core/util"
"time"
)
func GenerateEvent(metadata event.ActivityMetadata, fields util.MapStr, changeLog interface{}) *event.Activity {
return &event.Activity{
ID: util.GetUUID(),
Timestamp: time.Now(),
Metadata: metadata,
Fields: fields,
Changelog: changeLog,
}
}

View File

@ -1,40 +0,0 @@
package biz
import (
"infini.sh/console/model/rbac"
)
var ClusterApis = make(map[string][]string)
var IndexApis = make([]string, 50)
var RoleMap = make(map[string]rbac.Role)
type Token struct {
JwtStr string `json:"jwt_str"`
Value string `json:"value"`
ExpireIn int64 `json:"expire_in"`
}
var TokenMap = make(map[string]Token)
type RolePermission struct {
Platform []string `json:"platform,omitempty"`
Cluster []string `json:"cluster"`
ClusterPrivilege []string `json:"cluster_privilege"`
IndexPrivilege map[string][]string `json:"index_privilege"`
}
func ListElasticsearchPermission() interface{} {
list := ElasticsearchPermission{
ClusterPrivileges: ClusterApis,
IndexPrivileges: IndexApis,
}
return list
}
type ElasticsearchPermission struct {
IndexPrivileges []string `json:"index_privileges"`
ClusterPrivileges map[string][]string `json:"cluster_privileges"`
}

View File

@ -1,162 +0,0 @@
package biz
import (
"errors"
"fmt"
"infini.sh/console/internal/biz/enum"
"infini.sh/console/model/rbac"
"infini.sh/framework/core/event"
"infini.sh/framework/core/orm"
"infini.sh/framework/core/util"
log "src/github.com/cihub/seelog"
"strings"
"time"
)
type RoleType = string
const (
Platform RoleType = "platform"
Elasticsearch RoleType = "elasticsearch"
)
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
role.Updated = time.Now()
err = orm.Save(role)
return
}
func CreateRole(localUser *ShortUser, role *rbac.Role) (id string, err error) {
if role.Name == "" {
err = errors.New("role name is require")
return
}
if _, ok := enum.BuildRoles[role.Name]; ok {
err = fmt.Errorf("role name %s already exists", role.Name)
return
}
q := orm.Query{Size: 1}
q.Conds = orm.And(orm.Eq("name", role.Name))
err, result := orm.Search(rbac.Role{}, &q)
if err != nil {
return
}
if result.Total > 0 {
err = fmt.Errorf("role name %s already exists", role.Name)
return
}
role.ID = util.GetUUID()
role.Created = time.Now()
role.Updated = time.Now()
err = orm.Save(role)
if err != nil {
return
}
id = role.ID
RoleMap[role.Name] = *role
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "role",
Type: "create",
Labels: util.MapStr{
"id": id,
"name": role.Name,
"description": role.Description,
"privilege": role.Privilege,
"type": role.Type,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, nil))
if err != nil {
log.Error(err)
}
return
}
func DeleteRole(localUser *ShortUser, id string) (err error) {
role := rbac.Role{}
role.ID = id
roleName := role.Name
_, err = orm.Get(&role)
if err != nil {
return
}
err = orm.Delete(&role)
if err != nil {
return
}
delete(RoleMap, roleName)
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "role",
Type: "delete",
Labels: util.MapStr{
"id": id,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, util.MapStr{
"id": id,
"name": role.Name,
"description": role.Description,
"type": role.Type,
"created": role.Created.Format("2006-01-02 15:04:05"),
"updated": role.Updated.Format("2006-01-02 15:04:05"),
}, nil))
return
}
func GetRole(id string) (role rbac.Role, err error) {
role.ID = id
_, err = orm.Get(&role)
if err != nil {
return
}
return
}
func SearchRole(keyword string, from, size int) (roles orm.Result, err error) {
query := orm.Query{}
queryDSL := `{"query":{"bool":{"must":[%s]}}, "from": %d,"size": %d}`
mustBuilder := &strings.Builder{}
if keyword != "" {
mustBuilder.WriteString(fmt.Sprintf(`{"query_string":{"default_field":"*","query": "%s"}}`, keyword))
}
queryDSL = fmt.Sprintf(queryDSL, mustBuilder.String(), from, size)
query.RawQuery = []byte(queryDSL)
err, roles = orm.Search(rbac.Role{}, &query)
return
}
func IsAllowRoleType(roleType string) (err error) {
if roleType != Platform && roleType != Elasticsearch {
err = fmt.Errorf("invalid role type %s ", roleType)
return
}
return
}

View File

@ -1,279 +0,0 @@
package biz
import (
"fmt"
"golang.org/x/crypto/bcrypt"
"infini.sh/console/internal/dto"
"infini.sh/console/model/rbac"
"infini.sh/framework/core/event"
"infini.sh/framework/core/orm"
"infini.sh/framework/core/util"
"strings"
"time"
)
var ErrNotFound = fmt.Errorf("not found")
func DeleteUser(localUser *ShortUser, id string) (err error) {
user := rbac.User{}
user.ID = id
_, err = orm.Get(&user)
if err != nil {
return
}
err = orm.Delete(user)
if err != nil {
return
}
delete(TokenMap, id)
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "delete",
Labels: util.MapStr{
"id": id,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, util.MapStr{
"id": id,
"name": user.Name,
"email": user.Email,
"phone": user.Phone,
"password": user.Password,
"nickname": user.NickName,
"tags": user.Tags,
"roles": user.Roles,
"created": user.Created,
"updated": user.Updated,
}, nil))
return
}
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))
err, result := orm.Search(rbac.User{}, &q)
if err != nil {
return
}
if result.Total > 0 {
err = fmt.Errorf("user name %s already exists", req.Name)
return
}
roles := make([]rbac.UserRole, 0)
for _, v := range req.Roles {
roles = append(roles, rbac.UserRole{
ID: v.Id,
Name: v.Name,
})
}
randStr := util.GenerateRandomString(8)
hash, err := bcrypt.GenerateFromPassword([]byte(randStr), bcrypt.DefaultCost)
if err != nil {
return
}
user := rbac.User{
Name: req.Name,
NickName: req.NickName,
Password: string(hash),
Email: req.Email,
Phone: req.Phone,
Roles: roles,
Tags: req.Tags,
}
user.ID = util.GetUUID()
user.Created = time.Now()
user.Updated = time.Now()
err = orm.Save(&user)
if err != nil {
return
}
id = user.ID
password = randStr
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "create",
Labels: util.MapStr{
"id": id,
"name": user.Name,
"email": user.Email,
"phone": user.Phone,
"password": user.Password,
"nick_name": user.NickName,
"tags": user.Tags,
"roles": user.Roles,
"created": user.Created,
"updated": user.Updated,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, nil))
return
}
func UpdateUser(localUser *ShortUser, id string, req dto.UpdateUser) (err error) {
user := rbac.User{}
user.ID = id
_, err = orm.Get(&user)
if err != nil {
return
}
roles := make([]rbac.UserRole, 0)
for _, v := range req.Roles {
roles = append(roles, rbac.UserRole{
ID: v.Id,
Name: v.Name,
})
}
changeLog, _ := util.DiffTwoObject(user, req)
user.Name = req.Name
user.Email = req.Email
user.Phone = req.Phone
user.Tags = req.Tags
user.Roles = roles
user.Updated = time.Now()
err = orm.Save(&user)
if err != nil {
return
}
delete(TokenMap, id)
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "update",
Labels: util.MapStr{
"id": id,
"email": user.Email,
"phone": user.Phone,
"name": user.Name,
"tags": user.Tags,
"roles": roles,
"updated": user.Updated,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, changeLog))
return
}
func UpdateUserRole(localUser *ShortUser, id string, req dto.UpdateUserRole) (err error) {
user := rbac.User{}
user.ID = id
_, err = orm.Get(&user)
if err != nil {
return
}
changeLog, _ := util.DiffTwoObject(user, req)
roles := make([]rbac.UserRole, 0)
for _, v := range req.Roles {
roles = append(roles, rbac.UserRole{
ID: v.Id,
Name: v.Name,
})
}
user.Roles = roles
user.Updated = time.Now()
err = orm.Save(&user)
if err != nil {
return
}
delete(TokenMap, id)
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "update",
Labels: util.MapStr{
"id": id,
"roles": user.Roles,
"updated": user.Updated,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, changeLog))
return
}
func GetUser(id string) (user rbac.User, err error) {
user.ID = id
_, err = orm.Get(&user)
if err != nil {
return
}
return
}
func SearchUser(keyword string, from, size int) (users orm.Result, err error) {
query := orm.Query{}
queryDSL := `{"query":{"bool":{"must":[%s]}}, "from": %d,"size": %d}`
mustBuilder := &strings.Builder{}
if keyword != "" {
mustBuilder.WriteString(fmt.Sprintf(`{"query_string":{"default_field":"*","query": "%s"}}`, keyword))
}
queryDSL = fmt.Sprintf(queryDSL, mustBuilder.String(), from, size)
query.RawQuery = []byte(queryDSL)
err, users = orm.Search(rbac.User{}, &query)
return
}
func UpdateUserPassword(localUser *ShortUser, id string, password string) (err error) {
user := rbac.User{}
user.ID = id
_, err = orm.Get(&user)
if err != nil {
return
}
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return
}
user.Password = string(hash)
user.Updated = time.Now()
err = orm.Save(&user)
if err != nil {
return
}
if localUser.UserId == id {
delete(TokenMap, localUser.UserId)
}
err = orm.Save(GenerateEvent(event.ActivityMetadata{
Category: "platform",
Group: "rbac",
Name: "user",
Type: "update",
Labels: util.MapStr{
"id": id,
"password": password,
"updated": user.Updated,
},
User: util.MapStr{
"userid": localUser.UserId,
"username": localUser.Username,
},
}, nil, nil))
return
}

View File

@ -1,273 +0,0 @@
package biz
import (
"errors"
"fmt"
"infini.sh/console/internal/biz/enum"
"infini.sh/console/model/rbac"
httprouter "infini.sh/framework/core/api/router"
"infini.sh/framework/core/util"
"src/github.com/golang-jwt/jwt"
"strings"
"time"
)
type EsRequest struct {
Doc string `json:"doc"`
Privilege string `json:"privilege"`
ClusterRequest
IndexRequest
}
type ClusterRequest struct {
Cluster []string `json:"cluster"`
Privilege []string `json:"privilege"`
}
type IndexRequest struct {
Cluster []string `json:"cluster"`
Index []string `json:"index"`
Privilege []string `json:"privilege"`
}
func NewIndexRequest(ps httprouter.Params, privilege []string) IndexRequest {
index := ps.ByName("index")
clusterId := ps.ByName("id")
return IndexRequest{
Cluster: []string{clusterId},
Index: []string{index},
Privilege: privilege,
}
}
func NewClusterRequest(ps httprouter.Params, privilege []string) ClusterRequest {
clusterId := ps.ByName("id")
return ClusterRequest{
Cluster: []string{clusterId},
Privilege: privilege,
}
}
func ValidateElasticsearch(req rbac.ElasticsearchPrivilege, roleNames []string) (err error) {
return nil
}
func ValidateIndex(req IndexRequest, userRole RolePermission) (err error) {
userClusterMap := make(map[string]struct{})
for _, v := range userRole.Cluster {
userClusterMap[v] = struct{}{}
}
for _, v := range req.Cluster {
if _, ok := userClusterMap[v]; !ok {
err = errors.New("no cluster permission")
return
}
}
for _, val := range req.Privilege {
position := strings.Index(val, ".")
if position == -1 {
err = errors.New("invalid privilege parameter")
return err
}
prefix := val[:position]
for _, v := range req.Index {
privilege, ok := userRole.IndexPrivilege[v]
if !ok {
err = errors.New("no index permission")
return err
}
if util.StringInArray(privilege, prefix+".*") {
continue
}
if util.StringInArray(privilege, val) {
continue
}
return fmt.Errorf("no index api permission: %s", val)
}
}
return nil
}
func ValidateCluster(req ClusterRequest, roleNames []string) (err error) {
userClusterMap := GetRoleClusterMap(roleNames)
for _, v := range req.Cluster {
userClusterPermissions, ok := userClusterMap[v]
if !ok && userClusterMap["*"] == nil{
err = fmt.Errorf("no cluster[%s] permission", v)
return
}
if util.StringInArray(userClusterPermissions, "*") {
continue
}
// if include api.* for example: cat.* , return nil
for _, privilege := range req.Privilege {
prefix := privilege[:strings.Index(privilege, ".")]
if util.StringInArray(userClusterPermissions, prefix+".*") {
continue
}
if util.StringInArray(userClusterPermissions, privilege) {
continue
}
return fmt.Errorf("no cluster api permission: %s", privilege)
}
}
return nil
}
func CombineUserRoles(roleNames []string) RolePermission {
newRole := RolePermission{}
m := make(map[string][]string)
for _, val := range roleNames {
role := RoleMap[val]
for _, v := range role.Privilege.Elasticsearch.Cluster.Resources {
newRole.Cluster = append(newRole.Cluster, v.ID)
}
for _, v := range role.Privilege.Elasticsearch.Cluster.Permissions {
newRole.ClusterPrivilege = append(newRole.ClusterPrivilege, v)
}
for _, v := range role.Privilege.Platform {
newRole.Platform = append(newRole.Platform, v)
}
for _, v := range role.Privilege.Elasticsearch.Index {
for _, name := range v.Name {
if _, ok := m[name]; ok {
m[name] = append(m[name], v.Permissions...)
} else {
m[name] = v.Permissions
}
}
}
}
newRole.IndexPrivilege = m
return newRole
}
func GetRoleClusterMap(roles []string) map[string][]string {
userClusterMap := make(map[string][]string, 0)
for _, roleName := range roles {
role, ok := RoleMap[roleName]
if ok {
for _, ic := range role.Privilege.Elasticsearch.Cluster.Resources {
userClusterMap[ic.ID] = append(userClusterMap[ic.ID], role.Privilege.Elasticsearch.Cluster.Permissions...)
}
}
}
return userClusterMap
}
func GetRoleCluster(roles []string) []string {
userClusterMap := GetRoleClusterMap(roles)
realCluster := make([]string, 0, len(userClusterMap))
for k, _ := range userClusterMap {
realCluster = append(realCluster, k)
}
return realCluster
}
func GetRoleIndex(roles, clusterIDs []string) map[string][]string {
userClusterMap := make(map[string]struct{}, len(clusterIDs))
for _, clusterID := range clusterIDs {
userClusterMap[clusterID] = struct{}{}
}
realIndex := map[string][]string{}
for _, roleName := range roles {
role, ok := RoleMap[roleName]
if ok {
for _, ic := range role.Privilege.Elasticsearch.Cluster.Resources {
if _, ok = userClusterMap[ic.ID]; !ok {
continue
}
for _, ip := range role.Privilege.Elasticsearch.Index {
realIndex[ic.ID] = append(realIndex[ic.ID], ip.Name...)
}
}
}
}
return realIndex
}
func ValidateLogin(authorizationHeader string) (clams *UserClaims, err error) {
if authorizationHeader == "" {
err = errors.New("authorization header is empty")
return
}
fields := strings.Fields(authorizationHeader)
if fields[0] != "Bearer" || len(fields) != 2 {
err = errors.New("authorization header is invalid")
return
}
tokenString := fields[1]
token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(Secret), nil
})
if err != nil {
return
}
clams, ok := token.Claims.(*UserClaims)
if clams.UserId == "" {
err = errors.New("user id is empty")
return
}
//fmt.Println("user token", clams.UserId, TokenMap[clams.UserId])
tokenVal, ok := TokenMap[clams.UserId]
if !ok {
err = errors.New("token is invalid")
return
}
if tokenVal.ExpireIn < time.Now().Unix() {
err = errors.New("token is expire in")
delete(TokenMap, clams.UserId)
return
}
if ok && token.Valid {
return clams, nil
}
return
}
func ValidatePermission(claims *UserClaims, permissions []string) (err error) {
user := claims.ShortUser
if user.UserId == "" {
err = errors.New("user id is empty")
return
}
if user.Roles == nil {
err = errors.New("api permission is empty")
return
}
// 权限校验
userPermissions := make([]string, 0)
for _, role := range user.Roles {
if _, ok := RoleMap[role]; ok {
for _, v := range RoleMap[role].Privilege.Platform {
userPermissions = append(userPermissions, v)
}
}
}
userPermissionMap := make(map[string]struct{})
for _, val := range userPermissions {
for _, v := range enum.PermissionMap[val] {
userPermissionMap[v] = struct{}{}
}
}
for _, v := range permissions {
if _, ok := userPermissionMap[v]; !ok {
err = errors.New("permission denied")
return
}
}
return nil
}

View File

@ -1,147 +0,0 @@
package biz
import (
"github.com/stretchr/testify/assert"
"infini.sh/framework/core/util"
"testing"
)
func Test_validateIndex(t *testing.T) {
type args struct {
req IndexRequest
userRole RolePermission
}
tests := []struct {
name string
args args
want string
}{
{"no index permission",
args{
req: IndexRequest{
Cluster: []string{"cluster1"},
Index: []string{"index2"},
Privilege: []string{"indices.mapping"},
},
userRole: RolePermission{
Cluster: []string{
"cluster1",
},
ClusterPrivilege: []string{
"cat.*",
},
IndexPrivilege: map[string][]string{
"index1": []string{"indices.delete"},
},
},
}, "no index permission",
},
{"no index api permission",
args{
req: IndexRequest{
Cluster: []string{"cluster1"},
Index: []string{"index1"},
Privilege: []string{"indices.mapping"},
},
userRole: RolePermission{
Cluster: []string{
"cluster1",
},
ClusterPrivilege: []string{
"cat.*",
},
IndexPrivilege: map[string][]string{
"index1": []string{"indices.delete"},
},
},
},
"no index api permission",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ValidateIndex(tt.args.req, tt.args.userRole)
assert.EqualError(t, got, tt.want)
})
}
}
func Test_validateCluster(t *testing.T) {
type args struct {
req ClusterRequest
userRole RolePermission
}
tests := []struct {
name string
args args
want string
}{
{"no cluster",
args{
req: ClusterRequest{
Cluster: []string{"cluster1"},
Privilege: []string{"indices.get_mapping"},
},
userRole: RolePermission{
Cluster: []string{
"cluster2",
},
ClusterPrivilege: []string{
"cat.*",
},
},
}, "no cluster permission",
},
{"no cluster",
args{
req: ClusterRequest{
Cluster: []string{"cluster1"},
Privilege: []string{"indices.get_mapping"},
},
userRole: RolePermission{
Cluster: []string{},
ClusterPrivilege: []string{},
},
}, "no cluster permission",
},
{"no cluster api",
args{
req: ClusterRequest{
Cluster: []string{"cluster1"},
Privilege: []string{"indices.get_mapping"},
},
userRole: RolePermission{
Cluster: []string{
"cluster1",
},
ClusterPrivilege: []string{
"cat.*",
},
},
},
"no cluster api permission",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ValidateCluster(tt.args.req, tt.args.userRole)
assert.EqualError(t, got, tt.want)
})
}
}
func TestStringInArray(t *testing.T) {
array := []string{"a", "b", "c", "d", "e"}
assert.Equal(t, true, util.StringInArray(array, "c"))
assert.Equal(t, false, util.StringInArray(array, "h"))
}

View File

@ -1,45 +0,0 @@
package core
type Response struct {
Total int64 `json:"total,omitempty"`
Hit interface{} `json:"hit,omitempty"`
Id string `json:"_id,omitempty"`
Result string `json:"result,omitempty"`
}
type FoundResp struct {
Found bool `json:"found"`
Id string `json:"_id,omitempty"`
Source interface{} `json:"_source,omitempty"`
}
func CreateResponse(id string) Response {
return Response{
Id: id,
Result: "created",
}
}
func UpdateResponse(id string) Response {
return Response{
Id: id,
Result: "updated",
}
}
func DeleteResponse(id string) Response {
return Response{
Id: id,
Result: "deleted",
}
}
func NotFoundResponse(id string) FoundResp {
return FoundResp{
Id: id,
Found: false,
}
}
func FoundResponse(id string, data interface{}) FoundResp {
return FoundResp{
Id: id,
Found: true,
Source: data,
}
}

View File

@ -1,28 +0,0 @@
package dto
type CreateUser struct {
NickName string `json:"nick_name"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
Roles []Role `json:"roles"`
Tags []string `json:"tags"`
}
type Role struct {
Id string `json:"id"`
Name string `json:"name"`
}
type UpdateUser struct {
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
Tags []string `json:"tags"`
Roles []Role `json:"roles"`
}
type UpdateUserRole struct {
Roles []Role `json:"roles"`
}
type UpdateUserPassword struct {
Password string `json:"password"`
}

View File

@ -1,15 +0,0 @@
package dto
type Login struct {
Username string `json:"username"`
Password string `json:"password"`
}
type UpdatePassword struct {
OldPassword string `json:"old_password"`
NewPassword string `json:"new_password"`
}
type UpdateProfile struct {
Name string `json:"name"`
Phone string `json:"phone"`
Email string `json:"email"`
}

View File

@ -1,47 +0,0 @@
package middleware
import (
"infini.sh/console/internal/biz"
httprouter "infini.sh/framework/core/api/router"
"net/http"
)
func IndexRequired(h httprouter.Handle, route ...string) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
if err != nil {
w = handleError(w, http.StatusUnauthorized, err)
return
}
newRole := biz.CombineUserRoles(claims.Roles)
indexReq := biz.NewIndexRequest(ps, route)
err = biz.ValidateIndex(indexReq, newRole)
if err != nil {
w = handleError(w, http.StatusForbidden, err)
return
}
h(w, r, ps)
}
}
func ClusterRequired(h httprouter.Handle, route ...string) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
if err != nil {
w = handleError(w, http.StatusUnauthorized, err)
return
}
//newRole := biz.CombineUserRoles(claims.Roles)
clusterReq := biz.NewClusterRequest(ps, route)
err = biz.ValidateCluster(clusterReq, claims.Roles)
if err != nil {
w = handleError(w, http.StatusForbidden, err)
return
}
h(w, r, ps)
}
}

View File

@ -1,52 +0,0 @@
package middleware
import (
"infini.sh/console/internal/biz"
httprouter "infini.sh/framework/core/api/router"
"infini.sh/framework/core/util"
"net/http"
)
func LoginRequired(h httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
if err != nil {
w = handleError(w, http.StatusUnauthorized, err)
return
}
r = r.WithContext(biz.NewUserContext(r.Context(), claims))
h(w, r, ps)
}
}
func PermissionRequired(h httprouter.Handle, permissions ...string) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
claims, err := biz.ValidateLogin(r.Header.Get("Authorization"))
if err != nil {
w = handleError(w, http.StatusUnauthorized, err)
return
}
err = biz.ValidatePermission(claims, permissions)
if err != nil {
w = handleError(w, http.StatusForbidden, err)
return
}
r = r.WithContext(biz.NewUserContext(r.Context(), claims))
h(w, r, ps)
}
}
func handleError(w http.ResponseWriter, statusCode int, err error) http.ResponseWriter {
w.Header().Set("Content-type", util.ContentTypeJson)
w.WriteHeader(statusCode)
json := util.ToJson(util.MapStr{
"error": util.MapStr{
"status": statusCode,
"reason": err.Error(),
},
}, true)
w.Write([]byte(json))
return w
}

View File

@ -1,40 +0,0 @@
package rbac
import (
"time"
)
type Role struct {
ID string `json:"id,omitempty" elastic_meta:"_id" elastic_mapping:"id: { type: keyword }"`
Created time.Time `json:"created,omitempty" elastic_mapping:"created: { type: date }"`
Updated time.Time `json:"updated,omitempty" elastic_mapping:"updated: { type: date }"`
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
Type string `json:"type" elastic_mapping:"type: { type: keyword }"`
Description string `json:"description" elastic_mapping:"description: { type: text }"`
Builtin bool `json:"builtin" elastic_mapping:"builtin: { type: boolean }"`
Privilege RolePrivilege `json:"privilege" elastic_mapping:"privilege: { type: object }"`
}
type RolePrivilege struct {
Platform []string `json:"platform,omitempty" elastic_mapping:"platform: { type: keyword }"`
Elasticsearch ElasticsearchPrivilege `json:"elasticsearch,omitempty" elastic_mapping:"elasticsearch: { type: object }"`
}
type ElasticsearchPrivilege struct {
Cluster ClusterPrivilege `json:"cluster,omitempty" elastic_mapping:"cluster: { type: object }"`
Index []IndexPrivilege `json:"index,omitempty" elastic_mapping:"index: { type: object }"`
}
type InnerCluster struct {
ID string `json:"id" elastic_mapping:"id: { type: keyword }"`
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
}
type ClusterPrivilege struct {
Resources []InnerCluster `json:"resources,omitempty" elastic_mapping:"resources: { type: object }"`
Permissions []string `json:"permissions,omitempty" elastic_mapping:"permissions: { type: keyword }"`
}
type IndexPrivilege struct {
Name []string `json:"name,omitempty" elastic_mapping:"name: { type: keyword }"`
Permissions []string `json:"permissions,omitempty" elastic_mapping:"permissions: { type: keyword }"`
}

View File

@ -1,23 +0,0 @@
package rbac
import (
"time"
)
type User struct {
ID string `json:"id,omitempty" elastic_meta:"_id" elastic_mapping:"id: { type: keyword }"`
Created time.Time `json:"created,omitempty" elastic_mapping:"created: { type: date }"`
Updated time.Time `json:"updated,omitempty" elastic_mapping:"updated: { type: date }"`
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
NickName string `json:"nick_name" elastic_mapping:"nick_name: { type: keyword }"`
Password string `json:"password" elastic_mapping:"password: { type: keyword }"`
Email string `json:"email" elastic_mapping:"email: { type: keyword }"`
Phone string `json:"phone" elastic_mapping:"phone: { type: keyword }"`
Tags []string `json:"tags" elastic_mapping:"mobile: { type: keyword }"`
Roles []UserRole `json:"roles" elastic_mapping:"roles: { type: object }"`
}
type UserRole struct {
ID string `json:"id" elastic_mapping:"id: { type: keyword }"`
Name string `json:"name" elastic_mapping:"name: { type: keyword }"`
}

View File

@ -2,7 +2,7 @@ package api
import (
"infini.sh/console/config"
m "infini.sh/console/internal/middleware"
m "infini.sh/framework/core/security/rbac/middleware"
"infini.sh/console/plugin/api/alerting"
"infini.sh/console/plugin/api/index_management"
"infini.sh/framework/core/api"

View File

@ -1,105 +0,0 @@
package rbac
import (
"encoding/json"
"github.com/mitchellh/mapstructure"
"infini.sh/console/internal/biz"
"infini.sh/console/internal/biz/enum"
"infini.sh/console/model/rbac"
"infini.sh/framework/core/api"
"infini.sh/framework/core/elastic"
"infini.sh/framework/core/util"
"os"
"path"
log "github.com/cihub/seelog"
)
type Rbac struct {
api.Handler
}
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...))
}
func loadJsonConfig() {
pwd, _ := os.Getwd()
bytes, err := util.FileGetContent(path.Join(pwd, "/config/permission.json"))
if err != nil {
panic("load json file err " + err.Error())
}
apis := make(map[string][]string)
err = json.Unmarshal(bytes, &apis)
if err != nil {
panic("json config unmarshal err " + err.Error())
}
biz.IndexApis = apis["indices"]
delete(apis, "indices")
biz.ClusterApis = apis
//bytes, err = util.FileGetContent(path.Join(pwd, "/config/map.json"))
//if err != nil {
// panic("load json file err " + err.Error())
//}
//esapiMap := make(map[string]string)
//err = json.Unmarshal(bytes, &esapiMap)
//if err != nil {
// panic("json config unmarshal err " + err.Error())
//}
//for k, v := range esapiMap {
// s := strings.Split(k, "-")
// biz.EsApiRoutes.AddRoute(s[0], s[1], v)
//}
}
func loadRolePermission() {
biz.RoleMap = make(map[string]rbac.Role)
biz.RoleMap["admin"] = rbac.Role{
Privilege: rbac.RolePrivilege{
Platform: enum.AdminPrivilege,
},
}
res, err := biz.SearchRole("", 0, 1000)
if err != nil {
log.Error(err)
return
}
response := elastic.SearchResponse{}
util.FromJSONBytes(res.Raw, &response)
for _, v := range response.Hits.Hits {
var role rbac.Role
delete(v.Source, "created")
delete(v.Source, "updated")
err = mapstructure.Decode(v.Source, &role)
if err != nil {
log.Error(err)
return
}
biz.RoleMap[role.Name] = role
}
}
func Init() {
loadJsonConfig()
loadRolePermission()
}

View File

@ -1,24 +0,0 @@
package rbac
import (
log "github.com/cihub/seelog"
"infini.sh/console/internal/biz"
httprouter "infini.sh/framework/core/api/router"
"net/http"
)
func (h Rbac) ListPermission(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
typ := ps.MustGetParameter("type")
err := biz.IsAllowRoleType(typ)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
var permissions interface{}
if typ == biz.Elasticsearch {
permissions = biz.ListElasticsearchPermission()
}
h.WriteOKJSON(w, permissions)
return
}

View File

@ -1,151 +0,0 @@
package rbac
import (
log "github.com/cihub/seelog"
"infini.sh/console/internal/biz"
"infini.sh/console/internal/biz/enum"
"infini.sh/console/internal/core"
"infini.sh/console/model/rbac"
httprouter "infini.sh/framework/core/api/router"
"infini.sh/framework/core/elastic"
"infini.sh/framework/core/util"
"net/http"
)
func (h Rbac) CreateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
roleType := ps.MustGetParameter("type")
localUser, err := biz.FromUserContext(r.Context())
if err != nil {
log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
err = biz.IsAllowRoleType(roleType)
if err != nil {
h.ErrorInternalServer(w, err.Error())
return
}
role := &rbac.Role{
Type: roleType,
}
err = h.DecodeJSON(r, role)
if err != nil {
h.Error400(w, err.Error())
return
}
var id string
id, err = biz.CreateRole(localUser, role)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.CreateResponse(id))
return
}
func (h Rbac) SearchRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
var (
keyword = h.GetParameterOrDefault(r, "keyword", "")
from = h.GetIntOrDefault(r, "from", 0)
size = h.GetIntOrDefault(r, "size", 20)
)
res, err := biz.SearchRole(keyword, from, size)
if err != nil {
log.Error(err)
h.ErrorInternalServer(w, err.Error())
return
}
response := elastic.SearchResponse{}
util.FromJSONBytes(res.Raw, &response)
hits := response.Hits.Hits
list := make([]elastic.IndexDocument, 0)
total := response.GetTotal()
var index string
for _, v := range hits {
index = v.Index
}
for k, v := range enum.BuildRoles {
list = append(list, elastic.IndexDocument{
ID: k,
Index: index,
Type: "_doc",
Source: v,
})
total++
}
list = append(list, hits...)
response.Hits.Hits = list
response.Hits.Total = total
h.WriteOKJSON(w, response)
return
}
func (h Rbac) GetRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.MustGetParameter("id")
role, err := biz.GetRole(id)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
h.WriteOKJSON(w, core.Response{Hit: role})
return
}
func (h Rbac) DeleteRole(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
}
err = biz.DeleteRole(localUser, id)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.DeleteResponse(id))
return
}
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
//}
role := &rbac.Role{}
err := h.DecodeJSON(r, role)
if err != nil {
h.Error400(w, err.Error())
return
}
role.ID = id
err = biz.UpdateRole(role)
biz.RoleMap[role.Name] = *role
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
return
}

View File

@ -1,192 +0,0 @@
package rbac
import (
"errors"
"infini.sh/console/internal/biz"
"infini.sh/console/internal/core"
"infini.sh/console/internal/dto"
httprouter "infini.sh/framework/core/api/router"
"infini.sh/framework/core/util"
"infini.sh/framework/modules/elastic"
"net/http"
log "src/github.com/cihub/seelog"
)
type CreateUserReq struct {
Username string `json:"username" `
Password string `json:"password" `
Name string `json:"name" `
Phone string `json:"phone" `
Email string `json:"email" `
Tags []string `json:"tags"`
}
func (h Rbac) CreateUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
var req dto.CreateUser
err := h.DecodeJSON(r, &req)
if err != nil {
h.Error400(w, err.Error())
return
}
if req.Name == "" {
h.Error400(w, "username and phone and email is require")
return
}
localUser, err := biz.FromUserContext(r.Context())
if err != nil {
log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
id, pass, err := biz.CreateUser(localUser, req)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, util.MapStr{
"_id": id,
"password": pass,
"result": "created",
})
return
}
func (h Rbac) GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.MustGetParameter("id")
user, err := biz.GetUser(id)
if errors.Is(err, elastic.ErrNotFound) {
h.WriteJSON(w, core.NotFoundResponse(id), http.StatusNotFound)
return
}
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
h.WriteOKJSON(w, core.FoundResponse(id, user))
return
}
func (h Rbac) UpdateUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.MustGetParameter("id")
var req dto.UpdateUser
err := h.DecodeJSON(r, &req)
if err != nil {
_ = log.Error(err.Error())
h.Error400(w, err.Error())
return
}
localUser, err := biz.FromUserContext(r.Context())
if err != nil {
log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
err = biz.UpdateUser(localUser, id, req)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
return
}
func (h Rbac) UpdateUserRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.MustGetParameter("id")
var req dto.UpdateUserRole
err := h.DecodeJSON(r, &req)
if err != nil {
_ = log.Error(err.Error())
h.Error400(w, err.Error())
return
}
localUser, err := biz.FromUserContext(r.Context())
if err != nil {
log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
err = biz.UpdateUserRole(localUser, id, req)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
return
}
func (h Rbac) DeleteUser(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
}
err = biz.DeleteUser(localUser, id)
if errors.Is(err, elastic.ErrNotFound) {
h.WriteJSON(w, core.NotFoundResponse(id), http.StatusNotFound)
return
}
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.DeleteResponse(id))
return
}
func (h Rbac) SearchUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
var (
keyword = h.GetParameterOrDefault(r, "keyword", "")
from = h.GetIntOrDefault(r, "from", 0)
size = h.GetIntOrDefault(r, "size", 20)
)
res, err := biz.SearchUser(keyword, from, size)
if err != nil {
log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
h.Write(w, res.Raw)
return
}
func (h Rbac) UpdateUserPassword(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
id := ps.MustGetParameter("id")
var req dto.UpdateUserPassword
err := h.DecodeJSON(r, &req)
if err != nil {
_ = log.Error(err.Error())
h.Error400(w, err.Error())
return
}
localUser, err := biz.FromUserContext(r.Context())
if err != nil {
log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
err = biz.UpdateUserPassword(localUser, id, req.Password)
if err != nil {
_ = log.Error(err.Error())
h.ErrorInternalServer(w, err.Error())
return
}
_ = h.WriteOKJSON(w, core.UpdateResponse(id))
return
}