学习 jForum笔记 三 .ForumAction 发现用户认证模板

来源:互联网 发布:佐治亚理工本科知乎 编辑:程序博客网 时间:2024/05/18 21:08
PermissionControl pc = SecurityRepository.get (userId); //权限控制
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"

原创粉丝点击