if (pc.canAccess (SecurityConstants.PERM_FORUM, Integer.toString(forum.getId()))) {
forums.add(forum); //如果有权控制板块,则添加到返回列表
}
正如字面意思pc是权限控制,先看net.jforum.security/PermissionControl.java
private RoleCollection roles;//权限集合
private transient GroupSecurityDAO smodel;//组权限数据表
这里有两个属性,一个是权力集合,一个是组权限数据表,暂时没看懂有什么用。
public boolean canAccess(String roleName, String roleValue)
{
Role role = this.roles.get(roleName);
if (role == null) {
return false;
}
return role.getValues ().contains(new RoleValue(roleValue));
}
根据Category.java中的调用语句看,canAccess()的两个参数,一个是'perm_fourm',另一个是板块的ID。而在canAccess()这里,先根据perm_fourm获取一个Role,rol.getValues()是什么?
根据net.jforum.security/role.java
public RoleValueCollection getValues()
{
return this. roleValues ;
}
private final RoleValueCollection roleValues = new RoleValueCollection();
就是说,一个role 对应多个RoleValue ,而fourm_id也可能是一个RoleValue
pc.canAccess()就是判断role中是否包含指定的RoleValue。
再根据本页第一句,看net.jforum.security/SecurityRepository.java
public static PermissionControl get(int userId)
{ //从缓存中读权限控制
PermissionControl pc = (PermissionControl)cache.get(FQN, Integer.toString(userId));
if (pc == null) { //缓存中没有
try {
pc = load (userId); //取用户权限
}
catch (Exception e) {
throw new SecurityLoadException(e);
}
}
public static PermissionControl load(int userId)
{
return SecurityRepository. load (userId, false);
}
好绕啊。
public static PermissionControl load(int userId, boolean force)
{
if (force || cache.get(FQN, Integer.toString(userId)) == null) { //强制重取或缓存中没有
UserDAO um = DataAccessDriver.getInstance().newUserDAO();
return SecurityRepository. load (um.selectById(userId), force);
}
return SecurityRepository.get(userId);
}
再看
public static PermissionControl load(User user, boolean force)
{
String userId = Integer.toString(user.getId());
if (force || cache.get(FQN, userId) == null) { //强制重取或缓存中没有
PermissionControl pc = new PermissionControl();
// load roles
GroupSecurityDAO dao = DataAccessDriver.getInstance().newGroupSecurityDAO();
pc.setRoles(dao. loadRolesByUserGroups (user)); //从用户所在的组中取权限
cache.add(FQN, userId, pc);
return pc;
}
return SecurityRepository.get(user.getId());
}
再找doa.loadRolesByUserGroups(),在net.jforum.dao.generic.security\GenericGroupSecurityDAO.java中
public RoleCollection loadRolesByUserGroups(User user)
{
List groups = user.getGroupsList(); //取用户的所有组
// When the user is associated to more than one group, we
// should check the merged roles
int[] groupIds = this.getSortedGroupIds(groups); //对组排序
RoleCollection groupRoles = RolesRepository.getGroupRoles(groupIds); //从缓存中根据组取权限
// Not cached yet? then do it now
if (groupRoles == null) { //缓存中没有
groupRoles = this. loadRoles (groupIds); //从数据表中取所有组的权限
RolesRepository.addGroupRoles(groupIds, groupRoles); //将所有组ID及组权限写入缓存中
}
return groupRoles;
}
再看从数据表中取组权限的过程:
protected RoleCollection loadRoles(int[] groupIds) //从数据表中取所有组的权限
{
String sql = SystemGlobals.getSql("PermissionControl.loadGroupRoles"); //取sql语句
String groupIdAsString = SecurityCommon.groupIdAsString(groupIds); //将组ID转成适合SQL语句的字符型
if ("".equals(groupIdAsString)) {
// We suppose there is no "negative" group ids
sql = sql.replaceAll("#IN#","-1");
}
else { //将组ID加入SQL语句。
sql = sql.replaceAll("#IN#", groupIdAsString);
}
RoleCollection roles = null;
PreparedStatement p = null;
ResultSet rs = null;
try {
p = JForumExecutionContext.getConnection().prepareStatement(sql);
rs = p.executeQuery();
roles = SecurityCommon. loadRoles (rs); //将SQL执行结果转为roles
}
catch (SQLException e) {
throw new DatabaseException(e);
}
finally {
DbUtils.close(rs, p);
}
return roles;
}
查看net.jforum.dao.generic.security/SecurityCommon.java
public static RoleCollection loadRoles(ResultSet rs)
{
RoleCollection rc = new RoleCollection();
try {
Role r = null;
String lastName = null;
while (rs.next()) {
String currentName = rs.getString("name'); //当前规则名称
if (!currentName.equals(lastName)) { //当前规则名称与最后规则名称不同
if (r != null) {
rc.add(r); //将规则加入返回集,首次不同由于r的初始值为null,因此不会加入
}
r = new Role();
r.setName(rs.getString("name")); //设置规则名称,那么ID呢?没看到设置role的ID啊。
lastName = currentName; //最后规则名称刷新为当前规则名称
}
String roleValue = rs.getString("role_value");
if (!rs.wasNull() && StringUtils.isNotBlank(roleValue)) {
r.getValues().add(new RoleValue(roleValue)); //设置role的rolevalue
}
}
if (r != null) {
rc.add(r);//将循环后最后一个role放入结果集
}
return rc;
}
catch (SQLException e) {
throw new DatabaseException(e);
}
}
总结一下,role中有多个rolevalue.取权限的语句在"PermissionControl.loadGroupRoles" 中