/** * Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php */ package org.ralasafe.privilege; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import org.ralasafe.EntityExistException; import org.ralasafe.Factory; import org.ralasafe.RalasafeException; import org.ralasafe.ResourceConstants; import org.ralasafe.db.DBLevelException; import org.ralasafe.db.DBPower; import org.ralasafe.db.FieldWhereElement; import org.ralasafe.db.JavaBeanColumnAdapter; import org.ralasafe.db.JavaBeanObjectNewer; import org.ralasafe.db.SelectCondition; import org.ralasafe.db.SingleValueComparator; import org.ralasafe.db.Table; import org.ralasafe.db.TableNewer; import org.ralasafe.db.TableUpdator; import org.ralasafe.db.impl.TableDeletorImpl; import org.ralasafe.db.impl.TableSaverImpl; import org.ralasafe.db.impl.TableSelectorImpl; import org.ralasafe.db.impl.TableUpdatorImpl; import org.ralasafe.group.Node; import org.ralasafe.util.DBUtil; import org.ralasafe.util.Util; public class PrivilegeManagerImpl implements PrivilegeManager { private Privilege businessPrivilegeTree; private Privilege nonRolePrivilegeTree; private Map allBusinessPrivilegesMap; private Map allNonRolePrivilegesMap; private boolean businessPrivilegeTreeChanged = true; private boolean nonRolePrivilegeTreeChanged = true; private String appName; private String tableName; private Table table; private TableSelectorImpl selector; private TableSaverImpl saver; private TableUpdator updator; private TableDeletorImpl deletor; public PrivilegeManagerImpl(String appName) { this.appName = appName; this.tableName = appName + "_privilege"; TableNewer newer = new TableNewer(); newer.setTableName(tableName); newer.setColumnNames(new String[] { "id", "pid", "name", "description", "isleaf", "display", "decisionPolicyCombAlg", "queryPolicyCombAlg", "type", "constantName", "url", "target", "orderNum" }); newer.setIdColumnNames(new String[] { "id" }); newer.setUniqueColumnNames(new String[] { "name" }); newer.setMappingClass(Privilege.class.getName()); newer.put("id", new JavaBeanColumnAdapter("id", "int")); newer.put("pid", new JavaBeanColumnAdapter("pid", "int")); newer.put("name", new JavaBeanColumnAdapter( "name", "java.lang.String")); newer.put("description", new JavaBeanColumnAdapter( "description", "java.lang.String")); newer.put("isleaf", new JavaBeanColumnAdapter("isLeaf", "boolean")); newer.put("display", new JavaBeanColumnAdapter("display", "boolean")); newer.put("decisionPolicyCombAlg", new JavaBeanColumnAdapter( "decisionPolicyCombAlg", "int")); newer.put("queryPolicyCombAlg", new JavaBeanColumnAdapter( "queryPolicyCombAlg", "int")); newer.put("type", new JavaBeanColumnAdapter("type", "int")); newer.put("constantName", new JavaBeanColumnAdapter("constantName", "java.lang.String")); newer.put("url", new JavaBeanColumnAdapter("url", "java.lang.String")); newer.put("target", new JavaBeanColumnAdapter("target", "java.lang.String")); newer.put("orderNum", new JavaBeanColumnAdapter("orderNum", "int")); newer.setId(DBPower.getTableId(null, newer.getTableName())); table = newer.getTable(); selector = new TableSelectorImpl(); selector .setObjectNewer(new JavaBeanObjectNewer(newer.getMappingClass())); saver = new TableSaverImpl(); updator = new TableUpdatorImpl(); deletor = new TableDeletorImpl(); selector.setTable(table); saver.setTable(table); updator.setTable(table); deletor.setTable(table); } public void addReservedPrivilege(Locale locale) { try { addRalasafeAdminPrivilege(locale); addPolicyAdminPrivilege(locale); addAssignRoleToUserPrivilege(locale); addRoleAdminPrivilege(locale); businessPrivilegeTreeChanged = true; } catch (EntityExistException e) { throw new RalasafeException(e); } } private void addRalasafeAdminPrivilege(Locale locale) throws EntityExistException { Privilege privilege = new Privilege(); privilege.setType(Privilege.BUSINESS_PRIVILEGE); privilege.setIsLeaf(false); privilege.setId(Privilege.RALASAFE_ADMIN_ID); privilege.setPid(Privilege.BUSINESS_PRIVILEGE_TREE_ROOT_ID); privilege.setName(Util.getMessage(locale, ResourceConstants.RALASAFE_ADMIN)); privilege.setOrderNum(0); saver.save(privilege); } private void addPolicyAdminPrivilege(Locale locale) throws EntityExistException { Privilege privilege = new Privilege(); privilege.setType(Privilege.BUSINESS_PRIVILEGE); privilege.setIsLeaf(true); privilege.setId(Privilege.POLICY_ADMIN_ID); privilege.setPid(Privilege.RALASAFE_ADMIN_ID); privilege.setDescription(Util.getMessage(locale, ResourceConstants.POLICY_ADMIN_DESCRIPTION)); privilege.setName(Util.getMessage(locale, ResourceConstants.POLICY_ADMIN)); privilege.setConstantName("POLICY_ADMIN"); privilege.setOrderNum(1); saver.save(privilege); } private void addAssignRoleToUserPrivilege(Locale locale) throws EntityExistException { Privilege privilege = new Privilege(); privilege.setType(Privilege.BUSINESS_PRIVILEGE); privilege.setIsLeaf(true); privilege.setId(Privilege.ASSIGN_ROLE_TO_USER_ID); privilege.setPid(Privilege.RALASAFE_ADMIN_ID); privilege.setName(Util.getMessage(locale, ResourceConstants.ASSIGN_ROLE_TO_USER)); privilege.setConstantName("ASSIGN_ROLE_TO_USER"); privilege.setOrderNum(2); saver.save(privilege); } private void addRoleAdminPrivilege(Locale locale) throws EntityExistException { Privilege privilege = new Privilege(); privilege.setType(Privilege.BUSINESS_PRIVILEGE); privilege.setIsLeaf(true); privilege.setId(Privilege.ROLE_ADMIN_ID); privilege.setPid(Privilege.RALASAFE_ADMIN_ID); privilege .setName(Util.getMessage(locale, ResourceConstants.ROLE_ADMIN)); privilege.setConstantName("ROLE_ADMIN"); privilege.setOrderNum(3); saver.save(privilege); } public Privilege addPrivilege(Privilege pvlg) throws EntityExistException { int pid = pvlg.getPid(); Privilege parentPvlg = null; if (pvlg.getType() == Privilege.BUSINESS_PRIVILEGE) { buildBusinessPrivilegeTree(); parentPvlg = (Privilege) allBusinessPrivilegesMap.get(new Integer( pid)); } else if (pvlg.getType() == Privilege.NON_ROLE_PRIVILEGE) { buildNonRolePrivilegeTree(); parentPvlg = (Privilege) allNonRolePrivilegesMap.get(new Integer( pid)); } int orderNum = -1; // get the greatest orderNum if (parentPvlg != null && parentPvlg.getChildren() != null && parentPvlg.getChildren().size() > 0) { for (Iterator iter = parentPvlg.getChildren().iterator(); iter .hasNext();) { int temp = ((Privilege) iter.next()).getOrderNum(); orderNum = orderNum >= temp ? orderNum : temp; } } pvlg.setId(newPrivilegeId()); pvlg.setOrderNum(orderNum + 1); saver.save(pvlg); if (pvlg.getType() == Privilege.BUSINESS_PRIVILEGE) { businessPrivilegeTreeChanged = true; } else if (pvlg.getType() == Privilege.NON_ROLE_PRIVILEGE) { nonRolePrivilegeTreeChanged = true; } return pvlg; } private int newPrivilegeId() { try { return DBUtil.getSequenceNextVal(table, "id"); } catch (SQLException e) { throw new DBLevelException(e); } } public void deletePrivilege(int id) { if (id <= 0) { throw new RalasafeException("Cannot delete reserved privilege."); } // delete role-privilege relation infos RoleManager roleManager = Factory.getRoleManager(appName); roleManager.deleteRolePrivilegeByPrivilege(id); // delete privilege Privilege pvlg = getPrivilege(id); if (pvlg == null) { return; } deletor.deleteByIdColumns(pvlg); if (pvlg.getType() == Privilege.BUSINESS_PRIVILEGE) { businessPrivilegeTreeChanged = true; } else if (pvlg.getType() == Privilege.NON_ROLE_PRIVILEGE) { nonRolePrivilegeTreeChanged = true; } } public Collection getAllBusinessPrivileges() { buildBusinessPrivilegeTree(); return allBusinessPrivilegesMap.values(); } public Collection getAllBusinessPrivilegesFromDb() { FieldWhereElement emt = new FieldWhereElement(); emt.setColumn(table.getColumns()[8]); emt.setCompartor(SingleValueComparator.EQUAL); emt.setValue(new Integer(Privilege.BUSINESS_PRIVILEGE)); SelectCondition cdtn = new SelectCondition(); cdtn.setWhereElement(emt); return selector.select(cdtn, null); } public Collection getAllNonRolePrivileges() { buildNonRolePrivilegeTree(); return allNonRolePrivilegesMap.values(); } public Collection getAllNonRolePrivilegesFromDb() { FieldWhereElement emt = new FieldWhereElement(); emt.setColumn(table.getColumns()[8]); emt.setCompartor(SingleValueComparator.EQUAL); emt.setValue(new Integer(Privilege.NON_ROLE_PRIVILEGE)); SelectCondition cdtn = new SelectCondition(); cdtn.setWhereElement(emt); return selector.select(cdtn, null); } public Collection getLikelyPrivileges(String name) { buildBusinessPrivilegeTree(); buildNonRolePrivilegeTree(); Collection result=new LinkedList(); for( Iterator iter=allBusinessPrivilegesMap.values().iterator(); iter.hasNext(); ) { Privilege pvlg=(Privilege) iter.next(); if( pvlg.getName().contains( name ) ) { result.add( pvlg ); } } for( Iterator iter=allNonRolePrivilegesMap.values().iterator(); iter.hasNext(); ) { Privilege pvlg=(Privilege) iter.next(); if( pvlg.getName().contains( name ) ) { result.add( pvlg ); } } return result; // FieldWhereElement emt = new FieldWhereElement(); // emt.setColumn(table.getColumns()[2]); // emt.setCompartor(SingleValueComparator.LIKE); // emt.setContextValue(true); // SelectCondition cdtn = new SelectCondition(); // cdtn.setWhereElement(emt); // Privilege pvlg = new Privilege(); // pvlg.setName("%" + name + "%"); // return selector.select(cdtn, pvlg); } public Collection getLikelyPrivilegesByUrl(String url) { buildBusinessPrivilegeTree(); buildNonRolePrivilegeTree(); List result=new LinkedList(); for( Iterator iter=allBusinessPrivilegesMap.values().iterator(); iter.hasNext(); ) { Privilege pvlg=(Privilege) iter.next(); if( pvlg.getUrl()!=null && pvlg.getUrl().contains( url ) ) { result.add( pvlg ); } } for( Iterator iter=allNonRolePrivilegesMap.values().iterator(); iter.hasNext(); ) { Privilege pvlg=(Privilege) iter.next(); if( pvlg.getUrl()!=null && pvlg.getUrl().contains( url ) ) { result.add( pvlg ); } } Comparator comp = new Comparator() { public int compare(Object arg0, Object arg1) { Privilege p0 = (Privilege) arg0; Privilege p1 = (Privilege) arg1; String url0=p0.getUrl(); String url1=p1.getUrl(); if( url0==null ) { url0=""; } if( url1==null ) { url1=""; } return url0.compareTo( url1 ); } }; Collections.sort( result, comp ); return result; // FieldWhereElement emt = new FieldWhereElement(); // emt.setColumn(table.getColumns()[9]); // emt.setCompartor(SingleValueComparator.LIKE); // emt.setContextValue(true); // SelectCondition cdtn = new SelectCondition(); // cdtn.setWhereElement(emt); // OrderPart orderPart=new OrderPart(); // orderPart.setColumnNames( new String[]{"url"} ); // orderPart.setOrderTypes( new String[]{"desc"} ); // cdtn.setOrderPart( orderPart ); // Privilege pvlg = new Privilege(); // pvlg.setUrl("%" + url + "%"); // return selector.select(cdtn, pvlg); } public Privilege getPrivilege(int id) { buildBusinessPrivilegeTree(); buildNonRolePrivilegeTree(); Privilege nodeFromTree0 = (Privilege) allBusinessPrivilegesMap .get(new Integer(id)); Privilege nodeFromTree1 = (Privilege) allNonRolePrivilegesMap .get(new Integer(id)); return (nodeFromTree0 != null ? nodeFromTree0 : nodeFromTree1); } public void updatePrivilege(Privilege pvlg) throws EntityExistException { updator.updateByIdColumns(pvlg); if (pvlg.getType() == Privilege.BUSINESS_PRIVILEGE) { businessPrivilegeTreeChanged = true; } else if (pvlg.getType() == Privilege.NON_ROLE_PRIVILEGE) { nonRolePrivilegeTreeChanged = true; } } public void movePrivilege(Privilege privilege, Privilege target, int newOrderNum) { try { if (privilege.getId() <= 0) { throw new RalasafeException("Cannot move reserved privilege."); } privilege = getPrivilege(privilege.getId()); target = getPrivilege(target.getId()); if (privilege.getType() != target.getType()) { throw new RalasafeException( "Cannot move privilege out of the tree."); } if (target.getIsLeaf()) { throw new RalasafeException( "Canot move privilege to a leaf node."); } if (privilege == target || isCascadeChild(privilege.getId(), target.getId())) { throw new RalasafeException("This move will produce a cycle."); } Collection children = getChildren(target); ArrayList list = new ArrayList(); if (children != null) { list.addAll(children); } // If it still be a child of the original parent node if (privilege.getPid() == target.getId()) { list.remove(privilege); } privilege.setPid(target.getId()); // reset orderNum(s), and update to db list.add(newOrderNum, privilege); for (int i = 0, size = list.size(); i < size; i++) { Privilege p = (Privilege) list.get(i); p.setOrderNum(i); updator.updateByIdColumns(p); } if (target.getType() == Privilege.BUSINESS_PRIVILEGE) { businessPrivilegeTreeChanged = true; } else if (target.getType() == Privilege.NON_ROLE_PRIVILEGE) { nonRolePrivilegeTreeChanged = true; } } catch (EntityExistException e) { throw new DBLevelException(e); } } public void deletePrivilegeCascade(int nodeId) { Privilege current = getPrivilege(nodeId); Collection children = getAllChildren(current); // delete current node deletePrivilege(current.getId()); // delete cascade children nodes Iterator itr = children.iterator(); while (itr.hasNext()) { Node child = (Node) itr.next(); deletePrivilege(child.getId()); } if (current.getType() == Privilege.BUSINESS_PRIVILEGE) { businessPrivilegeTreeChanged = true; } else if (current.getType() == Privilege.NON_ROLE_PRIVILEGE) { nonRolePrivilegeTreeChanged = true; } } private Collection getAllChildren(Node current) { Set allChildren = new HashSet(); // direct children Collection children = current.getChildren(); allChildren.addAll(children); // find children of children Iterator itr = children.iterator(); while (itr.hasNext()) { Node child = (Node) itr.next(); // cascade allChildren.addAll(getAllChildren(child)); } return allChildren; } public Collection getChildren(Privilege privilege) { Privilege parent = getPrivilege(privilege.getId()); return parent.getChildren(); } public Privilege getParent(Privilege privilege) { Privilege child = getPrivilege(privilege.getId()); return (Privilege) child.getParent(); } public Privilege getBusinessPrivilegeTree() { buildBusinessPrivilegeTree(); return businessPrivilegeTree; } public Privilege getNonRolePrivilegeTree() { buildNonRolePrivilegeTree(); return nonRolePrivilegeTree; } public Privilege getTree(int nodeId) { return getPrivilege(nodeId); } public boolean isCascadeChild(int pId, int id) { Node parent = getPrivilege(pId); Node child = getPrivilege(id); if (parent != null && child != null) { while (child.getParent() != null) { if (parent.getId() == child.getPid()) return true; else child = child.getParent(); } } return false; } public boolean isChild(int pId, int id) { Node parent = getPrivilege(pId); Node child = getPrivilege(id); if (parent != null && child != null ) { if (parent.getId() == child.getPid()) return true; } return false; } private void buildTree(Collection privileges, Map allNodesMap) { // 1, Put all privilege into map Iterator itr = privileges.iterator(); while (itr.hasNext()) { Privilege privilege = (Privilege) itr.next(); allNodesMap.put(new Integer(privilege.getId()), privilege); } // 2, arrange child-parent relationship Privilege child; Privilege parent; itr = privileges.iterator(); while (itr.hasNext()) { child = (Privilege) itr.next(); parent = (Privilege) allNodesMap.get(new Integer(child.getPid())); if (parent != null) { parent.getChildren().add(child); child.setParent(parent); } } Comparator comp = new Comparator() { public int compare(Object arg0, Object arg1) { Privilege p0 = (Privilege) arg0; Privilege p1 = (Privilege) arg1; return p0.getOrderNum() - p1.getOrderNum(); } }; // 3, sort by orderNum for (Iterator iter = allNodesMap.values().iterator(); iter.hasNext();) { Privilege p = (Privilege) iter.next(); Collection children = p.getChildren(); if (children != null) { Collections.sort((List) children, comp); } } } private synchronized void buildBusinessPrivilegeTree() { if (!businessPrivilegeTreeChanged) return; businessPrivilegeTree = new Privilege(); businessPrivilegeTree.setId(Privilege.BUSINESS_PRIVILEGE_TREE_ROOT_ID); businessPrivilegeTree.setType(Privilege.BUSINESS_PRIVILEGE); businessPrivilegeTree.setIsLeaf(false); businessPrivilegeTree.setPid(Privilege.NULL_ROOT_ID); businessPrivilegeTree.setParent(null); allBusinessPrivilegesMap = new HashMap(); Collection privileges = getAllBusinessPrivilegesFromDb(); privileges.add(businessPrivilegeTree); buildTree(privileges, allBusinessPrivilegesMap); businessPrivilegeTreeChanged = false; } private synchronized void buildNonRolePrivilegeTree() { if (!nonRolePrivilegeTreeChanged) return; nonRolePrivilegeTree = new Privilege(); nonRolePrivilegeTree.setId(Privilege.NON_ROLE_PRIVILEGE_TREE_ROOT_ID); nonRolePrivilegeTree.setType(Privilege.NON_ROLE_PRIVILEGE); nonRolePrivilegeTree.setIsLeaf(false); nonRolePrivilegeTree.setPid(Privilege.NULL_ROOT_ID); nonRolePrivilegeTree.setParent(null); allNonRolePrivilegesMap = new HashMap(); Collection privileges = getAllNonRolePrivilegesFromDb(); privileges.add(nonRolePrivilegeTree); buildTree(privileges, allNonRolePrivilegesMap); nonRolePrivilegeTreeChanged = false; } }