/* * $Id: AccessControlList.java,v 1.6 2009/05/19 13:19:27 valdas Exp $ * Created on 28.12.2004 * * Copyright (C) 2004 Idega Software hf. All Rights Reserved. * * This software is the proprietary information of Idega hf. * Use is subject to license terms. */ package com.idega.slide.util; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.ListIterator; import java.util.logging.Logger; import org.apache.webdav.lib.Ace; import com.idega.util.CoreConstants; import com.idega.util.ListUtil; /** * * Last modified: $Date: 2009/05/19 13:19:27 $ by $Author: valdas $ * * @author <a href="mailto:gummi@idega.com">Gudmundur Agust Saemundsson</a> * @version $Revision: 1.6 $ */ public class AccessControlList { protected List<AccessControlEntry> aceList; protected String serverURI; protected String resourcePath; protected List<AccessControlEntry> acesForStandardPrincipals; protected List<AccessControlEntry> acesForRoles; protected List<AccessControlEntry> acesForUsers; protected List<AccessControlEntry> acesForGroups; protected List<AccessControlEntry> acesForOthers; protected boolean guaranteeThatRootHasAllPrivileges = true; public AccessControlList(String serverURI, String resourcePath){ this.serverURI = serverURI; this.resourcePath = resourcePath; initializeLists(); } private void initializeLists(){ clearLists(); } private void clearLists(){ this.aceList = new ArrayList<AccessControlEntry>(); this.acesForStandardPrincipals = new ArrayList<AccessControlEntry>(); this.acesForRoles = new ArrayList<AccessControlEntry>(); this.acesForUsers = new ArrayList<AccessControlEntry>(); this.acesForGroups = new ArrayList<AccessControlEntry>(); this.acesForOthers = new ArrayList<AccessControlEntry>(); } public void setAces(Ace[] aces){ clearLists(); if(aces != null){ for (int i = 0; i < aces.length; i++) { Ace ace = aces[i]; addAce(ace); } } } public void add(AccessControlEntry entry){ addAceToList(this.aceList,entry); switch (entry.getPrincipalType()) { case AccessControlEntry.PRINCIPAL_TYPE_ROLE: addAceToList(this.acesForRoles,entry); break; case AccessControlEntry.PRINCIPAL_TYPE_STANDARD: addAceToList(this.acesForStandardPrincipals,entry); break; case AccessControlEntry.PRINCIPAL_TYPE_GROUP: addAceToList(this.acesForUsers,entry); break; case AccessControlEntry.PRINCIPAL_TYPE_USER: addAceToList(this.acesForUsers,entry); break; case AccessControlEntry.PRINCIPAL_TYPE_OTHER: default: addAceToList(this.acesForOthers,entry); break; } } /** * This Method adds Ace to the list so that aces that have the same principal are added next to eachother * and the ace that returns false for entry#isNegative() gets lower index than the other. If entry#isNegative() * returns the same for both aces (and they have the same principal) the old one is swapped out for the new one. * * @param entry */ private void addAceToList(List<AccessControlEntry> theList, AccessControlEntry entry) { int index = -1; String entryPrincipal = entry.getPrincipal(); boolean entryIsNegative = entry.isNegative(); boolean listContainedAnalogousEntry = false; for (ListIterator<AccessControlEntry> iter = theList.listIterator(); iter.hasNext();) { AccessControlEntry ace = iter.next(); int lIndex = iter.nextIndex()-1; if(entryPrincipal.equals(ace.getPrincipal())){ if(entryIsNegative==ace.isNegative()){ //swap entries iter.remove(); iter.add(entry); index = -1; listContainedAnalogousEntry = true; break; } else { //keep index of ace with the same principal index = lIndex; } } } boolean addBefore = !entryIsNegative; if(!listContainedAnalogousEntry){ //add next after it's sister item int addIndex = (index+((addBefore)?0:1)); if(addIndex <= 0 || addIndex > theList.size()){ theList.add(entry); } else { theList.add(addIndex,entry); } } } /** * @param ace */ private void addAce(Ace ace) { int type; String principal = ace.getPrincipal(); AccessControlEntry acentry = null; if(IWSlideConstants.ALL_STANDARD_SUBJECT_URIS.contains(principal)){ type = AccessControlEntry.PRINCIPAL_TYPE_STANDARD; acentry = new AccessControlEntry(ace,type); } else { int index = principal.indexOf(this.serverURI); if(index > -1){ principal = principal.substring(index+this.serverURI.length()); if(principal.startsWith(IWSlideConstants.PATH_ROLES)){ type = AccessControlEntry.PRINCIPAL_TYPE_ROLE; acentry = new AccessControlEntry(ace,type); } else if(principal.startsWith(IWSlideConstants.PATH_USERS)){ type = AccessControlEntry.PRINCIPAL_TYPE_USER; acentry = new AccessControlEntry(ace,type); } else if(principal.startsWith(IWSlideConstants.PATH_GROUPS)){ type = AccessControlEntry.PRINCIPAL_TYPE_GROUP; acentry = new AccessControlEntry(ace,type); } else { type = AccessControlEntry.PRINCIPAL_TYPE_OTHER; acentry = new AccessControlEntry(ace,type); } } else { type = AccessControlEntry.PRINCIPAL_TYPE_OTHER; acentry = new AccessControlEntry(ace,type); } } if(acentry!=null){ add(acentry); } } public String getResourcePath(){ return this.resourcePath; } public Ace[] getAces(){ List<Ace> l = new ArrayList<Ace>(); String rootRoleSuffix = CoreConstants.SLASH.concat(IWSlideConstants.ROLENAME_ROOT); boolean containsPositiveRootACE = false; Collections.sort(this.aceList, new AcessControlEntryComparator()); // Groups roles, groups, users and standard principals together for (AccessControlEntry entry: this.aceList) { if(entry.hasPrivileges()){ if(isGuaranteedThatRootHasAllPrivileges() && entry.getPrincipalType() == AccessControlEntry.PRINCIPAL_TYPE_ROLE && entry.getPrincipal().endsWith(rootRoleSuffix)){ if(!entry.isNegative()){ entry.setInherited(false); entry.setInheritedFrom(null); entry.clearPrivileges(); entry.addPrivilege(IWSlideConstants.PRIVILEGE_ALL); containsPositiveRootACE = true; l.add(0,entry.getWrappedAce()); } } else { l.add(entry.getWrappedAce()); } } } if(!containsPositiveRootACE){ Logger.getLogger(this.getClass().getName()).warning("List " +this.aceList+ " does not contain positive ace for root role."); } return l.toArray(new Ace[l.size()]); } public List<AccessControlEntry> getAccessControlEntries(){ return this.aceList; } public List<AccessControlEntry> getAccessControlEntriesForStandardPrincipals(){ return this.acesForStandardPrincipals; } public List<AccessControlEntry> getAccessControlEntriesForRoles(){ return this.acesForRoles; } public List<AccessControlEntry> getAccessControlEntriesForUsers(){ return this.acesForUsers; } public List<AccessControlEntry> getAccessControlEntriesForGroups(){ return this.acesForGroups; } public List<AccessControlEntry> getAccessControlEntriesForOthers(){ return this.acesForOthers; } /** * @return Returns the guaranteeThatRootHasAllPrivileges. Default is true. */ public boolean isGuaranteedThatRootHasAllPrivileges() { return this.guaranteeThatRootHasAllPrivileges; } /** * * When this is true, as default, the method #getAces() returns array of Aces that is guaranteed not to * deny the root role any privileges when used to store ACL. * * @param guaranteeThatRootHasAllPrivileges The guaranteeThatRootHasAllPrivileges to set. Default is true. */ public void setGuaranteedThatRootHasAllPrivileges(boolean guaranteeThatRootHasAllPrivileges) { this.guaranteeThatRootHasAllPrivileges = guaranteeThatRootHasAllPrivileges; } @Override public String toString() { return ListUtil.isEmpty(aceList) ? "There are no ACL available" : "Aces: ".concat(aceList.toString()); } }