| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 | package iiimport (	"os"	"path/filepath"	"golib/features/mo")// Perms 权限, 由每个键值组成.// 示例: "PERM.OWN": [{"creator": "SIMANC"}],type Perms map[string]mo.A// Has 是否包含 perm 权限func (p Perms) Has(s string) bool {	_, ok := p[s]	return ok}func (p Perms) HasAll(s []string) bool {	if len(s) == 0 {		return false	}	for _, sp := range s {		if _, ok := p[sp]; !ok {			return false		}	}	return true}// Get 获取权限func (p Perms) Get(s string, u User) (mo.D, bool) {	cond, ok := p[s]	if !ok {		return nil, false	}	// 如果存在该权限, 但权限配置为空, 则表示拥有所有权限	if len(cond) == 0 {		return nil, true	}	con := make(mo.D, 0, len(cond))	for _, doc := range cond {		ele, o := doc.(mo.D)		if !o {			panic("element must be type mo.D")		}		for i, e := range ele {			switch e.Value {			case "$id":				ele[i] = mo.E{Key: e.Key, Value: u.ID()}			case "$name":				ele[i] = mo.E{Key: e.Key, Value: u.Name()}			case "$username":				ele[i] = mo.E{Key: e.Key, Value: u.UserName()}			case "$company":				ele[i] = mo.E{Key: e.Key, Value: u.Company()}			}		}		con = append(con, ele...)	}	return con, true}func (p Perms) GetAll(s []string, u User) (mo.D, bool) {	if len(s) == 0 {		return nil, false	}	perm := make(mo.D, 0, len(s))	for _, sp := range s {		cond, ok := p.Get(sp, u)		if !ok {			return nil, false		}		perm = append(perm, cond...)	}	return perm, true}// Group 用户组// 用户组包含用户组名称和该名称下用户角色和权限的对应关系type Group map[string]map[string][]string// Has 是否在用户组内// name 为用户组名称, role 为用户组内的角色// 若需要 Has 返回 true, 则用户首先应在当前用户组内, 其次 user.role 需要有对应当前用户组的角色且 group 内也有对应的角色权限控制////		 {//		  "groupName": {//		    "manager": [],    // role//		    "user": []        // role//	     "...": []         // role//		  }//		}func (g Group) Has(name, role string) bool {	group, ok := g[name]	if !ok {		return false	}	_, ok = group[role]	return ok}// Get 获取用户组对应角色下的权限// 返回的结果应当在 Perms 内转换为条件func (g Group) Get(name, role string) ([]string, bool) {	group, ok := g[name]	if !ok {		return nil, false	}	cond, ok := group[role]	if !ok {		return nil, false	}	return cond, len(cond) > 0}// Role 角色type Role []string// Has 是否包含角色 sfunc (r Role) Has(s string) bool {	for _, role := range r {		if role == s {			return true		}	}	return false}type DbPerms struct {	Group      string   `json:"group"`      // 所属用户组	OtherPerms []string `json:"otherPerms"` // 用户组之外的用户使用此权限查询}// Database 数据库表的权限type Database map[Name]DbPerms// Has 查询 name 是否在 group 用户组中func (d Database) Has(name Name, group string) bool {	db, ok := d[name]	if !ok {		// 未找到此数据库表		return false	}	return db.Group == group}// GetGroup 获取数据库表所需要的用户组func (d Database) GetGroup(name Name) string {	db, ok := d[name]	if !ok {		// 未找到此数据库表		return ""	}	return db.Group}func (d Database) GetOtherPerms(name Name) []string {	db, ok := d[name]	if !ok {		return nil	}	return db.OtherPerms}type Permission interface {	Has(name Name, u User) (mo.D, bool)}type PermsConfig struct {	Perms    Perms    `json:"perms"`	Group    Group    `json:"group"`	Role     Role     `json:"role"`	Database Database `json:"database"`}func (p *PermsConfig) Has(name Name, u User) (mo.D, bool) {	if u.IsSysadmin() {		return nil, true	}	// 查询数据库表所需要的用户组	group := p.Database.GetGroup(name)	// 如果用户不在数据库表要求的用户组时	if !u.Group(group) {		// 检查数据库是否允许 other 访问, 当 other 的权限数量 > 0 时表示有权限访问, 否则表示无权限		return p.Perms.GetAll(p.Database.GetOtherPerms(name), u)	}	// 如果用户在数据库表要求的用户组	// 获取用户在当前用户组的角色	role, ok := u.Role(group)	// 如果该用户没有当前用户组的角色时	if !ok {		// 检查数据库是否允许 other 访问, 当 other 的权限数量 > 0 时表示有权限访问, 否则表示无权限		return p.Perms.GetAll(p.Database.GetOtherPerms(name), u)	}	// 若用户在当前用户组的角色无效时	if !p.Role.Has(role) {		// 检查数据库是否允许 other 访问, 当 other 的权限数量 > 0 时表示有权限访问, 否则表示无权限		return p.Perms.GetAll(p.Database.GetOtherPerms(name), u)	}	// 检查用户是否有自定义该用户组角色的权限	perms, ok := u.Perms(group)	if ok {		// 如果用户的角色未在用户组配置时		if !p.Group.Has(group, role) {			// 检查数据库是否允许 other 访问, 当 other 的权限数量 > 0 时表示有权限访问, 否则表示无权限			return p.Perms.GetAll(p.Database.GetOtherPerms(name), u)		}	} else {		// 获取用户组包含的权限		perms, ok = p.Group.Get(group, role)		// 如果当前用户组内没有包含当前用户角色的权限		if !ok {			// 检查数据库是否允许 other 访问, 当 other 的权限数量 > 0 时表示有权限访问, 否则表示无权限			return p.Perms.GetAll(p.Database.GetOtherPerms(name), u)		}	}	// 当用户组所需要的权限在权限列表中全部匹配时表示有权限访问	return p.Perms.GetAll(perms, u)}func LoadPerms(name string) (Permission, error) {	b, err := os.ReadFile(filepath.Join(name))	if err != nil {		return nil, err	}	var perms PermsConfig	if err = mo.UnmarshalExtJSON(b, true, &perms); err != nil {		return nil, err	}	return &perms, err}
 |