forked from p85126437/datagear
角色启用/禁用、用户设置角色后刷新权限缓存
This commit is contained in:
parent
cddd34093f
commit
69af9b638e
|
@ -11,7 +11,8 @@
|
|||
ok 移除管理员的数据源授权功能;
|
||||
ok 移除通配符授权特性;
|
||||
系统添加缓存支持:
|
||||
实现postProcessGet,加载共享属性值;
|
||||
ok 角色启用/禁用、用户设置角色时刷新权限缓存;
|
||||
ok 实现postProcessGet,加载共享属性值;
|
||||
ok 服务层API内部引入缓存特性;
|
||||
ok 系统缓存统一改为Caffeine,移除Guava以减少程序包大小;
|
||||
ok 标签卡添加横排设置选项,简化配置项;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2018 datagear.tech
|
||||
*
|
||||
* Licensed under the LGPLv3 license:
|
||||
* http://www.gnu.org/licenses/lgpl-3.0.html
|
||||
*/
|
||||
|
||||
package org.datagear.management.service;
|
||||
|
||||
import org.datagear.management.domain.Role;
|
||||
import org.datagear.management.domain.User;
|
||||
|
||||
/**
|
||||
* 授权监听器。
|
||||
* <p>
|
||||
* 主要用于处理授权变更事件,比如清空或者重新加载缓存。
|
||||
* </p>
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public interface AuthorizationListener
|
||||
{
|
||||
/**
|
||||
* 指定资源的授权已更新。
|
||||
* <p>
|
||||
* 当直接修改了指定资源的授权信息后,将触发此事件。
|
||||
* </p>
|
||||
*
|
||||
* @param resourceType
|
||||
* @param resources
|
||||
*/
|
||||
void authorizationUpdated(String resourceType, String... resources);
|
||||
|
||||
/**
|
||||
* 未知量的资源的权限已更新。
|
||||
* <p>
|
||||
* 数据权限不仅与直接授权相关,还与下列操作相关:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>角色({@linkplain Role})启用、禁用</li>
|
||||
* <li>用户({@linkplain User})绑定、解绑角色</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 当上述操作后,将触发此事件。
|
||||
* </p>
|
||||
*/
|
||||
void permissionUpdated();
|
||||
}
|
|
@ -24,7 +24,8 @@ import org.datagear.persistence.Query;
|
|||
* @param <ID>
|
||||
* @param <T>
|
||||
*/
|
||||
public interface DataPermissionEntityService<ID, T extends DataPermissionEntity<ID>> extends EntityService<ID, T>
|
||||
public interface DataPermissionEntityService<ID, T extends DataPermissionEntity<ID>>
|
||||
extends EntityService<ID, T>, AuthorizationListener
|
||||
{
|
||||
/** 数据权限参数:当前用户,参考commonDataPermissionSqls.xml */
|
||||
String DATA_PERMISSION_PARAM_CURRENT_USER = "DP_CURRENT_USER";
|
||||
|
@ -197,14 +198,4 @@ public interface DataPermissionEntityService<ID, T extends DataPermissionEntity<
|
|||
* @throws PermissionDeniedException
|
||||
*/
|
||||
T getByStringId(User user, String id) throws PermissionDeniedException;
|
||||
|
||||
/**
|
||||
* 指定ID的实体权限更新事件通知。
|
||||
* <p>
|
||||
* 此方法通常用于清除、或者重新加载权限缓存。
|
||||
* </p>
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
void permissionUpdated(String... ids);
|
||||
}
|
||||
|
|
|
@ -206,10 +206,19 @@ public abstract class AbstractMybatisDataPermissionEntityService<ID, T extends D
|
|||
}
|
||||
|
||||
@Override
|
||||
public void permissionUpdated(String... ids)
|
||||
public void authorizationUpdated(String resourceType, String... resources)
|
||||
{
|
||||
for (String id : ids)
|
||||
this.permissionCache.evictImmediately(toPermissionCacheKeyOfStr(id));
|
||||
if (!getResourceType().equals(resourceType))
|
||||
return;
|
||||
|
||||
for (String res : resources)
|
||||
this.permissionCache.evictImmediately(toPermissionCacheKeyOfStr(res));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void permissionUpdated()
|
||||
{
|
||||
this.permissionCache.invalidate();
|
||||
}
|
||||
|
||||
protected void setDataFilterParam(Map<String, Object> params, String dataFilter)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
package org.datagear.management.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -744,6 +745,24 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
|
|||
return StringUtil.isEmpty(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果元素不为{@code null},才将其添加至集合。
|
||||
*
|
||||
* @param <E>
|
||||
* @param collection
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
protected <E> boolean addIfNonNull(Collection<E> collection, E element)
|
||||
{
|
||||
if (element == null)
|
||||
return false;
|
||||
|
||||
collection.add(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串是否为空。
|
||||
*
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2018 datagear.tech
|
||||
*
|
||||
* Licensed under the LGPLv3 license:
|
||||
* http://www.gnu.org/licenses/lgpl-3.0.html
|
||||
*/
|
||||
|
||||
package org.datagear.management.service.impl;
|
||||
|
||||
import org.datagear.management.service.AuthorizationListener;
|
||||
|
||||
/**
|
||||
* {@linkplain AuthorizationListener}相关类。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public interface AuthorizationListenerAware
|
||||
{
|
||||
/**
|
||||
* 获取{@linkplain AuthorizationListener}。
|
||||
*
|
||||
* @return 可能为{@code null}
|
||||
*/
|
||||
AuthorizationListener getAuthorizationListener();
|
||||
|
||||
/**
|
||||
* 设置{@linkplain AuthorizationListener}。
|
||||
*
|
||||
* @param authorizationListener
|
||||
* 允许为{@code null}
|
||||
*/
|
||||
void setAuthorizationListener(AuthorizationListener authorizationListener);
|
||||
}
|
|
@ -15,6 +15,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
|||
import org.datagear.management.domain.Authorization;
|
||||
import org.datagear.management.domain.DataPermissionEntity;
|
||||
import org.datagear.management.domain.User;
|
||||
import org.datagear.management.service.AuthorizationListener;
|
||||
import org.datagear.management.service.AuthorizationService;
|
||||
import org.datagear.management.service.DataPermissionEntityService;
|
||||
import org.datagear.management.util.dialect.MbSqlDialect;
|
||||
|
@ -27,12 +28,14 @@ import org.mybatis.spring.SqlSessionTemplate;
|
|||
*
|
||||
*/
|
||||
public class AuthorizationServiceImpl extends AbstractMybatisEntityService<String, Authorization>
|
||||
implements AuthorizationService
|
||||
implements AuthorizationService, AuthorizationListenerAware
|
||||
{
|
||||
protected static final String SQL_NAMESPACE = Authorization.class.getName();
|
||||
|
||||
private List<? extends DataPermissionEntityService<?, ?>> resourceServices;
|
||||
|
||||
private AuthorizationListener authorizationListener = null;
|
||||
|
||||
public AuthorizationServiceImpl()
|
||||
{
|
||||
super();
|
||||
|
@ -62,11 +65,23 @@ public class AuthorizationServiceImpl extends AbstractMybatisEntityService<Strin
|
|||
this.resourceServices = resourceServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationListener getAuthorizationListener()
|
||||
{
|
||||
return authorizationListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthorizationListener(AuthorizationListener authorizationListener)
|
||||
{
|
||||
this.authorizationListener = authorizationListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Authorization entity)
|
||||
{
|
||||
super.add(entity);
|
||||
permissionUpdated(entity.getResourceType(), entity.getResource());
|
||||
authorizationUpdated(entity.getResourceType(), entity.getResource());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,7 +90,7 @@ public class AuthorizationServiceImpl extends AbstractMybatisEntityService<Strin
|
|||
Authorization authorization = getById(id);
|
||||
|
||||
if (authorization != null)
|
||||
permissionUpdated(authorization.getResourceType(), authorization.getResource());
|
||||
authorizationUpdated(authorization.getResourceType(), authorization.getResource());
|
||||
|
||||
return super.deleteById(id);
|
||||
}
|
||||
|
@ -110,7 +125,7 @@ public class AuthorizationServiceImpl extends AbstractMybatisEntityService<Strin
|
|||
int count = updateMybatis("deleteByIdsForResource", params);
|
||||
|
||||
if (count > 0)
|
||||
permissionUpdated(resourceType, resource);
|
||||
authorizationUpdated(resourceType, resource);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -125,7 +140,7 @@ public class AuthorizationServiceImpl extends AbstractMybatisEntityService<Strin
|
|||
int count = updateMybatis("deleteByResource", params);
|
||||
|
||||
if (count > 0)
|
||||
permissionUpdated(resourceType, resources);
|
||||
authorizationUpdated(resourceType, resources);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -159,12 +174,10 @@ public class AuthorizationServiceImpl extends AbstractMybatisEntityService<Strin
|
|||
return context;
|
||||
}
|
||||
|
||||
protected void permissionUpdated(String resourceType, String... resources)
|
||||
protected void authorizationUpdated(String resourceType, String... resources)
|
||||
{
|
||||
DataPermissionEntityService<?, ?> resourceService = getResourceService(resourceType);
|
||||
|
||||
if (resourceService != null)
|
||||
resourceService.permissionUpdated(resources);
|
||||
if (this.authorizationListener != null)
|
||||
this.authorizationListener.authorizationUpdated(resourceType, resources);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2018 datagear.tech
|
||||
*
|
||||
* Licensed under the LGPLv3 license:
|
||||
* http://www.gnu.org/licenses/lgpl-3.0.html
|
||||
*/
|
||||
|
||||
package org.datagear.management.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.datagear.management.service.AuthorizationListener;
|
||||
|
||||
/**
|
||||
* 打包一起的{@linkplain AuthorizationListener}。
|
||||
*
|
||||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public class BundleAuthorizationListener implements AuthorizationListener
|
||||
{
|
||||
private Collection<AuthorizationListener> authorizationListeners = null;
|
||||
|
||||
public BundleAuthorizationListener()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public BundleAuthorizationListener(Collection<AuthorizationListener> authorizationListeners)
|
||||
{
|
||||
super();
|
||||
this.authorizationListeners = authorizationListeners;
|
||||
}
|
||||
|
||||
public Collection<AuthorizationListener> getAuthorizationListeners()
|
||||
{
|
||||
return authorizationListeners;
|
||||
}
|
||||
|
||||
public void setAuthorizationListeners(Collection<AuthorizationListener> authorizationListeners)
|
||||
{
|
||||
this.authorizationListeners = authorizationListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authorizationUpdated(String resourceType, String... resources)
|
||||
{
|
||||
if (this.authorizationListeners == null)
|
||||
return;
|
||||
|
||||
for (AuthorizationListener al : this.authorizationListeners)
|
||||
al.authorizationUpdated(resourceType, resources);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void permissionUpdated()
|
||||
{
|
||||
if (this.authorizationListeners == null)
|
||||
return;
|
||||
|
||||
for (AuthorizationListener al : this.authorizationListeners)
|
||||
al.permissionUpdated();
|
||||
}
|
||||
}
|
|
@ -359,6 +359,8 @@ public class HtmlChartWidgetEntityServiceImpl
|
|||
if (chartDataSetVOs == null || chartDataSetVOs.length == 0)
|
||||
return;
|
||||
|
||||
List<ChartDataSetVO> list = new ArrayList<ChartDataSetVO>(chartDataSetVOs.length);
|
||||
|
||||
for (int i = 0; i < chartDataSetVOs.length; i++)
|
||||
{
|
||||
ChartDataSetVO vo = chartDataSetVOs[i];
|
||||
|
@ -372,6 +374,8 @@ public class HtmlChartWidgetEntityServiceImpl
|
|||
dataSet = this.dataSetEntityService.getById(dataSetId);
|
||||
|
||||
vo.setDataSet(dataSet);
|
||||
|
||||
addIfNonNull(list, (vo.getDataSet() == null ? null : vo));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
|||
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.datagear.management.domain.Role;
|
||||
import org.datagear.management.service.AuthorizationListener;
|
||||
import org.datagear.management.service.DeleteBuiltinRoleDeniedException;
|
||||
import org.datagear.management.service.RoleService;
|
||||
import org.datagear.management.util.dialect.MbSqlDialect;
|
||||
|
@ -24,10 +25,13 @@ import org.mybatis.spring.SqlSessionTemplate;
|
|||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public class RoleServiceImpl extends AbstractMybatisEntityService<String, Role> implements RoleService
|
||||
public class RoleServiceImpl extends AbstractMybatisEntityService<String, Role>
|
||||
implements RoleService, AuthorizationListenerAware
|
||||
{
|
||||
protected static final String SQL_NAMESPACE = Role.class.getName();
|
||||
|
||||
private AuthorizationListener authorizationListener = null;
|
||||
|
||||
public RoleServiceImpl()
|
||||
{
|
||||
super();
|
||||
|
@ -43,6 +47,18 @@ public class RoleServiceImpl extends AbstractMybatisEntityService<String, Role>
|
|||
super(sqlSessionTemplate, dialect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationListener getAuthorizationListener()
|
||||
{
|
||||
return authorizationListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthorizationListener(AuthorizationListener authorizationListener)
|
||||
{
|
||||
this.authorizationListener = authorizationListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Role> getByIds(String... ids)
|
||||
{
|
||||
|
@ -54,13 +70,29 @@ public class RoleServiceImpl extends AbstractMybatisEntityService<String, Role>
|
|||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean update(Role entity, Map<String, Object> params)
|
||||
{
|
||||
boolean updated = super.update(entity, params);
|
||||
|
||||
if (updated && this.authorizationListener != null)
|
||||
this.authorizationListener.permissionUpdated();
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean deleteById(String id, Map<String, Object> params)
|
||||
{
|
||||
if (Role.isBuiltinRole(id))
|
||||
throw new DeleteBuiltinRoleDeniedException(id);
|
||||
|
||||
return super.deleteById(id, params);
|
||||
boolean deleted = super.deleteById(id, params);
|
||||
|
||||
if (deleted && this.authorizationListener != null)
|
||||
this.authorizationListener.permissionUpdated();
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Set;
|
|||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.datagear.management.domain.Role;
|
||||
import org.datagear.management.domain.User;
|
||||
import org.datagear.management.service.AuthorizationListener;
|
||||
import org.datagear.management.service.RoleService;
|
||||
import org.datagear.management.service.UserService;
|
||||
import org.datagear.management.util.dialect.MbSqlDialect;
|
||||
|
@ -28,7 +29,8 @@ import org.mybatis.spring.SqlSessionTemplate;
|
|||
* @author datagear@163.com
|
||||
*
|
||||
*/
|
||||
public class UserServiceImpl extends AbstractMybatisEntityService<String, User> implements UserService
|
||||
public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
|
||||
implements UserService, AuthorizationListenerAware
|
||||
{
|
||||
protected static final String SQL_NAMESPACE = User.class.getName();
|
||||
|
||||
|
@ -36,6 +38,8 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
|
|||
|
||||
private UserPasswordEncoder userPasswordEncoder = null;
|
||||
|
||||
private AuthorizationListener authorizationListener = null;
|
||||
|
||||
public UserServiceImpl()
|
||||
{
|
||||
super();
|
||||
|
@ -75,6 +79,18 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
|
|||
this.userPasswordEncoder = userPasswordEncoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizationListener getAuthorizationListener()
|
||||
{
|
||||
return authorizationListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthorizationListener(AuthorizationListener authorizationListener)
|
||||
{
|
||||
this.authorizationListener = authorizationListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getByName(String name)
|
||||
{
|
||||
|
@ -148,8 +164,13 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
|
|||
|
||||
Boolean ignoreRole = (Boolean) params.get("ignoreRole");
|
||||
if (ignoreRole == null || !ignoreRole.booleanValue())
|
||||
{
|
||||
saveUserRoles(entity);
|
||||
|
||||
if (this.authorizationListener != null)
|
||||
this.authorizationListener.permissionUpdated();
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
@ -230,7 +251,7 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
|
|||
for (Role role : roles)
|
||||
{
|
||||
role = this.roleService.getById(role.getId());
|
||||
rolesNew.add(role);
|
||||
addIfNonNull(rolesNew, role);
|
||||
}
|
||||
|
||||
obj.setRoles(rolesNew);
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.datagear.dataexchange.support.SqlDataExportService;
|
|||
import org.datagear.dataexchange.support.SqlDataImportService;
|
||||
import org.datagear.management.dbversion.DbVersionManager;
|
||||
import org.datagear.management.service.AnalysisProjectService;
|
||||
import org.datagear.management.service.AuthorizationListener;
|
||||
import org.datagear.management.service.AuthorizationService;
|
||||
import org.datagear.management.service.DataPermissionEntityService;
|
||||
import org.datagear.management.service.DataSetEntityService;
|
||||
|
@ -64,7 +65,9 @@ import org.datagear.management.service.UserService;
|
|||
import org.datagear.management.service.impl.AbstractMybatisDataPermissionEntityService;
|
||||
import org.datagear.management.service.impl.AbstractMybatisEntityService;
|
||||
import org.datagear.management.service.impl.AnalysisProjectServiceImpl;
|
||||
import org.datagear.management.service.impl.AuthorizationListenerAware;
|
||||
import org.datagear.management.service.impl.AuthorizationServiceImpl;
|
||||
import org.datagear.management.service.impl.BundleAuthorizationListener;
|
||||
import org.datagear.management.service.impl.DataSetEntityServiceImpl;
|
||||
import org.datagear.management.service.impl.DataSetResDirectoryServiceImpl;
|
||||
import org.datagear.management.service.impl.HtmlChartWidgetEntityServiceImpl;
|
||||
|
@ -742,6 +745,7 @@ public class CoreConfig implements ApplicationListener<ContextRefreshedEvent>
|
|||
ApplicationContext context = event.getApplicationContext();
|
||||
|
||||
initAuthorizationResourceServices(context);
|
||||
initAuthorizationListenerAwares(context);
|
||||
initServiceCaches(context);
|
||||
initDevotedDataExchangeServices(context);
|
||||
}
|
||||
|
@ -752,9 +756,23 @@ public class CoreConfig implements ApplicationListener<ContextRefreshedEvent>
|
|||
Map<String, DataPermissionEntityService> dataPermissionEntityServices = context
|
||||
.getBeansOfType(DataPermissionEntityService.class);
|
||||
|
||||
List<DataPermissionEntityService<?, ?>> resourceServices = this.authorizationResourceServices();
|
||||
for (DataPermissionEntityService<?, ?> dps : dataPermissionEntityServices.values())
|
||||
resourceServices.add(dps);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DataPermissionEntityService> resourceServices = (List) this.authorizationResourceServices();
|
||||
resourceServices.addAll(dataPermissionEntityServices.values());
|
||||
}
|
||||
|
||||
protected void initAuthorizationListenerAwares(ApplicationContext context)
|
||||
{
|
||||
Map<String, AuthorizationListener> listenerMap = context.getBeansOfType(AuthorizationListener.class);
|
||||
List<AuthorizationListener> listenerList = new ArrayList<AuthorizationListener>(
|
||||
listenerMap.size());
|
||||
listenerList.addAll(listenerMap.values());
|
||||
|
||||
AuthorizationListener listener = new BundleAuthorizationListener(listenerList);
|
||||
|
||||
Map<String, AuthorizationListenerAware> awareMap = context.getBeansOfType(AuthorizationListenerAware.class);
|
||||
for (AuthorizationListenerAware aware : awareMap.values())
|
||||
aware.setAuthorizationListener(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
|
Loading…
Reference in New Issue