package utils import ( "errors" "spaceofcheng/services/models/model" "strings" ) // 系统内置数据种类 const ( DATATYPE_USER = "user" DATATYPE_CASE = "case" DATATYPE_COURSE = "course" DATATYPE_COUPON = "coupon" DATATYPE_CARD = "card" ) // DataAuthEngine 鉴权数据 type DataAuthEngine struct { ctx *Context } // NewAuthEngine 生成新实例 func NewAuthEngine(ctx *Context) *DataAuthEngine { return &DataAuthEngine{ctx: ctx} } // CheckCase 校验案场数据权限 func (t *DataAuthEngine) CheckCase(caseID string) error { cases := t.ctx.Get("cases") if cases == nil { return errors.New("请授权用户案场权限") } found := false userCases := cases.([]model.SysUserCase) for _, cs := range userCases { if caseID == cs.CaseId { found = true } } if !found { return errors.New("用户无该案场数据权限") } return nil } // AuthFilter 按权限过滤 func (t *DataAuthEngine) AuthFilter(targ interface{}, sql string, params ...interface{}) error { if t.ctx == nil { return errors.New("未指定上下文环境") } // 用户所属案场 casesRaw := t.ctx.Get("cases") if casesRaw == nil { return errors.New("用户无权限操作该数据") } cases := casesRaw.([]model.SysUserCase) csIDs := make([]string, 0) for _, cs := range cases { csIDs = append(csIDs, cs.CaseId) } newSQL := "select * from (" + sql + ") where case_id in ('" + strings.Join(csIDs, "','") + "')" if err := t.ctx.DB.SQL(newSQL, params...).Find(targ); err != nil { LogError("按权限查询数据失败: " + err.Error()) return errors.New("数据查询失败") } return nil } // HasUserPermission 是否有人员权限 func (t *DataAuthEngine) HasUserPermission(userID, borrower string, caseID ...string) error { // 1、先判断组织是否相同 userOrg, err := t.getOrgOfData(userID, DATATYPE_USER) if err != nil { LogError("查询用户(" + userID + ") 所属组织失败: " + err.Error()) return errors.New("查询用户相关信息失败") } borwOrg, err := t.getOrgOfData(borrower, DATATYPE_USER) if err != nil { LogError("查询用户(" + borrower + ") 所属组织失败: " + err.Error()) return errors.New("查询用户相关信息失败") } if userOrg != borwOrg { return errors.New("人员不存在或无权浏览") } // 2、再判断是否案场相同 sameCases, err := t.getSameCase(userID, borrower) if err != nil { return errors.New("用户没有相同案场授权") } // 3、是否指定了案场 if len(caseID) > 0 { if StrSliceIndexOf(sameCases, caseID[0]) < 0 { return errors.New("用户没有当前案场权限") } } return nil } func (t *DataAuthEngine) getOrgOfData(dataID, dataType string) (string, error) { org := make(map[string]interface{}) switch dataType { // 用户 case DATATYPE_USER: if _, err := t.ctx.DB.SQL("select org_id from sys_user where user_id = ?", dataID).Get(&org); err != nil { return "", err } orgID := org["org_id"].(string) return orgID, nil // 案场 case DATATYPE_CASE: if _, err := t.ctx.DB.SQL("select org_id from sys_case where case_id = ?", dataID).Get(&org); err != nil { return "", err } orgID := org["org_id"].(string) return orgID, nil default: return "", nil } } func (t *DataAuthEngine) getSameCase(user1, user2 string) ([]string, error) { sql := ` SELECT t.case_id FROM sys_user_case t JOIN sys_user_case s ON t.user_id = ? AND s.user_id = ? AND t.case_id = s.case_id ` res, err := t.ctx.DB.Query(sql, user1, user2) if err != nil { LogError("查询用户相同案场失败: " + err.Error()) return nil, err } if res == nil || len(res) == 0 { return nil, errors.New("用户没有相同案场授权") } csIDs := make([]string, 0) for _, cs := range res { csIDs = append(csIDs, string(cs["case_id"])) } return csIDs, nil }