mirror of
https://github.com/PowerJob/PowerJob.git
synced 2025-07-17 00:00:04 +08:00
feat: support user related query
This commit is contained in:
parent
31a7690844
commit
c350607762
@ -47,9 +47,17 @@ public interface PowerJobPermissionService {
|
||||
|
||||
/**
|
||||
* 获取有相关权限的用户
|
||||
* @param roleScope 权限范围
|
||||
* @param roleScope 角色范围
|
||||
* @param target 目标
|
||||
* @return 角色对应的用户列表
|
||||
*/
|
||||
Map<Role, List<Long>> fetchUserWithPermissions(RoleScope roleScope, Long target);
|
||||
|
||||
/**
|
||||
* 获取用户有权限的目标
|
||||
* @param roleScope 角色范围
|
||||
* @param userId 用户ID
|
||||
* @return result
|
||||
*/
|
||||
Map<Role, List<Long>> fetchUserHadPermissionTargets(RoleScope roleScope, Long userId);
|
||||
}
|
||||
|
@ -123,6 +123,21 @@ public class PowerJobPermissionServiceImpl implements PowerJobPermissionService
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Role, List<Long>> fetchUserHadPermissionTargets(RoleScope roleScope, Long userId) {
|
||||
|
||||
Map<Role, List<Long>> ret = Maps.newHashMap();
|
||||
List<UserRoleDO> userRoleDOList = userRoleRepository.findAllByUserIdAndScope(userId, roleScope.getV());
|
||||
|
||||
Optional.ofNullable(userRoleDOList).orElse(Collections.emptyList()).forEach(r -> {
|
||||
Role role = Role.of(r.getRole());
|
||||
List<Long> targetIds = ret.computeIfAbsent(role, ignore -> Lists.newArrayList());
|
||||
targetIds.add(r.getTarget());
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean checkAppPermission(Long targetId, Permission requiredPermission, Multimap<Long, Role> appId2Role, Multimap<Long, Role> namespaceId2Role) {
|
||||
|
||||
final Collection<Role> appRoles = appId2Role.get(targetId);
|
||||
|
@ -32,4 +32,6 @@ public interface AppInfoRepository extends JpaRepository<AppInfoDO, Long>, JpaSp
|
||||
@Query(value = "select id from AppInfoDO where currentServer = :currentServer")
|
||||
List<Long> listAppIdByCurrentServer(@Param("currentServer")String currentServer);
|
||||
|
||||
List<AppInfoDO> findAllByNamespaceId(Long namespaceId);
|
||||
|
||||
}
|
||||
|
@ -18,4 +18,6 @@ public interface UserRoleRepository extends JpaRepository<UserRoleDO, Long> {
|
||||
List<UserRoleDO> findAllByScopeAndTarget(Integer scope, Long target);
|
||||
|
||||
List<UserRoleDO> findAllByScopeAndTargetAndRoleAndUserId(Integer scope, Long target, Integer role, Long userId);
|
||||
|
||||
List<UserRoleDO> findAllByUserIdAndScope(Long userId, Integer scope);
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import tech.powerjob.server.auth.Permission;
|
||||
import tech.powerjob.server.auth.RoleScope;
|
||||
import tech.powerjob.server.web.request.ComponentUserRoleInfo;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Web Auth 服务
|
||||
* 写在 starter 包下,抽取 controller 的公共逻辑
|
||||
@ -38,4 +40,6 @@ public interface WebAuthService {
|
||||
* @return 是否有权限
|
||||
*/
|
||||
boolean hasPermission(RoleScope roleScope, Long target, Permission permission);
|
||||
|
||||
Set<Long> fetchMyPermissionTargets(RoleScope roleScope);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tech.powerjob.common.serialize.JsonUtils;
|
||||
import tech.powerjob.server.auth.*;
|
||||
import tech.powerjob.server.auth.common.AuthErrorCode;
|
||||
import tech.powerjob.server.auth.common.PowerJobAuthException;
|
||||
import tech.powerjob.server.auth.service.WebAuthService;
|
||||
import tech.powerjob.server.auth.service.permission.PowerJobPermissionService;
|
||||
import tech.powerjob.server.web.request.ComponentUserRoleInfo;
|
||||
@ -59,6 +61,23 @@ public class WebAuthServiceImpl implements WebAuthService {
|
||||
return powerJobPermissionService.hasPermission(powerJobUser.getId(), roleScope, target, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> fetchMyPermissionTargets(RoleScope roleScope) {
|
||||
|
||||
PowerJobUser powerJobUser = LoginUserHolder.get();
|
||||
if (powerJobUser == null) {
|
||||
throw new PowerJobAuthException(AuthErrorCode.USER_NOT_LOGIN);
|
||||
}
|
||||
|
||||
Map<Role, List<Long>> role2TargetIds = powerJobPermissionService.fetchUserHadPermissionTargets(roleScope, powerJobUser.getId());
|
||||
|
||||
Set<Long> targetIds = Sets.newHashSet();
|
||||
role2TargetIds.values().forEach(targetIds::addAll);
|
||||
|
||||
// 展示不考虑穿透权限的问题(即拥有 namespace 权限也可以看到全部的 apps)
|
||||
return targetIds;
|
||||
}
|
||||
|
||||
private void diffGrant(RoleScope roleScope, Long target, Role role, List<Long> uids, Map<Role, List<Long>> originRole2Uids) {
|
||||
|
||||
Set<Long> originUids = Sets.newHashSet(Optional.ofNullable(originRole2Uids.get(role)).orElse(Collections.emptyList()));
|
||||
|
@ -30,9 +30,9 @@ public class ControllerExceptionHandler {
|
||||
// 不是所有异常都需要打印完整堆栈,后续可以定义内部的Exception,便于判断
|
||||
if (e instanceof PowerJobException) {
|
||||
ret.setCode(((PowerJobException) e).getCode());
|
||||
log.warn("[ControllerException] PowerJobException, message is {}.", ExceptionUtils.getMessage(e));
|
||||
log.warn("[ControllerException] PowerJobException, message is {}.", e.getMessage());
|
||||
} else if (e instanceof IllegalArgumentException) {
|
||||
log.warn("[ControllerException] http request failed, message is {}.", e.getMessage());
|
||||
log.warn("[ControllerException] http request failed due to IllegalArgument, message is {}.", e.getMessage());
|
||||
} else if (e instanceof HttpMessageNotReadableException || e instanceof MethodArgumentTypeMismatchException) {
|
||||
log.warn("[ControllerException] invalid http request params, exception is {}.", e.getMessage());
|
||||
} else if (e instanceof HttpRequestMethodNotSupportedException) {
|
||||
|
@ -2,6 +2,7 @@ package tech.powerjob.server.web.controller;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
@ -30,8 +31,10 @@ import tech.powerjob.server.web.request.QueryAppInfoRequest;
|
||||
import tech.powerjob.server.web.response.AppInfoVO;
|
||||
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -102,11 +105,18 @@ public class AppInfoController {
|
||||
|
||||
Pageable pageable = PageRequest.of(queryAppInfoRequest.getIndex(), queryAppInfoRequest.getPageSize());
|
||||
|
||||
// TODO: 我有权限的列表
|
||||
// 相关权限(先查处关联 ids)
|
||||
Set<Long> queryAppIds;
|
||||
Boolean showMyRelated = queryAppInfoRequest.getShowMyRelated();
|
||||
if (BooleanUtils.isTrue(showMyRelated)) {
|
||||
queryAppIds = webAuthService.fetchMyPermissionTargets(RoleScope.APP);
|
||||
} else {
|
||||
queryAppIds = Collections.emptySet();
|
||||
}
|
||||
|
||||
Specification<AppInfoDO> specification = (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> predicates = Lists.newArrayList();
|
||||
|
||||
|
||||
Long appId = queryAppInfoRequest.getAppId();
|
||||
Long namespaceId = queryAppInfoRequest.getNamespaceId();
|
||||
|
||||
@ -122,6 +132,10 @@ public class AppInfoController {
|
||||
predicates.add(criteriaBuilder.like(root.get("appName"), QueryConvertUtils.convertLikeParams(queryAppInfoRequest.getAppNameLike())));
|
||||
}
|
||||
|
||||
if (!queryAppIds.isEmpty()) {
|
||||
predicates.add(criteriaBuilder.in(root.get("id")).value(queryAppIds));
|
||||
}
|
||||
|
||||
return query.where(predicates.toArray(new Predicate[0])).getRestriction();
|
||||
};
|
||||
|
||||
|
@ -2,12 +2,14 @@ package tech.powerjob.server.web.controller;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import tech.powerjob.common.exception.PowerJobException;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import tech.powerjob.server.auth.LoginUserHolder;
|
||||
import tech.powerjob.server.auth.Permission;
|
||||
@ -17,10 +19,13 @@ import tech.powerjob.server.auth.interceptor.ApiPermission;
|
||||
import tech.powerjob.server.auth.plugin.ModifyOrCreateDynamicPermission;
|
||||
import tech.powerjob.server.auth.plugin.SaveNamespaceGrantPermissionPlugin;
|
||||
import tech.powerjob.server.auth.service.WebAuthService;
|
||||
import tech.powerjob.server.common.SJ;
|
||||
import tech.powerjob.server.common.constants.SwitchableStatus;
|
||||
import tech.powerjob.server.persistence.PageResult;
|
||||
import tech.powerjob.server.persistence.QueryConvertUtils;
|
||||
import tech.powerjob.server.persistence.remote.model.AppInfoDO;
|
||||
import tech.powerjob.server.persistence.remote.model.NamespaceDO;
|
||||
import tech.powerjob.server.persistence.remote.repository.AppInfoRepository;
|
||||
import tech.powerjob.server.persistence.remote.repository.NamespaceRepository;
|
||||
import tech.powerjob.server.web.converter.NamespaceConverter;
|
||||
import tech.powerjob.server.web.request.ComponentUserRoleInfo;
|
||||
@ -51,6 +56,8 @@ public class NamespaceController {
|
||||
@Resource
|
||||
private WebAuthService webAuthService;
|
||||
@Resource
|
||||
private AppInfoRepository appInfoRepository;
|
||||
@Resource
|
||||
private NamespaceRepository namespaceRepository;
|
||||
|
||||
@ResponseBody
|
||||
@ -102,6 +109,13 @@ public class NamespaceController {
|
||||
@DeleteMapping("/delete")
|
||||
@ApiPermission(name = "Namespace-Delete", roleScope = RoleScope.NAMESPACE, requiredPermission = Permission.SU)
|
||||
public ResultDTO<Void> deleteNamespace(Long id) {
|
||||
|
||||
List<AppInfoDO> appInfosInNamespace = appInfoRepository.findAllByNamespaceId(id);
|
||||
if (CollectionUtils.isNotEmpty(appInfosInNamespace)) {
|
||||
List<String> relatedApps = appInfosInNamespace.stream().map(AppInfoDO::getAppName).collect(Collectors.toList());
|
||||
throw new PowerJobException("Unable to delete due to associated apps: " + SJ.COMMA_JOINER.join(relatedApps));
|
||||
}
|
||||
|
||||
namespaceRepository.deleteById(id);
|
||||
return ResultDTO.success(null);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user