package model import ( "context" "errors" "icloudapp.cn/tools/service" utString "icloudapp.cn/tools/util/string" url2 "icloudapp.cn/tools/util/url" "net/url" "strings" ) type MRoles struct { ctx context.Context } func NewMRoles(ctx context.Context) *MRoles { return &MRoles{ ctx: ctx, } } func (r *MRoles) Verify(uid int64, URL *url.URL) (bool, error) { if uid == 0 { return false, errors.New("请先登录后再试") } userGroups := service.NewUserGroup(r.ctx).UserGroups(uid) if userGroups == nil { return false, errors.New("无访问组权限") } splitGroups := strings.Split(userGroups.Groups, ",") var groupsID []int64 for _, v := range splitGroups { groupsID = append(groupsID, utString.ConvertInt64(v)) } if len(groupsID) == 0 { return false, errors.New("无访问组权限") } //获取分组对应的权限 groupsField, _ := service.NewGroup(r.ctx).Infos(groupsID...) if groupsField == nil { return false, errors.New("无权限访问") } var rolesID strings.Builder for _, v := range groupsField { if v == nil { continue } rolesID.WriteString(v.Roles + ",") } //获取权限对应的model roles := uniqueToInt64(rolesID.String(), ",") if len(roles) == 0 { return false, errors.New("无权限访问") } mRole := service.NewRoles(r.ctx) modelsField, _ := mRole.Infos(roles...) if modelsField == nil { return false, errors.New("无模块访问权限") } var modelIds strings.Builder for _, v := range modelsField { modelIds.WriteString(v.ModelIds + ",") } //获取对应的model modulesId := uniqueToInt64(modelIds.String(), ",") modules := service.NewModule(r.ctx) moduleField, _ := modules.Infos(modulesId...) if moduleField == nil { return false, errors.New("无模块访问权限") } //验证request是否有权限 matchedURL := make([]string, 0) for _, module := range moduleField { moduleURL := module.ModelURL //设置的url和请求的path一样直接通过,如果是带参数或*需要额外处理 if moduleURL == URL.Path { return true, nil } else if strings.Contains(moduleURL, URL.Path) { matchedURL = append(matchedURL, moduleURL) } else if strings.Contains(moduleURL, ".*") { //如果是以.*结尾的,将modelURL才分成两部分,前半部分能匹配上当前的url就可以 urlSplit := strings.Split(moduleURL, ",") if strings.Contains(URL.String(), urlSplit[0]) { return true, nil } } } if len(matchedURL) == 0 { return false, errors.New("无模块访问权限") } for _, singleURL := range matchedURL { //这里需要区分url中有没有参数,没有参数就直接过,有参数就再验证参数 parseString, _ := url2.ParseString(singleURL) queries := parseString.Query() for name, _ := range queries { if queries.Get(name) != URL.Query().Get(name) { return false, errors.New("权限无匹配") } } } return true, nil } func splitStrToInt64(str, sep string) []int64 { splitSlice := strings.Split(str, sep) var res []int64 for _, v := range splitSlice { res = append(res, utString.ConvertInt64(v)) } return res } func uniqueToInt64(str, sep string) []int64 { var res []int64 splitSlice := splitStrToInt64(str, sep) splitMap := make(map[int64]bool, 0) for _, v := range splitSlice { if v == 0 { continue } if _, ok := splitMap[v]; ok { continue } splitMap[v] = true res = append(res, v) } return res }