|
|
@ -9,13 +9,16 @@ import com.inspect.base.core.utils.StringUtils; |
|
|
import com.inspect.base.redis.service.RedisService; |
|
|
import com.inspect.base.redis.service.RedisService; |
|
|
import com.inspect.common.security.utils.SecurityUtils; |
|
|
import com.inspect.common.security.utils.SecurityUtils; |
|
|
import com.inspect.system.base.domain.SysDept; |
|
|
import com.inspect.system.base.domain.SysDept; |
|
|
|
|
|
import com.inspect.system.base.domain.SysRole; |
|
|
import com.inspect.system.base.domain.SysUser; |
|
|
import com.inspect.system.base.domain.SysUser; |
|
|
import com.inspect.system.client.ExtAuthClient; |
|
|
import com.inspect.system.client.ExtAuthClient; |
|
|
import com.inspect.system.domain.ExtSyncResult; |
|
|
import com.inspect.system.domain.ExtSyncResult; |
|
|
import com.inspect.system.domain.ext.ExtDept; |
|
|
import com.inspect.system.domain.ext.ExtDept; |
|
|
import com.inspect.system.domain.ext.ExtDeptRef; |
|
|
import com.inspect.system.domain.ext.ExtDeptRef; |
|
|
|
|
|
import com.inspect.system.domain.ext.ExtRole; |
|
|
import com.inspect.system.domain.ext.ExtUser; |
|
|
import com.inspect.system.domain.ext.ExtUser; |
|
|
import com.inspect.system.domain.ext.ExtUserRef; |
|
|
import com.inspect.system.domain.ext.ExtUserRef; |
|
|
|
|
|
import com.inspect.system.domain.ext.RoleSyncResult; |
|
|
import com.inspect.system.mapper.ExtOrgSyncMapper; |
|
|
import com.inspect.system.mapper.ExtOrgSyncMapper; |
|
|
import com.inspect.system.service.IExtOrgSyncService; |
|
|
import com.inspect.system.service.IExtOrgSyncService; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
@ -58,6 +61,11 @@ public class ExtOrgSyncServiceImpl implements IExtOrgSyncService { |
|
|
/** 同步用户默认角色:普通角色,可由 yanyuan.sync.default-role-key 覆盖(部分库为 common1) */ |
|
|
/** 同步用户默认角色:普通角色,可由 yanyuan.sync.default-role-key 覆盖(部分库为 common1) */ |
|
|
@Value("${yanyuan.sync.default-role-key:common}") |
|
|
@Value("${yanyuan.sync.default-role-key:common}") |
|
|
private String defaultRoleKey; |
|
|
private String defaultRoleKey; |
|
|
|
|
|
|
|
|
|
|
|
/** 仅同步以该前缀开头的外部角色名 */ |
|
|
|
|
|
@Value("${yanyuan.sync.role-name-prefix:动环}") |
|
|
|
|
|
private String roleNamePrefix; |
|
|
|
|
|
|
|
|
private static final String LOCK_KEY = "ext:org:sync:lock"; |
|
|
private static final String LOCK_KEY = "ext:org:sync:lock"; |
|
|
private static final String ENSURE_LOCK_PREFIX = "ext:user:ensure:"; |
|
|
private static final String ENSURE_LOCK_PREFIX = "ext:user:ensure:"; |
|
|
private static final long ENSURE_LOCK_SECONDS = 30L; |
|
|
private static final long ENSURE_LOCK_SECONDS = 30L; |
|
|
@ -309,6 +317,90 @@ public class ExtOrgSyncServiceImpl implements IExtOrgSyncService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 登录时同步外部角色:只处理以配置前缀(默认动环)开头的外部角色名, |
|
|
|
|
|
* 与本地 role_name 精确匹配后授权;回收范围同样限定为动环前缀角色。 |
|
|
|
|
|
*/ |
|
|
|
|
|
@Override |
|
|
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
|
|
public RoleSyncResult syncUserRoles(String username) { |
|
|
|
|
|
if (StringUtils.isEmpty(username)) { |
|
|
|
|
|
throw new ServiceException("用户名不能为空", ExtAuthConstants.TOKEN_INVALID); |
|
|
|
|
|
} |
|
|
|
|
|
RoleSyncResult result = new RoleSyncResult(); |
|
|
|
|
|
result.setUsername(username); |
|
|
|
|
|
|
|
|
|
|
|
SysUser user = extOrgSyncMapper.selectUserByUserName(username); |
|
|
|
|
|
if (user == null || !"0".equals(user.getDelFlag())) { |
|
|
|
|
|
throw new ServiceException("本地用户[" + username + "]不存在或已删除", |
|
|
|
|
|
ExtAuthConstants.TOKEN_INVALID); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils.isEmpty(roleNamePrefix)) { |
|
|
|
|
|
log.info("[EXT-ROLE] 未配置角色名前缀,跳过角色同步, username={}", username); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Response<List<ExtRole>> response = extAuthClient.getRoleByUser(username, SOURCE); |
|
|
|
|
|
if (response == null || response.getCode() != Response.SUCCESS || response.getData() == null) { |
|
|
|
|
|
throw new ServiceException("获取外部角色失败", ExtAuthConstants.SERVICE_UNAVAILABLE); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Map<Long, String> desired = new LinkedHashMap<>(); |
|
|
|
|
|
for (ExtRole extRole : response.getData()) { |
|
|
|
|
|
String roleName = StringUtils.trim(extRole.getRoleName()); |
|
|
|
|
|
if (StringUtils.isEmpty(roleName)) { |
|
|
|
|
|
result.getSkipped().add("外部角色名为空"); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
if (!roleName.startsWith(roleNamePrefix)) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
SysRole localRole = extOrgSyncMapper.selectRoleByName(roleName); |
|
|
|
|
|
if (localRole == null) { |
|
|
|
|
|
result.getSkipped().add(roleName + "(本地角色不存在)"); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
if (!"0".equals(localRole.getStatus())) { |
|
|
|
|
|
result.getSkipped().add(roleName + "(本地角色已停用)"); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
desired.put(localRole.getRoleId(), roleName); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Long commonRoleId = extOrgSyncMapper.selectRoleIdByRoleKey(defaultRoleKey); |
|
|
|
|
|
Set<Long> currentIds = new HashSet<>(); |
|
|
|
|
|
for (SysRole current : extOrgSyncMapper.selectRolesByUserId(user.getUserId())) { |
|
|
|
|
|
currentIds.add(current.getRoleId()); |
|
|
|
|
|
if (commonRoleId != null && commonRoleId.equals(current.getRoleId())) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
String currentName = current.getRoleName(); |
|
|
|
|
|
// 只回收动环前缀角色;非动环角色视为管理员手工授权,不参与对账 |
|
|
|
|
|
if (StringUtils.isEmpty(currentName) || !currentName.startsWith(roleNamePrefix)) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
if (!desired.containsKey(current.getRoleId())) { |
|
|
|
|
|
extOrgSyncMapper.deleteUserRole(user.getUserId(), current.getRoleId()); |
|
|
|
|
|
result.getRemoved().add(currentName); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<Long, String> entry : desired.entrySet()) { |
|
|
|
|
|
if (currentIds.contains(entry.getKey())) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
extOrgSyncMapper.insertUserRole(user.getUserId(), entry.getKey()); |
|
|
|
|
|
result.getAdded().add(entry.getValue()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
log.info("[EXT-ROLE] username={}, {}", username, result.getSummary()); |
|
|
|
|
|
for (String skipped : result.getSkipped()) { |
|
|
|
|
|
log.warn("[EXT-ROLE] username={}, 跳过: {}", username, skipped); |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 用户落库:按 ext_id 更新;无 ext_id 记录时优先绑定同名账号(覆盖 ext_id),否则新建。 |
|
|
* 用户落库:按 ext_id 更新;无 ext_id 记录时优先绑定同名账号(覆盖 ext_id),否则新建。 |
|
|
*/ |
|
|
*/ |
|
|
|