feat: api权限验证基本功能以及仪表板增删改权限demo

This commit is contained in:
fit2cloud-chenyw 2022-01-25 14:35:07 +08:00
parent 5c2ae56184
commit 71f3d463c4
22 changed files with 861 additions and 39 deletions

View File

@ -22,6 +22,12 @@
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@ -0,0 +1,22 @@
package io.dataease.auth.annotation;
import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.constants.ResourceAuthLevel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DePermission {
DePermissionType type();
ResourceAuthLevel level() default ResourceAuthLevel.COMMON_LEVEL_USE;
String value() default "";
int paramIndex() default 0;
}

View File

@ -0,0 +1,21 @@
package io.dataease.auth.annotation;
import org.apache.shiro.authz.annotation.Logical;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DePermissions {
DePermission[] value();
Logical logical() default Logical.AND;
}

View File

@ -0,0 +1,187 @@
package io.dataease.auth.aop;
import io.dataease.auth.annotation.DePermission;
import io.dataease.auth.annotation.DePermissions;
import io.dataease.auth.entity.AuthItem;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.LogUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.Logical;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
@Aspect
@Component
public class DePermissionAnnotationHandler {
@Around(value = "@annotation(io.dataease.auth.annotation.DePermissions)")
public Object PermissionsAround(ProceedingJoinPoint point) {
try {
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
DePermissions annotation = method.getAnnotation(DePermissions.class);
Logical logical = annotation.logical();
DePermission[] dePermissions = annotation.value();
Object[] args = point.getArgs();
if (logical == Logical.AND) {
for (int i = 0; i < dePermissions.length; i++) {
DePermission permission = dePermissions[i];
boolean currentAccess = access(args[permission.paramIndex()], permission, 0);
if (!currentAccess) {
return null;
}
}
} else {
List<Exception> exceptions = new ArrayList<>();
Boolean someAccess = false;
for (int i = 0; i < dePermissions.length; i++) {
DePermission permission = dePermissions[i];
try{
boolean currentAccess = access(args[permission.paramIndex()], permission, 0);
if (currentAccess) {
someAccess = true;
break;
}
}catch (Exception e) {
exceptions.add(e);
}
}
if (!someAccess) {
throw exceptions.get(0);
}
}
return point.proceed(point.getArgs());
} catch (Throwable throwable) {
LogUtil.error(throwable.getMessage(), throwable);
throw new RuntimeException(throwable);
}
}
@Around(value = "@annotation(io.dataease.auth.annotation.DePermission)")
public Object PermissionAround(ProceedingJoinPoint point) {
try {
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
DePermission annotation = method.getAnnotation(DePermission.class);
Object arg = point.getArgs()[annotation.paramIndex()];
if (access(arg, annotation, 0)) {
return point.proceed(point.getArgs());
}
return false;
} catch (Throwable throwable) {
LogUtil.error(throwable.getMessage(), throwable);
throw new RuntimeException(throwable);
}
}
private Boolean access(Object arg, DePermission annotation, int layer) throws Exception {
if (ObjectUtils.isEmpty(arg)) return true;
String type = annotation.type().name().toLowerCase();
String value = annotation.value();
Integer requireLevel = annotation.level().getLevel();
Set<String> resourceIds = AuthUtils.permissionByType(type).stream().filter(
item -> item.getLevel() >= requireLevel
).map(AuthItem::getAuthSource).collect(Collectors.toSet());
Class<?> parameterType = arg.getClass();
if (parameterType.isPrimitive() || isWrapClass(parameterType) || isString(parameterType)) {
boolean permissionValid = resourceIds.contains(arg);
if (permissionValid) return true;
throw new UnauthorizedException("Subject does not have permission[" + annotation.level().name() +":"+ annotation.type() + ":" + arg + "]");
} else if (isArray(parameterType)) {
for (int i = 0; i < Array.getLength(arg); i++) {
Object o = Array.get(arg, i);
if (!access(o, annotation, layer)) {
return false;
}
}
} else if (isCollection(parameterType)) {
Object[] array = ((Collection) arg).toArray();
for (int i = 0; i < array.length; i++) {
Object o = array[i];
if (!access(o, annotation, layer)) {
return false;
}
}
} else if (isMap(parameterType)) {
Map<String, Object> argMap = (Map) arg;
String[] values = value.split(".");
Object o = argMap.get(values[layer]);
return access(o, annotation, ++layer);
} else {
//当作自定义类处理
String[] values = value.split("u002E");
String fieldName = values[layer];
Object fieldValue = getFieldValue(arg, fieldName);
return access(fieldValue, annotation, ++layer);
}
return true;
}
private Object getFieldValue(Object o, String fieldName) throws Exception{
Class<?> aClass = o.getClass();
while (null != aClass.getSuperclass()) {
Field[] declaredFields = aClass.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
String name = field.getName();
if (StringUtils.equals(name, fieldName)) {
field.setAccessible(true);
return field.get(o);
}
}
aClass = aClass.getSuperclass();
}
throw new NoSuchFieldException(fieldName);
}
private final static String[] wrapClasies = {
"java.lang.Boolean",
"java.lang.Character",
"java.lang.Integer",
"java.lang.Byte",
"java.lang.Short",
"java.lang.Long",
"java.lang.Float",
"java.lang.Double",
};
private Boolean isString(Class clz) {
return StringUtils.equals("java.lang.String", clz.getName());
}
private Boolean isArray(Class clz) {
return clz.isArray();
}
private Boolean isCollection(Class clz) {
return Collection.class.isAssignableFrom(clz);
}
private Boolean isMap(Class clz) {
return Map.class.isAssignableFrom(clz);
}
private Boolean isWrapClass(Class clz) {
return Arrays.stream(wrapClasies).anyMatch(item -> StringUtils.equals(item, clz.getName()));
}
}

View File

@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -44,11 +45,11 @@ public class F2CRealm extends AuthorizingRealm {
//验证资源权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Long userId = JWTUtils.tokenInfoByToken(principals.toString()).getUserId();
CurrentUserDto userDto = (CurrentUserDto)principals.getPrimaryPrincipal();
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
Set<String> role = new HashSet<>(authUserService.roles(userId));
Set<String> role = new HashSet<>(userDto.getRoles().stream().map(item -> ( item.getId() + "")).collect(Collectors.toSet()));
simpleAuthorizationInfo.addRoles(role);
Set<String> permission = new HashSet<>(authUserService.permissions(userId));
Set<String> permission = new HashSet<>(userDto.getPermissions());
simpleAuthorizationInfo.addStringPermissions(permission);
return simpleAuthorizationInfo;
}

View File

@ -0,0 +1,39 @@
package io.dataease.auth.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Objects;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class AuthItem implements Serializable {
private static final long serialVersionUID = 7909546616315767531L;
private String authSource;
private Integer level;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AuthItem authItem = (AuthItem) o;
return Objects.equals(authSource, authItem.authSource) &&
Objects.equals(level, authItem.level);
}
@Override
public int hashCode() {
return Objects.hash(authSource, level);
}
}

View File

@ -1,7 +1,9 @@
package io.dataease.auth.service;
import io.dataease.auth.entity.AuthItem;
import io.dataease.commons.model.AuthURD;
import java.util.List;
import java.util.Set;
public interface ExtAuthService {
@ -9,4 +11,22 @@ public interface ExtAuthService {
Set<Long> userIdsByRD(AuthURD request);
AuthURD resourceTarget(String resourceId);
List<AuthItem> dataSourceIdByUser(Long userId);
List<AuthItem> dataSetIdByUser(Long userId);
List<AuthItem> panelIdByUser(Long userId);
List<AuthItem> dataSourceIdByRole(Long roleId);
List<AuthItem> dataSetIdByRole(Long roleId);
List<AuthItem> panelIdByRole(Long roleId);
List<AuthItem> dataSourceIdByDept(Long deptId);
List<AuthItem> dataSetIdByDept(Long deptId);
List<AuthItem> panelIdByDept(Long deptId);
void clearUserResource(Long userId);
void clearDeptResource(Long deptId);
void clearRoleResource(Long roleId);
}

View File

@ -1,22 +1,28 @@
package io.dataease.auth.service.impl;
import io.dataease.auth.entity.AuthItem;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.base.domain.SysAuth;
import io.dataease.base.mapper.ext.ExtAuthMapper;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.model.AuthURD;
import io.dataease.commons.utils.LogUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ExtAuthServiceImpl implements ExtAuthService {
private static final List<AuthItem> emptyResult = new ArrayList();
@Resource
private ExtAuthMapper extAuthMapper;
@ -55,4 +61,89 @@ public class ExtAuthServiceImpl implements ExtAuthService {
}
return authURD;
}
@Cacheable(value = AuthConstants.USER_LINK_NAME, key = "'user' + #userId")
@Override
public List<AuthItem> dataSourceIdByUser(Long userId) {
return extAuthMapper.dataSourceIdByUser(userId.toString());
}
@Cacheable(value = AuthConstants.USER_DATASET_NAME, key = "'user' + #userId")
@Override
public List<AuthItem> dataSetIdByUser(Long userId) {
return extAuthMapper.dataSetIdByUser(userId.toString());
}
@Cacheable(value = AuthConstants.USER_PANEL_NAME, key = "'user' + #userId")
@Override
public List<AuthItem> panelIdByUser(Long userId) {
return extAuthMapper.panelIdByUser(userId.toString());
}
@Cacheable(value = AuthConstants.ROLE_LINK_NAME, key = "'role' + #roleId")
@Override
public List<AuthItem> dataSourceIdByRole(Long roleId) {
return extAuthMapper.dataSourceIdByRole(roleId.toString());
}
@Cacheable(value = AuthConstants.ROLE_DATASET_NAME, key = "'role' + #roleId")
@Override
public List<AuthItem> dataSetIdByRole(Long roleId) {
return extAuthMapper.dataSetIdByRole(roleId.toString());
}
@Cacheable(value = AuthConstants.ROLE_PANEL_NAME, key = "'role' + #roleId")
@Override
public List<AuthItem> panelIdByRole(Long roleId) {
return extAuthMapper.panelIdByRole(roleId.toString());
}
@Cacheable(value = AuthConstants.DEPT_LINK_NAME, key = "'dept' + #deptId")
@Override
public List<AuthItem> dataSourceIdByDept(Long deptId) {
if (ObjectUtils.isEmpty(deptId)) return emptyResult;
return extAuthMapper.dataSourceIdByDept(deptId.toString());
}
@Cacheable(value = AuthConstants.DEPT_DATASET_NAME, key = "'dept' + #deptId")
@Override
public List<AuthItem> dataSetIdByDept(Long deptId) {
if (ObjectUtils.isEmpty(deptId)) return emptyResult;
return extAuthMapper.dataSetIdByDept(deptId.toString());
}
@Cacheable(value = AuthConstants.DEPT_PANEL_NAME, key = "'dept' + #deptId")
@Override
public List<AuthItem> panelIdByDept(Long deptId) {
if (ObjectUtils.isEmpty(deptId)) return emptyResult;
return extAuthMapper.panelIdByDept(deptId.toString());
}
@Caching(evict = {
@CacheEvict(value = AuthConstants.USER_LINK_NAME, key = "'user' + #userId"),
@CacheEvict(value = AuthConstants.USER_DATASET_NAME, key = "'user' + #userId"),
@CacheEvict(value = AuthConstants.USER_PANEL_NAME, key = "'user' + #userId")
})
public void clearUserResource(Long userId) {
LogUtil.info("all permission resource of user {} is cleanning...", userId);
}
@Caching(evict = {
@CacheEvict(value = AuthConstants.DEPT_LINK_NAME, key = "'dept' + #deptId"),
@CacheEvict(value = AuthConstants.DEPT_DATASET_NAME, key = "'dept' + #deptId"),
@CacheEvict(value = AuthConstants.DEPT_PANEL_NAME, key = "'dept' + #deptId")
})
public void clearDeptResource(Long deptId) {
LogUtil.info("all permission resource of dept {} is cleanning...", deptId);
}
@Caching(evict = {
@CacheEvict(value = AuthConstants.ROLE_LINK_NAME, key = "'role' + #roleId"),
@CacheEvict(value = AuthConstants.ROLE_DATASET_NAME, key = "'role' + #roleId"),
@CacheEvict(value = AuthConstants.ROLE_PANEL_NAME, key = "'role' + #roleId")
})
public void clearRoleResource(Long roleId) {
LogUtil.info("all permission resource of role {} is cleanning...", roleId);
}
}

View File

@ -1,6 +1,7 @@
package io.dataease.base.mapper.ext;
import io.dataease.auth.entity.AuthItem;
import io.dataease.base.domain.SysAuth;
import org.apache.ibatis.annotations.Param;
@ -14,4 +15,16 @@ public interface ExtAuthMapper {
List<Long> queryUserIdWithDeptIds(@Param("deptIds") List<Long> deptIds);
List<SysAuth> queryByResource(@Param("resourceId") String resourceId);
List<AuthItem> dataSourceIdByUser(String userId);
List<AuthItem> dataSetIdByUser(String userId);
List<AuthItem> panelIdByUser(String userId);
List<AuthItem> dataSourceIdByRole(String roleId);
List<AuthItem> dataSetIdByRole(String roleId);
List<AuthItem> panelIdByRole(String roleId);
List<AuthItem> dataSourceIdByDept(String deptId);
List<AuthItem> dataSetIdByDept(String deptId);
List<AuthItem> panelIdByDept(String deptId);
}

View File

@ -2,6 +2,10 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="io.dataease.base.mapper.ext.ExtAuthMapper">
<resultMap id="AuthItemMap" type="io.dataease.auth.entity.AuthItem">
<result column="auth_source" property="authSource"/>
<result column="level" property="level"/>
</resultMap>
<select id="queryUserIdWithRoleIds" resultType="java.lang.Long" >
select user_id
@ -29,6 +33,125 @@
where a.auth_source = #{resourceId} and b.privilege_value = 1
</select>
<select id="dataSourceIdByUser" resultMap="AuthItemMap">
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'datasource'
AND auth_target_type = 'user'
AND auth_target = #{userId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="dataSetIdByUser" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'dataset'
AND auth_target_type = 'user'
AND auth_target = #{userId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="panelIdByUser" resultMap="AuthItemMap">
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'panel'
AND auth_target_type = 'user'
AND auth_target = #{userId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="dataSourceIdByRole" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'datasource'
AND auth_target_type = 'role'
AND auth_target = #{roleId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="dataSetIdByRole" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'dataset'
AND auth_target_type = 'role'
AND auth_target = #{roleId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="panelIdByRole" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'panel'
AND auth_target_type = 'role'
AND auth_target = #{roleId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="dataSourceIdByDept" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'datasource'
AND auth_target_type = 'dept'
AND auth_target = #{deptId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="dataSetIdByDept" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'dataset'
AND auth_target_type = 'dept'
AND auth_target = #{deptId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
<select id="panelIdByDept" resultMap="AuthItemMap" >
SELECT
auth_source, MAX(d.privilege_type) as level
FROM
sys_auth a
LEFT JOIN sys_auth_detail d on d.auth_id = a.id
WHERE
auth_source_type = 'panel'
AND auth_target_type = 'dept'
AND auth_target = #{deptId}
AND d.privilege_value = 1
GROUP BY a.id
</select>
</mapper>

View File

@ -9,4 +9,16 @@ public class AuthConstants {
public final static String ID_TOKEN_KEY = "IdToken";
public final static String USER_LINK_NAME = "user_link";
public final static String USER_DATASET_NAME = "user_dataset";
public final static String USER_PANEL_NAME = "user_panel";
public final static String ROLE_LINK_NAME = "role_link";
public final static String ROLE_DATASET_NAME = "role_dataset";
public final static String ROLE_PANEL_NAME = "role_panel";
public final static String DEPT_LINK_NAME = "dept_link";
public final static String DEPT_DATASET_NAME = "dept_dataset";
public final static String DEPT_PANEL_NAME = "dept_panel";
}

View File

@ -0,0 +1,5 @@
package io.dataease.commons.constants;
public enum DePermissionType {
DATASOURCE, DATASET, PANEL
}

View File

@ -0,0 +1,35 @@
package io.dataease.commons.constants;
public enum ResourceAuthLevel {
COMMON_LEVEL_USE(1),
PANNEL_LEVEL_VIEW(1),
PANNEL_LEVEL_EXPORT(3),
PANNEL_LEVEL_MANAGE(5),
PANNEL_LEVEL_GRANT(15),
DATASET_LEVEL_USE(1),
DATASET_LEVEL_MANAGE(3),
DATASET_LEVEL_GRANT(15),
LINK_LEVEL_USE(1),
LINK_LEVEL_MANAGE(3),
LINK_LEVEL_GRANT(15);
private Integer level;
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
ResourceAuthLevel(Integer level) {
this.level = level;
}
}

View File

@ -0,0 +1,16 @@
package io.dataease.commons.model;
import lombok.Data;
import java.io.Serializable;
@Data
public class UserPermissionItem implements Serializable {
private String type;
private String resourceId;
}

View File

@ -1,18 +1,27 @@
package io.dataease.commons.utils;
import io.dataease.auth.api.dto.CurrentRoleDto;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.entity.AuthItem;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.commons.constants.ResourceAuthLevel;
import io.dataease.commons.model.AuthURD;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class AuthUtils {
private static final String[] defaultPanelPermissions = {"panel_list"};
private static final String[] defaultDataSetPermissions = {"0"};
private static final String[] defaultLinkPermissions = {"0"};
private static ExtAuthService extAuthService;
@Autowired
@ -38,4 +47,53 @@ public class AuthUtils {
public static AuthURD authURDR(String resourceId) {
return extAuthService.resourceTarget(resourceId);
}
public static Set<AuthItem> permissionByType(String type) {
CurrentUserDto user = getUser();
Long userId = user.getUserId();
Long deptId = user.getDeptId();
List<CurrentRoleDto> roles = user.getRoles();
Set<AuthItem> result = new HashSet<>();
if (StringUtils.equals("link", type)) {
Set<AuthItem> userSet = extAuthService.dataSourceIdByUser(userId).stream().collect(Collectors.toSet());
Set<AuthItem> roleSet = roles.stream().map(role -> extAuthService.dataSourceIdByRole(role.getId())).flatMap(Collection::stream).collect(Collectors.toSet());
Set<AuthItem> deptSet = extAuthService.dataSourceIdByDept(deptId).stream().collect(Collectors.toSet());
result.addAll(userSet);
result.addAll(roleSet);
result.addAll(deptSet);
Arrays.stream(defaultLinkPermissions).forEach(item -> {
result.add(new AuthItem(item, ResourceAuthLevel.LINK_LEVEL_MANAGE.getLevel()));
});
return result;
}
else if (StringUtils.equals("dataset", type)) {
Set<AuthItem> userSet = extAuthService.dataSetIdByUser(userId).stream().collect(Collectors.toSet());
Set<AuthItem> roleSet = roles.stream().map(role -> extAuthService.dataSetIdByRole(role.getId())).flatMap(Collection::stream).collect(Collectors.toSet());
Set<AuthItem> deptSet = extAuthService.dataSetIdByDept(deptId).stream().collect(Collectors.toSet());
result.addAll(userSet);
result.addAll(roleSet);
result.addAll(deptSet);
Arrays.stream(defaultDataSetPermissions).forEach(item -> {
result.add(new AuthItem(item, ResourceAuthLevel.DATASET_LEVEL_MANAGE.getLevel()));
});
return result;
}
else if (StringUtils.equals("panel", type)) {
Set<AuthItem> userSet = extAuthService.panelIdByUser(userId).stream().collect(Collectors.toSet());
Set<AuthItem> roleSet = roles.stream().map(role -> extAuthService.panelIdByRole(role.getId())).flatMap(Collection::stream).collect(Collectors.toSet());
Set<AuthItem> deptSet = extAuthService.panelIdByDept(deptId).stream().collect(Collectors.toSet());
result.addAll(userSet);
result.addAll(roleSet);
result.addAll(deptSet);
Arrays.stream(defaultPanelPermissions).forEach(item -> {
result.add(new AuthItem(item, ResourceAuthLevel.PANNEL_LEVEL_MANAGE.getLevel()));
});
return result;
}
return result;
}
}

View File

@ -1,14 +1,19 @@
package io.dataease.controller.panel;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.auth.annotation.DePermission;
import io.dataease.auth.annotation.DePermissions;
import io.dataease.base.domain.PanelGroup;
import io.dataease.base.domain.PanelGroupWithBLOBs;
import io.dataease.commons.constants.DePermissionType;
import io.dataease.commons.constants.ResourceAuthLevel;
import io.dataease.controller.handler.annotation.I18n;
import io.dataease.controller.request.panel.PanelGroupRequest;
import io.dataease.dto.panel.PanelGroupDTO;
import io.dataease.service.panel.PanelGroupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -42,18 +47,24 @@ public class PanelGroupController {
@ApiOperation("保存")
@PostMapping("/save")
@DePermissions(value = {
@DePermission(type = DePermissionType.PANEL, value = "id"),
@DePermission(type = DePermissionType.PANEL, value = "pid", level = ResourceAuthLevel.PANNEL_LEVEL_MANAGE)
}, logical = Logical.AND)
@I18n
public PanelGroup saveOrUpdate(@RequestBody PanelGroupRequest request) {
return panelGroupService.saveOrUpdate(request);
}
@ApiOperation("删除")
@DePermission(type = DePermissionType.PANEL, level = ResourceAuthLevel.PANNEL_LEVEL_MANAGE)
@PostMapping("/deleteCircle/{id}")
public void deleteCircle(@PathVariable String id) {
panelGroupService.deleteCircle(id);
}
@ApiOperation("详细信息")
@DePermission(type = DePermissionType.PANEL, level = ResourceAuthLevel.PANNEL_LEVEL_VIEW)
@GetMapping("/findOne/{id}")
public PanelGroupWithBLOBs findOne(@PathVariable String id) throws Exception {
return panelGroupService.findOne(id);

View File

@ -23,6 +23,8 @@ import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
@ -44,6 +46,7 @@ public class SysUserController {
private SysRoleService sysRoleService;
@ApiOperation("查询用户")
@RequiresPermissions("user:read")
@PostMapping("/userGrid/{goPage}/{pageSize}")
@ApiImplicitParams({
@ApiImplicitParam(paramType="path", name = "goPage", value = "页码", required = true, dataType = "Integer"),
@ -57,18 +60,21 @@ public class SysUserController {
@ApiOperation("创建用户")
@RequiresPermissions("user:add")
@PostMapping("/create")
public void create(@RequestBody SysUserCreateRequest request){
sysUserService.save(request);
}
@ApiOperation("更新用户")
@RequiresPermissions("user:edit")
@PostMapping("/update")
public void update(@RequestBody SysUserCreateRequest request){
sysUserService.update(request);
}
@ApiOperation("删除用户")
@RequiresPermissions("user:del")
@PostMapping("/delete/{userId}")
@ApiImplicitParam(paramType = "path", value = "用户ID", name = "userId", required = true, dataType = "Integer")
public void delete(@PathVariable("userId") Long userId){
@ -77,6 +83,8 @@ public class SysUserController {
@ApiOperation("更新用户状态")
@RequiresPermissions("user:edit")
@RequiresRoles("1")
@PostMapping("/updateStatus")
public void updateStatus(@RequestBody SysUserStateRequest request){
sysUserService.updateStatus(request);
@ -89,6 +97,7 @@ public class SysUserController {
sysUserService.updatePwd(request);
}
@ApiOperation("更新指定用户密码")
@RequiresPermissions("user:editPwd")
@PostMapping("/adminUpdatePwd")
public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){
sysUserService.adminUpdatePwd(request);

View File

@ -12,17 +12,19 @@ import io.dataease.plugins.xpack.auth.dto.request.XpackSysAuthRequest;
import io.dataease.plugins.xpack.auth.dto.response.XpackSysAuthDetail;
import io.dataease.plugins.xpack.auth.dto.response.XpackSysAuthDetailDTO;
import io.dataease.plugins.xpack.auth.dto.response.XpackVAuthModelDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import io.dataease.plugins.xpack.auth.service.AuthXpackService;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
@RequestMapping("/plugin/auth")
@RestController
public class XAuthServer {
private static final Set<String> cacheTypes = new HashSet<>();
@PostMapping("/authModels")
@I18n
public List<XpackVAuthModelDTO> authModels(@RequestBody XpackBaseTreeRequest request){
@ -64,6 +66,26 @@ public class XAuthServer {
CacheUtils.removeAll(AuthConstants.USER_ROLE_CACHE_NAME);
CacheUtils.removeAll(AuthConstants.USER_PERMISSION_CACHE_NAME);
}
String authCacheKey = getAuthCacheKey(request);
if (StringUtils.isNotBlank(authCacheKey)) {
CacheUtils.remove(authCacheKey, request.getAuthTargetType() + request.getAuthTarget());
}
});
}
private String getAuthCacheKey(XpackSysAuthRequest request) {
if (CollectionUtils.isEmpty(cacheTypes)) {
cacheTypes.add("link");
cacheTypes.add("dataset");
cacheTypes.add("panel");
}
String authTargetType = request.getAuthTargetType();
String authSourceType = request.getAuthSourceType();
if (!cacheTypes.contains(authSourceType)) {
return null;
}
return authTargetType + "_" + authSourceType;
}
}

View File

@ -1,6 +1,7 @@
package io.dataease.plugins.server;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.sys.response.DeptNodeResponse;
import io.dataease.plugins.common.entity.XpackGridRequest;
@ -13,6 +14,7 @@ import io.dataease.plugins.xpack.dept.dto.response.XpackSysDept;
import io.dataease.plugins.xpack.dept.service.DeptXpackService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
@ -23,6 +25,9 @@ import java.util.stream.Collectors;
@RestController
public class XDeptServer {
@Autowired
private ExtAuthService extAuthService;
@ApiOperation("查询子节点")
@PostMapping("/childNodes/{pid}")
public List<DeptNodeResponse> childNodes(@PathVariable("pid") Long pid){
@ -72,6 +77,9 @@ public class XDeptServer {
@PostMapping("/delete")
public void delete(@RequestBody List<XpackDeleteDept> requests){
DeptXpackService deptService = SpringContextUtil.getBean(DeptXpackService.class);
requests.forEach(request -> {
extAuthService.clearDeptResource(request.getDeptId());
});
deptService.batchDelete(requests);
}

View File

@ -3,6 +3,7 @@ package io.dataease.plugins.server;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.plugins.common.entity.XpackGridRequest;
@ -12,6 +13,7 @@ import io.dataease.plugins.xpack.role.dto.response.XpackRoleItemDto;
import io.dataease.plugins.xpack.role.service.RoleXpackService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
@ -21,6 +23,8 @@ import java.util.List;
@RestController
public class XRoleServer {
@Autowired
private ExtAuthService extAuthService;
@ApiOperation("新增角色")
@PostMapping("/create")
@ -34,6 +38,7 @@ public class XRoleServer {
@PostMapping("/delete/{roleId}")
public void delete(@PathVariable("roleId") Long roleId){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
extAuthService.clearDeptResource(roleId);
roleXpackService.delete(roleId);
}

View File

@ -1,6 +1,7 @@
package io.dataease.service.sys;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.service.ExtAuthService;
import io.dataease.base.domain.SysUser;
import io.dataease.base.domain.SysUserExample;
import io.dataease.base.domain.SysUsersRolesExample;
@ -27,6 +28,7 @@ import io.dataease.plugins.xpack.oidc.dto.SSOUserInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@ -54,6 +56,9 @@ public class SysUserService {
@Resource
private ExtSysUserMapper extSysUserMapper;
@Autowired
private ExtAuthService extAuthService;
public List<SysUserGridResponse> query(BaseGridRequest request) {
@ -268,6 +273,7 @@ public class SysUserService {
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #userId")
@Transactional
public int delete(Long userId) {
extAuthService.clearUserResource(userId);
deleteUserRoles(userId);
return sysUserMapper.deleteByPrimaryKey(userId);
}

View File

@ -79,7 +79,7 @@
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="FIFO"
>
<cacheEventListenerFactory class="io.dataease.listener.LicCacheEventListener" />
<cacheEventListenerFactory class="io.dataease.listener.LicCacheEventListener"/>
</cache>
<cache
@ -97,45 +97,157 @@
<!--消息渠道缓存-->
<cache
name="sys_msg_channel"
eternal="true"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
name="sys_msg_channel"
eternal="true"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
/>
<!--消息类型缓存-->
<cache
name="sys_msg_type"
eternal="true"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
name="sys_msg_type"
eternal="true"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="false"
/>
<!--消息类型缓存-->
<cache
name="sys_msg_user_subscribe"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="10000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="28800"
timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU"
name="sys_msg_user_subscribe"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="10000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="28800"
timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU"
/>
<!--消息类型缓存-->
<cache
name="sys_map_areas"
eternal="true"
maxElementsInMemory="100"
maxElementsOnDisk="3000"
overflowToDisk="true"
diskPersistent="false"
name="sys_map_areas"
eternal="true"
maxElementsInMemory="100"
maxElementsOnDisk="3000"
overflowToDisk="true"
diskPersistent="false"
/>
<!--用户授权数据源缓存-->
<cache
name="user_link"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--用户授权数据集缓存-->
<cache
name="user_dataset"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--用户授权仪表板缓存-->
<cache
name="user_panel"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--角色授权数据源缓存-->
<cache
name="role_link"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--角色授权数据集缓存-->
<cache
name="role_dataset"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--角色授权仪表板缓存-->
<cache
name="role_panel"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--组织授权数据源缓存-->
<cache
name="dept_link"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--组织授权数据集缓存-->
<cache
name="dept_dataset"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>
<!--组织授权仪表板缓存-->
<cache
name="dept_panel"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="1000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LRU"
/>