sync: 同步 v1.0.4 并脱敏配置与镜像

This commit is contained in:
MiFaZhan
2026-10-29 14:36:49 +08:00
parent 743e8e6e6e
commit 2206a393f7
516 changed files with 18119 additions and 2253 deletions
+88 -35
View File
@@ -2,19 +2,16 @@ package rolepolicy
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity"
"github.com/gogf/gf/v2/errors/gerror"
"strconv"
"strings"
)
const TemplateConfigKey = "agent.role.template.role_id"
// TemplateForRoles reports whether any of roleIDs is the configured platform template.
// Callers use it to tell "this save touches the template" apart from "this save is an
// ordinary role" — the latter must not be forced to is_pass=1.
func TemplateForRoles(ctx context.Context, roleIDs ...int64) (*entity.SysRole, error) {
var configs []*entity.SysConfig
if err := dao.SysConfig.Ctx(ctx).Master().Where("tenant_id", consts.DefaultSystemTenantCode).Where("config_key", TemplateConfigKey).Scan(&configs); err != nil {
@@ -47,7 +44,7 @@ func TemplateForRoles(ctx context.Context, roleIDs ...int64) (*entity.SysRole, e
func Template(ctx context.Context) (*entity.SysRole, error) {
var configs []*entity.SysConfig
if err := dao.SysConfig.Ctx(ctx).Where("tenant_id", consts.DefaultSystemTenantCode).Where("config_key", TemplateConfigKey).Scan(&configs); err != nil {
if err := dao.SysConfig.Ctx(ctx).Master().Where("tenant_id", consts.DefaultSystemTenantCode).Where("config_key", TemplateConfigKey).Scan(&configs); err != nil {
return nil, err
}
if len(configs) == 0 {
@@ -65,23 +62,23 @@ func ValidateTemplate(ctx context.Context, value string) (*entity.SysRole, error
return nil, gerror.New("代理模板参数必须填写非超级管理员的有效角色ID")
}
var role *entity.SysRole
if err = dao.SysRole.Ctx(ctx).Where("role_id", roleID).Where("tenant_id", consts.DefaultSystemTenantCode).Scan(&role); err != nil {
if err = dao.SysRole.Ctx(ctx).Master().Where("role_id", roleID).Where("tenant_id", consts.DefaultSystemTenantCode).Scan(&role); err != nil {
return nil, err
}
if role == nil || role.Status != "0" || (role.CreatedDept > 0 && role.CreatedDept != role.DeptId) || role.DeptId <= 0 || role.IsPass != 1 {
return nil, gerror.New("请在企业管理的角色管理创建下发模板,模板须正常启用、绑定本级机构且非上级继承角色")
if role == nil || role.Status != "0" || (role.CreatedDept > 0 && role.CreatedDept != role.DeptId) || role.DeptId <= 0 {
return nil, gerror.New("代理模板参数对应角色须正常启用、绑定本级机构且非上级继承角色")
}
if role.DataScope != consts.SysRoleDataScopeDeptAndBelow {
return nil, gerror.New("代理模板数据范围必须为本机构及下级")
}
var dept *entity.SysDept
if err := dao.SysDept.Ctx(ctx).Where("tenant_id", role.TenantId).Where("dept_id", role.DeptId).Where("status", "0").Scan(&dept); err != nil {
if err := dao.SysDept.Ctx(ctx).Master().Where("tenant_id", role.TenantId).Where("dept_id", role.DeptId).Where("status", "0").Scan(&dept); err != nil {
return nil, err
}
if dept == nil {
return nil, gerror.New("代理模板所属机构不存在或已停用")
}
invalidScopes, err := dao.SysRoleMenu.Ctx(ctx).Where("tenant_id", role.TenantId).Where("role_id", role.RoleId).WhereIn("data_scope", []string{consts.SysRoleDataScopeAll, consts.SysRoleDataScopeCustom}).Count()
invalidScopes, err := dao.SysRoleMenu.Ctx(ctx).Master().Where("tenant_id", role.TenantId).Where("role_id", role.RoleId).WhereIn("data_scope", []string{consts.SysRoleDataScopeAll, consts.SysRoleDataScopeCustom}).Count()
if err != nil {
return nil, err
}
@@ -93,7 +90,7 @@ func ValidateTemplate(ctx context.Context, value string) (*entity.SysRole, error
func MenuIDs(ctx context.Context, roleID int64) ([]int64, error) {
var menus []*entity.SysRoleMenu
if err := dao.SysRoleMenu.Ctx(ctx).Where("role_id", roleID).Scan(&menus); err != nil {
if err := dao.SysRoleMenu.Ctx(ctx).Master().Where("role_id", roleID).Scan(&menus); err != nil {
return nil, err
}
ids := make([]int64, 0, len(menus))
@@ -122,19 +119,22 @@ func CurrentSuperAdmin(ctx context.Context, userID int64) (bool, error) {
return false, nil
}
var relations []*entity.SysUserRole
if err := dao.SysUserRole.Ctx(ctx).Where("tenant_id", consts.DefaultSystemTenantCode).Where("user_id", userID).Where("role_id", consts.SuperAdminRoleId).Scan(&relations); err != nil {
if err := dao.SysUserRole.Ctx(ctx).Master().Where("tenant_id", consts.DefaultSystemTenantCode).Where("user_id", userID).Where("role_id", consts.SuperAdminRoleId).Scan(&relations); err != nil {
return false, err
}
if len(relations) == 0 {
return false, nil
}
var role *entity.SysRole
if err := dao.SysRole.Ctx(ctx).Where("tenant_id", consts.DefaultSystemTenantCode).Where("role_id", consts.SuperAdminRoleId).Where("status", "0").Scan(&role); err != nil {
if err := dao.SysRole.Ctx(ctx).Master().Where("tenant_id", consts.DefaultSystemTenantCode).Where("role_id", consts.SuperAdminRoleId).Where("status", "0").Scan(&role); err != nil {
return false, err
}
return role != nil, nil
}
// RestrictMenus validates organization membership and role bindings. Templates are
// overwrite sources, not runtime permission ceilings: platform role edits must
// remain effective until the next explicit template distribution.
func RestrictMenus(ctx context.Context, tenantID string, deptID int64, ids []int64) ([]int64, error) {
template, err := Template(ctx)
if err != nil {
@@ -150,35 +150,27 @@ func RestrictMenus(ctx context.Context, tenantID string, deptID int64, ids []int
}
seen[deptID] = true
var dept *entity.SysDept
if err := dao.SysDept.Ctx(ctx).Where("tenant_id", tenantID).Where("dept_id", deptID).Scan(&dept); err != nil {
if err := dao.SysDept.Ctx(ctx).Master().Where("tenant_id", tenantID).Where("dept_id", deptID).Scan(&dept); err != nil {
return nil, err
}
if dept == nil || dept.Status != "0" {
return []int64{}, nil
}
if template != nil && tenantID == template.TenantId && deptID == template.DeptId {
if len(seen) > 1 {
menus, err := MenuIDs(ctx, template.RoleId)
if err != nil {
return nil, err
}
ids = Intersect(ids, menus)
}
if tenantID == template.TenantId && deptID == template.DeptId {
break
}
if dept.DeptRole != consts.SuperAdminRoleId {
var role *entity.SysRole
if err := dao.SysRole.Ctx(ctx).Where("tenant_id", tenantID).Where("dept_id", deptID).Where("role_id", dept.DeptRole).Where("status", "0").Scan(&role); err != nil {
return nil, err
}
if role == nil {
return []int64{}, nil
}
menus, err := MenuIDs(ctx, role.RoleId)
if err != nil {
return nil, err
}
ids = Intersect(ids, menus)
if dept.DeptRole == consts.SuperAdminRoleId {
return nil, gerror.Newf("机构%d不能使用超级管理员角色作为代理权限上限,请核对机构角色绑定", dept.DeptId)
}
if dept.DeptRole <= 0 {
return nil, gerror.Newf("机构%d未关联默认角色,请联系平台管理员核对机构角色绑定", dept.DeptId)
}
var role *entity.SysRole
if err := dao.SysRole.Ctx(ctx).Master().Where("tenant_id", tenantID).Where("dept_id", deptID).Where("role_id", dept.DeptRole).Where("status", "0").Scan(&role); err != nil {
return nil, err
}
if role == nil {
return nil, gerror.Newf("机构%d默认角色不存在、已停用或归属不匹配,请联系平台管理员核对", dept.DeptId)
}
deptID = dept.ParentId
}
@@ -187,3 +179,64 @@ func RestrictMenus(ctx context.Context, tenantID string, deptID int64, ids []int
}
return ids, nil
}
func RestrictAssignableMenus(ctx context.Context, tenantID string, deptID, userID int64, ids []int64) ([]int64, error) {
allowed, err := RestrictMenus(ctx, tenantID, deptID, ids)
if err != nil {
return nil, err
}
// Local administrators can delegate only their organization's current default
// role permissions and their own active permissions. Ancestor/template menus
// do not cap a platform-authorized individual expansion.
template, err := Template(ctx)
if err != nil {
return nil, err
}
if template != nil && (tenantID != template.TenantId || deptID != template.DeptId) {
var dept *entity.SysDept
if err := dao.SysDept.Ctx(ctx).Master().Where("tenant_id", tenantID).Where("dept_id", deptID).Scan(&dept); err != nil {
return nil, err
}
if dept == nil {
return []int64{}, nil
}
menus, err := MenuIDs(ctx, dept.DeptRole)
if err != nil {
return nil, err
}
allowed = Intersect(allowed, menus)
}
var relations []*entity.SysUserRole
if err := dao.SysUserRole.Ctx(ctx).Master().Where("tenant_id", tenantID).Where("user_id", userID).Scan(&relations); err != nil {
return nil, err
}
roleIDs := make([]int64, 0, len(relations))
for _, relation := range relations {
if relation.RoleId != consts.SuperAdminRoleId {
roleIDs = append(roleIDs, relation.RoleId)
}
}
if len(roleIDs) == 0 {
return []int64{}, nil
}
var roles []*entity.SysRole
if err := dao.SysRole.Ctx(ctx).Master().Where("tenant_id", tenantID).WhereIn("role_id", roleIDs).Where("status", "0").Scan(&roles); err != nil {
return nil, err
}
roleIDs = roleIDs[:0]
for _, role := range roles {
roleIDs = append(roleIDs, role.RoleId)
}
if len(roleIDs) == 0 {
return []int64{}, nil
}
var menus []*entity.SysRoleMenu
if err := dao.SysRoleMenu.Ctx(ctx).Master().Where("tenant_id", tenantID).WhereIn("role_id", roleIDs).Scan(&menus); err != nil {
return nil, err
}
owned := make([]int64, 0, len(menus))
for _, menu := range menus {
owned = append(owned, menu.MenuId)
}
return Intersect(allowed, owned), nil
}