學習 jForum筆記 三 .ForumAction 發現用戶認證模板

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"

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章