package service import ( "errors" "fmt" casbin "github.com/casbin/casbin/v2" "github.com/casbin/casbin/v2/model" gormadapter "github.com/casbin/gorm-adapter/v3" "gorm.io/gorm" ) type ( Auth struct { enforcer *casbin.Enforcer } // Permission 权限信息 Permission struct { Identity *Identity // 身份信息 Roles []string // 角色 Request []*AuthRequest } // Identity 身份信息 Identity struct { Tenant string // 平台-小区 User string // 用户唯一标识 } AuthRequest struct { Url string Method string } IdentityPermission func(tenant, user string) *Permission ) var auth *Auth // adapter 规则 var adapter = map[string]func(params ...interface{}) interface{}{ "mysql": adapterForOrm, "sqlite": adapterForOrm, } // adapterForOrm func adapterForOrm(params ...interface{}) interface{} { db := params[0].(*gorm.DB) obj := params[1].(string) adapter, _ := gormadapter.NewAdapterByDBUseTableName(db, "", obj) return adapter } // Register 注册权限 // 多平台 admin tenant1, data1, read (角色-域-用户-事件) // p admin tenant1, data1, read (角色-域-用户-事件) // g alice, admin, tenant1 (用户-角色-域) func (this *Auth) Register() func(mode string, params ...interface{}) interface{} { return func(mode string, params ...interface{}) interface{} { m := model.NewModel() m.AddDef("r", "r", "sub, dom, obj, act") m.AddDef("p", "p", "sub, dom, obj, act") m.AddDef("g", "g", "_, _, _") m.AddDef("e", "e", "some(where (p.eft == allow))") m.AddDef("m", "m", "g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act") a, has := adapter[mode] if has { this.enforcer, _ = casbin.NewEnforcer(m, a(params...)) this.enforcer.EnableAutoSave(true) } else { this.enforcer, _ = casbin.NewEnforcer(m) } auth = this return nil } } // tenantIdentity 平台租户信息 func (this *Identity) tenantIdentity() string { return fmt.Sprintf("%s%s", "t_", this.Tenant) } // userIdentity 用户身份信息 func (this *Identity) userIdentity() string { return fmt.Sprintf("%s%s", "u_", this.User) } // roleIdentity 角色身份信息 func (this *Permission) roleIdentity() []string { roles := make([]string, 0) for _, v := range this.Roles { roles = append(roles, fmt.Sprintf("%s%s", "r_", v)) } return roles } // AddRoleForUser 增加用户角色 func (this *Permission) AddRoleForUser() (bool, error) { if this.Roles == nil || len(this.Roles) <= 0 { return false, errors.New("无角色信息") } for _, role := range this.roleIdentity() { if _, err := auth.enforcer.AddRoleForUser(this.Identity.userIdentity(), role, this.Identity.tenantIdentity()); err != nil { return false, err } } return true, nil } // DeleteRoleForUser 删除用户角色 //func (this *Permission) DeleteRoleForUser() (bool, error) { // if this.Roles == nil || len(this.Roles) <= 0 { // return false, errors.New("角色信息不存在") // } // for _, role := range this.roleIdentity() { // status, err := auth.enforcer.DeleteRoleForUser(this.Identity.userIdentity(), role, this.Identity.tenantIdentity()) // if err != nil { // return false, err // } else if !status { // return false, errors.New("删除失败") // } // } // return true, nil //} // DeleteRolesForUser 删除用户所有角色 func (this *Permission) DeleteRolesForUser(allTenant bool) (bool, error) { if allTenant { return auth.enforcer.DeleteRolesForUser(this.Identity.userIdentity()) } return auth.enforcer.DeleteRolesForUser(this.Identity.userIdentity(), this.Identity.tenantIdentity()) } //// AddPolicy 增加规则 //func (this *Permission) AddPolicy() (bool, error) { // if this.Request == nil || len(this.Request) <= 0 { // return false, errors.New("请求事件错误") // } // return auth.enforcer.AddPolicy(this.roleIdentity()[0], this.Identity.tenantIdentity(), this.Request[0].Url, this.Request[0].Method) //} // AddPolicies TODO:增加多个规则 func (this *Permission) AddPolicies() (bool, error) { if this.Request == nil || len(this.Request) <= 0 { return false, errors.New("请求事件错误") } rules := make([][]string, 0) for _, s := range this.Request { rules = append(rules, []string{ this.roleIdentity()[0], this.Identity.tenantIdentity(), s.Url, s.Method, }) } return auth.enforcer.AddPolicies(rules) } //// RemovePolicy TODO:删除规则 //func (this *Permission) RemovePolicy() (bool, error) { // if this.Request == nil || len(this.Request) <= 0 { // return false, errors.New("请求事件错误") // } // return auth.enforcer.RemovePolicy(this.roleIdentity()[0], this.Identity.tenantIdentity(), this.Request[0].Url, this.Request[0].Method) //} // //// RemovePolicies 删除多个规则 //func (this *Permission) RemovePolicies() (bool, error) { // rules := make([][]string, 0) // // for _, s := range this.Request { // rules = append(rules, []string{ // this.roleIdentity()[0], this.Identity.tenantIdentity(), s.Url, s.Method, // }) // } // return auth.enforcer.RemovePolicies(rules) //} // RemoveRolePolicy 删除角色的所有规则 func (this *Permission) RemoveRolePolicy() (bool, error) { if this.Roles == nil || len(this.Roles) <= 0 { return false, errors.New("角色信息不存在") } return auth.enforcer.RemoveFilteredPolicy(0, this.roleIdentity()[0], this.Identity.tenantIdentity()) } // RemoveNamedGroupingPolicies 删除租户下角色的权限 func (this *Permission) RemoveNamedGroupingPolicies() (bool, error) { rules := make([][]string, 0) roles := this.roleIdentity() for _, role := range roles { rule := make([]string, 0) for _, request := range this.Request { rule = append(rule, role, this.Identity.tenantIdentity(), request.Url, request.Method) } rules = append(rules, rule) } return auth.enforcer.RemoveNamedGroupingPolicies("g", rules) } // RemoveFilteredGroupingPolicy 删除组权限规则 func (this *Permission) RemoveFilteredGroupingPolicy() (bool, error) { return auth.enforcer.RemoveFilteredGroupingPolicy(0, this.Identity.tenantIdentity()) } // HasPolicy 检查访问权限 func (this *Permission) Enforce() (bool, error) { if this.Request == nil || len(this.Request) <= 0 { return false, errors.New("请求事件错误") } return auth.enforcer.Enforce(this.Identity.userIdentity(), this.Identity.tenantIdentity(), this.Request[0].Url, "*") } // NewAuth func NewAuth() *Auth { return &Auth{} } // NewPermission func NewPermission(roles []string, act ...*AuthRequest) IdentityPermission { return func(tenant, user string) *Permission { return &Permission{ Identity: &Identity{ Tenant: tenant, User: user, }, Roles: roles, Request: act, } } }