342 lines
13 KiB
Java
342 lines
13 KiB
Java
package com.zhgd.xmgl.security;
|
||
|
||
import cn.hutool.core.convert.Convert;
|
||
import cn.hutool.core.util.StrUtil;
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.zhgd.jeecg.common.util.SpringContextUtils;
|
||
import com.zhgd.xmgl.constant.Cts;
|
||
import com.zhgd.xmgl.modules.basicdata.entity.Company;
|
||
import com.zhgd.xmgl.modules.basicdata.entity.SystemUser;
|
||
import com.zhgd.xmgl.modules.basicdata.enums.SystemUserAccountTypeEnum;
|
||
import com.zhgd.xmgl.modules.basicdata.service.ICompanyService;
|
||
import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService;
|
||
import com.zhgd.xmgl.modules.project.service.IProjectService;
|
||
import com.zhgd.xmgl.modules.worker.entity.UserEnterprise;
|
||
import com.zhgd.xmgl.modules.worker.entity.WorkerInfo;
|
||
import com.zhgd.xmgl.modules.worker.service.IUserEnterpriseService;
|
||
import com.zhgd.xmgl.modules.worker.service.IWorkerInfoService;
|
||
import com.zhgd.xmgl.security.entity.UserInfo;
|
||
import com.zhgd.xmgl.security.util.SecurityUtils;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.apache.commons.lang3.StringUtils;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.context.annotation.Lazy;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
import java.io.Serializable;
|
||
import java.lang.reflect.Field;
|
||
import java.lang.reflect.Method;
|
||
import java.util.Objects;
|
||
|
||
@Slf4j
|
||
@Component("perm")
|
||
public class PermissionEvaluator {
|
||
@Lazy
|
||
@Autowired
|
||
private ICompanyService companyService;
|
||
@Lazy
|
||
@Autowired
|
||
private IProjectService projectService;
|
||
@Lazy
|
||
@Autowired
|
||
private ISystemUserService systemUserService;
|
||
@Lazy
|
||
@Autowired
|
||
private IUserEnterpriseService userEnterpriseService;
|
||
@Lazy
|
||
@Autowired
|
||
private IWorkerInfoService workerInfoService;
|
||
|
||
/**
|
||
* 有企业sn的权限
|
||
*
|
||
* @param sn 企业sn
|
||
* @return
|
||
*/
|
||
public boolean hasCompanySnAccess(String sn) {
|
||
UserInfo user = SecurityUtils.getUser();
|
||
if (user.getAccountType().equals(SystemUserAccountTypeEnum.SYSTEM_ADMINISTRATOR.getValue())) {
|
||
return true;
|
||
}
|
||
if (user.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_ADMINISTRATOR_ACCOUNT.getValue())) {
|
||
return companyService.hasCompanySnAccessBy1(user.getUserId(), sn);
|
||
} else if (user.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_DISTRICT_ACCOUNT.getValue())) {
|
||
return companyService.hasCompanySnAccessBy2(user.getUserId(), sn);
|
||
} else if (user.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_CITY_ACCOUNT.getValue())) {
|
||
return companyService.hasCompanySnAccessBy3(user.getUserId(), sn);
|
||
} else if (user.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_SUB_ACCOUNT.getValue())) {
|
||
return companyService.hasCompanySnAccessBy4(user.getUserId(), sn);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 有企业id的权限
|
||
*
|
||
* @param companyId 企业id
|
||
* @return
|
||
*/
|
||
public boolean hasCompanyIdAccess(String companyId) {
|
||
UserInfo user = SecurityUtils.getUser();
|
||
if (user.getAccountType().equals(SystemUserAccountTypeEnum.SYSTEM_ADMINISTRATOR.getValue())) {
|
||
return true;
|
||
}
|
||
Company company = companyService.getById(companyId);
|
||
if (company == null) {
|
||
return false;
|
||
}
|
||
return hasCompanySnAccess(company.getCompanySn());
|
||
}
|
||
|
||
/**
|
||
* 有sn(企业或项目)的权限
|
||
*
|
||
* @param sn 企业或项目sn
|
||
* @return
|
||
*/
|
||
public boolean hasSnAccess(String sn) {
|
||
UserInfo user = SecurityUtils.getUser();
|
||
if (user == null) {
|
||
return false;
|
||
}
|
||
if (user.getAccountType().equals(SystemUserAccountTypeEnum.SYSTEM_ADMINISTRATOR.getValue())) {
|
||
return true;
|
||
}
|
||
int c = companyService.count(new LambdaQueryWrapper<Company>()
|
||
.eq(Company::getCompanySn, sn));
|
||
if (c > 0) {
|
||
return hasCompanySnAccess(sn);
|
||
} else {
|
||
return hasProjectSnAccess(sn);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 有项目sn的权限
|
||
*
|
||
* @param projectSn
|
||
* @return
|
||
*/
|
||
public boolean hasProjectSnAccess(String projectSn) {
|
||
UserInfo owner = SecurityUtils.getUser();
|
||
if (owner.getAccountType().equals(SystemUserAccountTypeEnum.SYSTEM_ADMINISTRATOR.getValue())) {
|
||
return true;
|
||
}
|
||
if (owner.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_ADMINISTRATOR_ACCOUNT.getValue())) {
|
||
return companyService.hasProjectSnAccessBy1(owner.getUserId(), projectSn);
|
||
} else if (owner.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_DISTRICT_ACCOUNT.getValue())) {
|
||
return companyService.hasProjectSnAccessBy2(owner.getUserId(), projectSn);
|
||
} else if (owner.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_CITY_ACCOUNT.getValue())) {
|
||
return companyService.hasProjectSnAccessBy3(owner.getUserId(), projectSn);
|
||
} else if (owner.getAccountType().equals(SystemUserAccountTypeEnum.ENTERPRISE_SUB_ACCOUNT.getValue())) {
|
||
return companyService.hasProjectSnAccessBy4(owner.getUserId(), projectSn);
|
||
} else if (owner.getAccountType().equals(SystemUserAccountTypeEnum.PROJECT_ACCOUNT.getValue())) {
|
||
return projectService.hasProjectSnAccess(owner.getUserId(), projectSn);
|
||
} else if (owner.getAccountType().equals(SystemUserAccountTypeEnum.PROJECT_SUB_ACCOUNT.getValue())) {
|
||
return projectService.hasProjectSnAccess(owner.getUserId(), projectSn);
|
||
} else if (owner.getAccountType().equals(SystemUserAccountTypeEnum.NEW_USER.getValue())) {
|
||
return projectService.hasProjectSnAccessByNewUser(owner.getUserId(), projectSn);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 能访问这个用户id
|
||
*
|
||
* @param userId
|
||
* @return
|
||
*/
|
||
public boolean hasUserAccess(String userId) {
|
||
UserInfo owner = SecurityUtils.getUser();
|
||
if (owner.getAccountType().equals(SystemUserAccountTypeEnum.SYSTEM_ADMINISTRATOR.getValue())) {
|
||
return true;
|
||
}
|
||
SystemUser checkUser = systemUserService.getById(userId);
|
||
Integer checkAccountType = checkUser.getAccountType();
|
||
Integer ownerAccountType = owner.getAccountType();
|
||
if (isCompanyType(checkAccountType)) {
|
||
if (!isCompanyType(ownerAccountType)) {
|
||
return false;
|
||
}
|
||
if (!hasCompanySnAccess(checkUser.getSn())) {
|
||
return false;
|
||
}
|
||
String ownerSn = getSn(owner.getUserId() + "");
|
||
return !Objects.equals(ownerSn, checkUser.getSn());
|
||
} else if (checkAccountType.equals(SystemUserAccountTypeEnum.PROJECT_ACCOUNT.getValue())) {
|
||
if (!hasSnAccess(checkUser.getSn())) {
|
||
return false;
|
||
}
|
||
if (isCompanyType(ownerAccountType)) {
|
||
return true;
|
||
}
|
||
String ownerSn = getSn(owner.getUserId() + "");
|
||
return !Objects.equals(ownerSn, checkUser.getSn());
|
||
} else if (checkAccountType.equals(SystemUserAccountTypeEnum.PROJECT_SUB_ACCOUNT.getValue())) {
|
||
if (!hasSnAccess(checkUser.getSn())) {
|
||
return false;
|
||
}
|
||
if (isCompanyType(ownerAccountType)) {
|
||
return true;
|
||
}
|
||
if (ownerAccountType.equals(SystemUserAccountTypeEnum.PROJECT_ACCOUNT.getValue())
|
||
|| ownerAccountType.equals(SystemUserAccountTypeEnum.NEW_USER.getValue())) {
|
||
return true;
|
||
} else {
|
||
//项目子账号
|
||
UserEnterprise userEnterprise = userEnterpriseService.selectUserEnterpriseByUserId(owner.getUserId());
|
||
WorkerInfo workerInfo = workerInfoService.getOne(new LambdaQueryWrapper<WorkerInfo>()
|
||
.eq(WorkerInfo::getId, checkUser.getWorkerId()).last(Cts.IGNORE_DATA_SCOPE_CONDITION));
|
||
return userEnterprise != null && StrUtil.isNotBlank(userEnterprise.getEnterpriseId())
|
||
&& workerInfo != null && userEnterprise.getEnterpriseId().contains(Convert.toStr(workerInfo.getEnterpriseId()));
|
||
}
|
||
} else if (checkAccountType.equals(SystemUserAccountTypeEnum.NEW_USER.getValue())) {
|
||
if (isProjectType(ownerAccountType) || ownerAccountType.equals(SystemUserAccountTypeEnum.NEW_USER.getValue())) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 获取账号的sn
|
||
*
|
||
* @param userId
|
||
* @return
|
||
*/
|
||
private String getSn(String userId) {
|
||
SystemUser user = systemUserService.getById(userId);
|
||
if (isCompanyType(user.getAccountType())
|
||
|| user.getAccountType().equals(SystemUserAccountTypeEnum.PROJECT_ACCOUNT.getValue())
|
||
|| user.getAccountType().equals(SystemUserAccountTypeEnum.PROJECT_SUB_ACCOUNT.getValue())
|
||
) {
|
||
return user.getSn();
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 是项目级别账号
|
||
*
|
||
* @param accountType
|
||
* @return
|
||
*/
|
||
private boolean isProjectType(Integer accountType) {
|
||
return accountType.equals(SystemUserAccountTypeEnum.PROJECT_ACCOUNT.getValue())
|
||
|| accountType.equals(SystemUserAccountTypeEnum.PROJECT_SUB_ACCOUNT.getValue());
|
||
}
|
||
|
||
/**
|
||
* 是企业级别账号
|
||
*
|
||
* @param accountType
|
||
* @return
|
||
*/
|
||
private boolean isCompanyType(Integer accountType) {
|
||
return accountType.equals(SystemUserAccountTypeEnum.ENTERPRISE_ADMINISTRATOR_ACCOUNT.getValue())
|
||
|| accountType.equals(SystemUserAccountTypeEnum.ENTERPRISE_DISTRICT_ACCOUNT.getValue())
|
||
|| accountType.equals(SystemUserAccountTypeEnum.ENTERPRISE_CITY_ACCOUNT.getValue())
|
||
|| accountType.equals(SystemUserAccountTypeEnum.ENTERPRISE_SUB_ACCOUNT.getValue());
|
||
}
|
||
|
||
|
||
/**
|
||
* 通用ID权限验证方法,id的entityClassName.fieldName查询出sn,通过sn判断是否有权限
|
||
*
|
||
* @param entityClassName 实体类名
|
||
* @param snFieldName sn属性字段名
|
||
* @param id 实体ID值
|
||
* @return 是否有权限
|
||
*/
|
||
public boolean hasIdAccess(String entityClassName, String snFieldName, String id) {
|
||
UserInfo user = SecurityUtils.getUser();
|
||
if (user.getAccountType().equals(SystemUserAccountTypeEnum.SYSTEM_ADMINISTRATOR.getValue())) {
|
||
return true;
|
||
}
|
||
if (StringUtils.isBlank(entityClassName) || StringUtils.isBlank(snFieldName) || id == null) {
|
||
return false;
|
||
}
|
||
|
||
try {
|
||
// 1. 根据实体类名获取对应的实体对象
|
||
Object entity = getEntityById(entityClassName, id);
|
||
if (entity == null) {
|
||
return true;
|
||
}
|
||
|
||
// 2. 通过反射获取指定字段的值
|
||
Object fieldValue = getFieldValue(entity, snFieldName);
|
||
if (fieldValue == null) {
|
||
return false;
|
||
}
|
||
|
||
// 3. 调用hasSnAccess进行权限验证
|
||
return hasSnAccess(fieldValue.toString());
|
||
|
||
} catch (Exception e) {
|
||
log.error("权限验证失败 entity: {}, snFieldName: {}, id: {}", entityClassName, snFieldName, id, e);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 根据实体类名和ID获取实体对象
|
||
*/
|
||
private Object getEntityById(String entityClassName, Serializable id) {
|
||
switch (entityClassName) {
|
||
case "XXX":
|
||
// return organizationJobMapper.selectById(id);
|
||
default:
|
||
// 通用反射方式获取(需要规范命名)
|
||
return getEntityByReflection(entityClassName, id);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 反射方式通用获取实体(需要规范Mapper命名)
|
||
*/
|
||
private Object getEntityByReflection(String entityClassName, Serializable id) {
|
||
try {
|
||
String mapperBeanName = StringUtils.uncapitalize(entityClassName) + "Mapper";
|
||
Object mapper = SpringContextUtils.getBean(mapperBeanName);
|
||
|
||
Method selectByIdMethod = mapper.getClass().getMethod("selectById", Serializable.class);
|
||
return selectByIdMethod.invoke(mapper, id);
|
||
|
||
} catch (Exception e) {
|
||
log.warn("通过反射获取实体失败: {}", entityClassName, e);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通过反射获取字段值
|
||
*/
|
||
private Object getFieldValue(Object entity, String fieldName) {
|
||
try {
|
||
Field field = entity.getClass().getDeclaredField(fieldName);
|
||
field.setAccessible(true);
|
||
return field.get(entity);
|
||
} catch (Exception e) {
|
||
// 尝试通过getter方法获取
|
||
return getFieldValueByGetter(entity, fieldName);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 通过getter方法获取字段值
|
||
*/
|
||
private Object getFieldValueByGetter(Object entity, String fieldName) {
|
||
try {
|
||
String getterMethodName = "get" + StringUtils.capitalize(fieldName);
|
||
Method getterMethod = entity.getClass().getMethod(getterMethodName);
|
||
return getterMethod.invoke(entity);
|
||
} catch (Exception e) {
|
||
log.warn("获取字段值失败: {}", fieldName, e);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
}
|