/* * JBoss, Home of Professional Open Source * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.seam.wiki.core.action; import org.jboss.seam.Component; import org.jboss.seam.ScopeType; import static org.jboss.seam.annotations.Install.APPLICATION; import org.jboss.seam.annotations.*; import org.jboss.seam.annotations.intercept.BypassInterceptors; import org.jboss.seam.core.Events; import org.jboss.seam.security.AuthorizationException; import org.jboss.seam.security.Identity; import org.jboss.seam.wiki.core.model.*; import org.jboss.seam.wiki.core.model.Role; /** * Need this until Drools fixes bugs and becomes usable/debuggable. * */ @Name("org.jboss.seam.security.identity") @Scope(ScopeType.SESSION) @BypassInterceptors @Install(precedence=APPLICATION) @AutoCreate @Startup public class WikiIdentity extends Identity { private User currentUser; private Integer currentAccessLevel; // We don't care if a user is logged in, just check it... public void checkRestriction(String expr) { if (!evaluateExpression(expr)) { Events.instance().raiseEvent("org.jboss.seam.notAuthorized"); throw new AuthorizationException(String.format( "Authorization check failed for expression [%s]", expr)); } } public boolean hasPermission(String name, String action, Object... args) { currentUser = (User)Component.getInstance("currentUser"); currentAccessLevel = (Integer)Component.getInstance("currentAccessLevel"); if (args == null || args.length == 0) { // All the security checks currently need arguments... return false; } if ("Node".equals(name) && "create".equals(action)) { return checkCreateAccess( (WikiNode)args[0]); } else if ("Node".equals(name) && "edit".equals(action)) { return checkEditAccess((WikiNode)args[0]); } else if ("Node".equals(name) && "read".equals(action)) { return checkReadAccess((WikiNode)args[0]); } else if ("Node".equals(name) && "changeAccessLevel".equals(action)) { return checkRaiseAccessLevel((WikiNode)args[0]); } else if ("User".equals(name) && "edit".equals(action)) { return checkEditUser((User)args[0]); } else if ("User".equals(name) && "delete".equals(action)) { return checkDeleteUser((User)args[0]); } else if ("User".equals(name) && "editRoles".equals(action)) { return checkEditUserRoles((User)args[0]); } else if ("Node".equals(name) && "editMenu".equals(action)) { return checkEditMenu((WikiNode)args[0]); } else if ("User".equals(name) && "isAdmin".equals(action)) { return checkIsAdmin((User)args[0]); } else if ("Comment".equals(name) && "create".equals(action)) { return checkCommentCreate((WikiDocument)args[0]); } else if ("Comment".equals(name) && "reportSpam".equals(action)) { return checkCommentReportSpam((WikiNode)args[0]); } if ("Comment".equals(name) && "delete".equals(action)) { return checkCommentDelete((WikiNode)args[0]); } else if ("Trash".equals(name) && "empty".equals(action)) { return checkTrashEmpty((WikiDirectory)args[0]); } else if ("Feed".equals(name) && "write".equals(action)) { return checkFeedWrite((WikiFeed)args[0]); } return false; } /* User either needs to have the access level of the parent directory or the user is the creator of the parent directory */ private boolean checkCreateAccess(WikiNode directory) { //if (directory.getId().equals(wikiPrefs.getMemberAreaId())) return false; // Member home dir is immutable if (directory.getWriteAccessLevel() == Role.GUESTROLE_ACCESSLEVEL) return true; int dirWriteAccessLevel = directory.getWriteAccessLevel(); User dirCreator = directory.getCreatedBy(); if ( currentAccessLevel >= dirWriteAccessLevel || currentUser.getId().equals(dirCreator.getId()) ) return true; return false; } /* User either needs to have the access level of the edited node or has to be the creator */ private boolean checkReadAccess(WikiNode node) { if (node.getReadAccessLevel() == Role.GUESTROLE_ACCESSLEVEL) return true; int nodeReadAccessLevel = node.getReadAccessLevel(); User nodeCreator = node.getCreatedBy(); if (currentAccessLevel >= nodeReadAccessLevel || currentUser.getId().equals(nodeCreator.getId()) ) return true; return false; } /* User either needs to have the access level of the edited node or has to be the creator, if the node is write protected, he needs to be admin. */ private boolean checkEditAccess(WikiNode node) { if (node.isWriteProtected() && currentAccessLevel != Role.ADMINROLE_ACCESSLEVEL) return false; if (node.getWriteAccessLevel() == Role.GUESTROLE_ACCESSLEVEL) return true; int nodeWriteAccessLevel = node.getWriteAccessLevel(); User nodeCreator = node.getCreatedBy(); if (currentAccessLevel >= nodeWriteAccessLevel || currentUser.getId().equals(nodeCreator.getId()) ) return true; return false; } /* User can't persist or update a node and assign a higher access level than he has, unless he is the creator */ private boolean checkRaiseAccessLevel(WikiNode node) { //if (node.getId() != null && node.getId().equals(wikiPrefs.getMemberAreaId())) return false; // Member home dir is immutable int desiredWriteAccessLevel = node.getWriteAccessLevel(); int desiredReadAccessLevel = node.getReadAccessLevel(); User nodeCreator = node.getCreatedBy(); if ( ( desiredReadAccessLevel <= currentAccessLevel && desiredWriteAccessLevel <= currentAccessLevel ) || ( nodeCreator == null || currentUser.getId().equals(nodeCreator.getId()) ) ) return true; return false; } /* Only admins can change roles of a user */ private boolean checkEditUserRoles(User currentUser) { return currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL; } /* Only admins can edit users, or the user himself */ private boolean checkEditUser(User user) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; if (currentUser.getId().equals(user.getId())) return true; return false; } /* Only admins can delete users and some users can't be deleted */ private boolean checkDeleteUser(User user) { // Can't delete admin and guest accounts User adminUser = (User)Component.getInstance("adminUser"); User guestUser = (User)Component.getInstance("guestUser"); if (adminUser.getId().equals(user.getId())) return false; if (guestUser.getId().equals(user.getId())) return false; if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; return false; } /* Admins can edit all menus, owners can edit their own. */ private boolean checkEditMenu(WikiNode node) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; if (node.getCreatedBy().getId().equals(currentUser.getId())) return true; return false; } /* Only admins are admins */ private boolean checkIsAdmin(User user) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; return false; } /* Only admins or enabled documents allow comments, if you can read the document. */ private boolean checkCommentCreate(WikiDocument doc) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; if (doc.getReadAccessLevel() <= currentAccessLevel && currentAccessLevel > Role.GUESTROLE_ACCESSLEVEL && doc.isEnableComments() && doc.isEnableCommentForm()) return true; return false; } private boolean checkCommentReportSpam(WikiNode node) { if (currentAccessLevel > Role.GUESTROLE_ACCESSLEVEL) return true; return false; } /* Only admins can delete comments. */ private boolean checkCommentDelete(WikiNode node) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; return false; } /* Only admins can empty the trash */ private boolean checkTrashEmpty(WikiDirectory trashArea) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; return false; } /* Only admins can write to feed or users who have write permission on the associated dir. */ private boolean checkFeedWrite(WikiFeed feed) { if (currentAccessLevel == Role.ADMINROLE_ACCESSLEVEL) return true; return feed.getDirectory().getWriteAccessLevel() <= currentAccessLevel; } }