package org.beangle.security.monitor.service;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.beangle.model.persist.impl.BaseServiceImpl;
import org.beangle.security.Group;
import org.beangle.security.Resource;
import org.beangle.security.User;
import org.beangle.security.monitor.service.AuthorityManager;
import org.beangle.security.service.AuthorityService;
import org.beangle.security.service.ResourceService;
import org.beangle.security.service.UserService;
public class DefaultAuthorityManager extends BaseServiceImpl implements
AuthorityManager {
/** [userId,groupIds[]] */
protected Map userGroupIds = new HashMap();
/** [groupId,parentGroupId] */
protected Map parentGroupIds = new HashMap();
/** 用户组权限 [groupId,actionIdSet] */
protected Map authorities = new HashMap();
/** 公开资源name */
protected Set<String> publicResources;
/** 公有资源id */
protected Set<Long> protectedResourceIds;
/** 所有资源map [resourceName,resourceId] */
protected Map resourceMap;
/** 授权服务 */
protected AuthorityService authorityService;
/** 资源服务 */
protected ResourceService resourceService;
/** 用户服务 */
protected UserService userService;
private boolean expired = true;
public boolean isPublic(String resourceName) {
if (expired) {
refreshResourceCache();
}
return publicResources.contains(resourceName);
}
/**
* 资源是否被授权<br>
* 1)检查是否是属于公有资源<br>
* 2)检查用户组权限<br>
*/
public boolean isAuthorized(Long userId, String resourceName) {
if (expired) {
refreshResourceCache();
}
Long resourceId = (Long) resourceMap.get(resourceName);
if (null == resourceId) {
return false;
}
if (protectedResourceIds.contains(resourceId)) {
return true;
}
Long[] groupIds = (Long[]) userGroupIds.get(userId);
if (null == groupIds) {
return false;
}
for (int i = 0; i < groupIds.length; i++) {
if (isAuthorizedByGroup(groupIds[i], resourceId)) {
return true;
}
}
return false;
}
/**
* 判断组内是否含有该资源
*
* @param groupId
* @param resourceId
* @return
*/
private boolean isAuthorizedByGroup(Long groupId, Long resourceId) {
Set actions = (Set) authorities.get(groupId);
boolean success = (null != actions && actions.contains(resourceId));
if (success) {
return success;
} else {
Long parentId = (Long) parentGroupIds.get(groupId);
if (null != parentId) {
return isAuthorizedByGroup(parentId, resourceId);
} else {
return false;
}
}
}
public void registerAuthorities(Long userId) {
User user = (User) entityDao.get(User.class, userId);
Set groups = userService.getGroups(user);
Long[] groupIds = new Long[groups.size()];
int i = 0;
for (Iterator iter = groups.iterator(); iter.hasNext();) {
Group group = (Group) iter.next();
registerGroupAuthorities(group);
groupIds[i++] = group.getId();
}
userGroupIds.put(user.getId(), groupIds);
}
public void registerGroupAuthorities(Group group) {
Set ra = authorityService.getResourceIds(group);
authorities.put(group.getId(), ra);
if (null != group.getParent()) {
parentGroupIds.put(group.getId(), group.getParent().getId());
registerGroupAuthorities(group.getParent());
}
logger.debug("add authorities for group:{} resource:{}", group.getName(), ra);
}
public void removeAuthorities(Long userId) {
logger.debug("remove authorities for userId:{}", userId);
if (null != userId) {
userGroupIds.remove(userId);
}
}
/**
* 加载三类资源
*/
public synchronized void refreshResourceCache() {
if (!expired)
return;
resourceMap = new HashMap();
publicResources = new HashSet();
protectedResourceIds = new HashSet();
List resources = resourceService.getResources();
for (Iterator iter = resources.iterator(); iter.hasNext();) {
Resource resource = (Resource) iter.next();
switch (resource.getScope()) {
case Resource.PUBLIC:
publicResources.add(resource.getName());
break;
case Resource.PROTECTED:
protectedResourceIds.add(resource.getId());
break;
}
resourceMap.put(resource.getName(), resource.getId());
}
expired = false;
logger.info("public resources loaded:{}",publicResources);
}
public Set getPublicResources() {
return publicResources;
}
public void setPublicResources(Set ignoreResources) {
this.publicResources = ignoreResources;
}
public void setAuthorityService(AuthorityService authorityService) {
this.authorityService = authorityService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void setResourceService(ResourceService resourceService) {
this.resourceService = resourceService;
}
}