diff --git a/config/alfresco/application-context.xml b/config/alfresco/application-context.xml index 47fd76a876..82632ceeef 100644 --- a/config/alfresco/application-context.xml +++ b/config/alfresco/application-context.xml @@ -40,7 +40,8 @@ - + + diff --git a/config/alfresco/simple-permissions-context.xml b/config/alfresco/simple-permissions-context.xml new file mode 100644 index 0000000000..7b24feb515 --- /dev/null +++ b/config/alfresco/simple-permissions-context.xml @@ -0,0 +1,15 @@ + + + + + + + read + write + delete + shimmy + shake + + + + diff --git a/source/java/org/alfresco/repo/avm/util/RawServices.java b/source/java/org/alfresco/repo/avm/util/RawServices.java index 04214acd9e..1f3f1c1629 100644 --- a/source/java/org/alfresco/repo/avm/util/RawServices.java +++ b/source/java/org/alfresco/repo/avm/util/RawServices.java @@ -9,6 +9,8 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.MimetypeService; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.simple.permission.CapabilityRegistry; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -58,6 +60,16 @@ public class RawServices implements ApplicationContextAware */ private LookupCache fLookupCache; + /** + * The Authority Service. + */ + private AuthorityService fAuthorityService; + + /** + * The CapabilityRegistry. + */ + private CapabilityRegistry fCapabilityRegistry; + /** * Default constructor. */ @@ -135,6 +147,25 @@ public class RawServices implements ApplicationContextAware return fLookupCache; } + public AuthorityService getAuthorityService() + { + if (fAuthorityService == null) + { + // TODO change this back to the unwrapped bean before production. + fAuthorityService = (AuthorityService)fContext.getBean("AuthorityService"); + } + return fAuthorityService; + } + + public CapabilityRegistry getCapabilityRegistry() + { + if (fCapabilityRegistry == null) + { + fCapabilityRegistry = (CapabilityRegistry)fContext.getBean("capabilityRegistry"); + } + return fCapabilityRegistry; + } + public ApplicationContext getContext() { return fContext; diff --git a/source/java/org/alfresco/repo/simple/permission/ACLImpl.java b/source/java/org/alfresco/repo/simple/permission/ACLImpl.java new file mode 100644 index 0000000000..5cab211fc4 --- /dev/null +++ b/source/java/org/alfresco/repo/simple/permission/ACLImpl.java @@ -0,0 +1,482 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.repo.simple.permission; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.alfresco.repo.avm.util.RawServices; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; +import org.alfresco.service.simple.permission.ACL; +import org.alfresco.service.simple.permission.CapabilityRegistry; + +/** + * Basic implementation of an ACL + * @author britt + */ +public class ACLImpl implements ACL +{ + private static final long serialVersionUID = 5184311729355811095L; + + /** + * The allowed entries for users. + */ + private Map> fUserAllows; + + /** + * The allowed entries for groups. + */ + private Map> fGroupAllows; + + /** + * The denied entries for users. + */ + private Map> fUserDenies; + + /** + * The denied entries for groups. + */ + private Map> fGroupDenies; + + /** + * Bit indicating whether a child (however that is defined) + * should inherit these permissions. + */ + private boolean fInherit; + + private transient AuthorityService fAuthorityService; + + private transient CapabilityRegistry fCapabilityRegistry; + + private transient String fStringRep; + + public ACLImpl(boolean inherit) + { + fAuthorityService = RawServices.Instance().getAuthorityService(); + fCapabilityRegistry = RawServices.Instance().getCapabilityRegistry(); + fUserAllows = new HashMap>(); + fGroupAllows = new HashMap>(); + fUserDenies = new HashMap>(); + fGroupDenies = new HashMap>(); + fInherit = inherit; + fStringRep = null; + } + + public ACLImpl(String stringRep) + { + this(true); + fStringRep = stringRep; + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.ACL#allow(java.lang.String, java.lang.String[]) + */ + public void allow(String agent, String... capabilities) + { + digest(); + AuthorityType type = AuthorityType.getAuthorityType(agent); + if (type == AuthorityType.ADMIN) + { + return; + } + Set capDenied = null; + Set capAllowed = null; + switch (type) + { + case EVERYONE : + case GROUP : + { + capDenied = fGroupDenies.get(agent); + capAllowed = fGroupAllows.get(agent); + if (capAllowed == null) + { + capAllowed = new HashSet(); + fGroupAllows.put(agent, capAllowed); + } + break; + } + case ADMIN : + case USER : + case OWNER : + { + capDenied = fUserDenies.get(agent); + capAllowed = fUserAllows.get(agent); + if (capAllowed == null) + { + capAllowed = new HashSet(); + fUserAllows.put(agent, capAllowed); + } + break; + } + default : + { + // ignore. + return; + } + } + if (capDenied != null) + { + for (String cap : capabilities) + { + capDenied.remove(cap); + capAllowed.add(cap); + } + } + else + { + for (String cap : capabilities) + { + capAllowed.add(cap); + } + } + } + + private void digestMap(String mapRep, Map> map) + { + String[] segments = mapRep.split(":"); + if (segments.length == 0 || segments[0].equals("")) + { + return; + } + for (String segment : segments) + { + String[] entrySeg = segment.split(";"); + if (entrySeg.length == 0 || entrySeg[0].equals("")) + { + continue; + } + Set caps = new HashSet(); + map.put(entrySeg[0], caps); + for (int i = 1; i < entrySeg.length; ++i) + { + String cap = fCapabilityRegistry.getCapabilityName(Integer.parseInt(entrySeg[i], 16)); + if (cap == null) + { + continue; + } + caps.add(cap); + } + } + } + + private void digest() + { + if (fStringRep == null) + { + return; + } + String[] segments = fStringRep.split("\\|"); + fInherit = segments[0].equals("i") ? true : false; + digestMap(segments[1], fUserAllows); + digestMap(segments[2], fUserDenies); + digestMap(segments[3], fGroupAllows); + digestMap(segments[4], fGroupDenies); + fStringRep = null; + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.ACL#can(java.lang.String, java.lang.String) + */ + public boolean can(String agent, String capability) + { + digest(); + AuthorityType type = AuthorityType.getAuthorityType(agent); + // Admin trumps all. + if (type == AuthorityType.ADMIN) + { + return true; + } + // Next check for denied entries that apply. + Set denied = fUserDenies.get(agent); + if (denied == null) + { + denied = new HashSet(); + } + Set containing = fAuthorityService.getContainingAuthorities(null, agent, false); + Set found = fGroupDenies.get(agent); + if (found != null) + { + denied.addAll(found); + } + for (String container : containing) + { + found = fGroupDenies.get(container); + if (found != null) + { + denied.addAll(found); + } + } + if (denied.contains(capability)) + { + return false; + } + // Now go look for the alloweds. + Set allowed = fUserAllows.get(agent); + if (allowed == null) + { + allowed = new HashSet(); + } + found = fGroupAllows.get(agent); + if (found != null) + { + allowed.addAll(found); + } + for (String container : containing) + { + found = fGroupAllows.get(container); + if (found != null) + { + allowed.addAll(found); + } + } + return allowed.contains(capability); + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.ACL#deny(java.lang.String, java.lang.String[]) + */ + public void deny(String agent, String ... capabilities) + { + digest(); + AuthorityType type = AuthorityType.getAuthorityType(agent); + if (type == AuthorityType.ADMIN) + { + return; + } + Set allowed = fUserAllows.get(agent); + if (allowed != null) + { + for (String cap : capabilities) + { + allowed.remove(cap); + } + } + allowed = fGroupAllows.get(agent); + if (allowed != null) + { + for (String cap : capabilities) + { + allowed.remove(cap); + } + } + Set denied = null; + switch (type) + { + case EVERYONE : + case GROUP : + { + denied = fGroupDenies.get(agent); + if (denied == null) + { + denied = new HashSet(); + fGroupDenies.put(agent, denied); + } + break; + } + case OWNER : + case USER : + case GUEST : + { + denied = fUserDenies.get(agent); + if (denied == null) + { + denied = new HashSet(); + fUserDenies.put(agent, denied); + } + break; + } + default : + { + // Cop Out! + return; + } + } + for (String cap : capabilities) + { + denied.add(cap); + } + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.ACL#getCapabilities(java.lang.String) + */ + public Set getCapabilities(String agent) + { + digest(); + AuthorityType type = AuthorityType.getAuthorityType(agent); + if (type == AuthorityType.ADMIN) + { + return fCapabilityRegistry.getAll(); + } + // First add in all the possible capabilities from the allow sets. + Set capabilities = new HashSet(); + Set found = fUserAllows.get(agent); + if (found != null) + { + capabilities.addAll(found); + } + found = fGroupAllows.get(agent); + if (found != null) + { + capabilities.addAll(found); + } + Set containers = fAuthorityService.getContainingAuthorities(null, agent, false); + for (String container : containers) + { + found = fGroupAllows.get(container); + if (found != null) + { + capabilities.addAll(found); + } + } + // Now remove everything that's denied. + found = fUserDenies.get(agent); + if (found != null) + { + capabilities.removeAll(found); + } + found = fGroupDenies.get(agent); + if (found != null) + { + capabilities.removeAll(found); + } + for (String container : containers) + { + found = fGroupDenies.get(container); + if (found != null) + { + capabilities.removeAll(found); + } + } + return capabilities; + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.ACL#getStringRepresentation() + */ + public String getStringRepresentation() + { + if (fStringRep != null) + { + return fStringRep; + } + StringBuilder builder = new StringBuilder(); + builder.append(fInherit ? 'i' : 'n'); + builder.append('|'); + int count = 0; + for (Map.Entry> entry : fUserAllows.entrySet()) + { + builder.append(entry.getKey()); + if (entry.getValue().size() != 0) + { + for (String cap : entry.getValue()) + { + builder.append(';'); + builder.append(Integer.toString(fCapabilityRegistry.getCapabilityID(cap), 16)); + } + } + if (count++ < fUserAllows.size() - 1) + { + builder.append(':'); + } + } + builder.append('|'); + count = 0; + for (Map.Entry> entry : fUserDenies.entrySet()) + { + builder.append(entry.getKey()); + if (entry.getValue().size() != 0) + { + for (String cap : entry.getValue()) + { + builder.append(';'); + builder.append(Integer.toString(fCapabilityRegistry.getCapabilityID(cap), 16)); + } + } + if (count++ < fUserDenies.size() - 1) + { + builder.append(':'); + } + } + builder.append('|'); + count = 0; + for (Map.Entry> entry : fGroupAllows.entrySet()) + { + builder.append(entry.getKey()); + if (entry.getValue().size() != 0) + { + for (String cap : entry.getValue()) + { + builder.append(';'); + builder.append(Integer.toString(fCapabilityRegistry.getCapabilityID(cap), 16)); + } + } + if (count++ < fGroupAllows.size() - 1) + { + builder.append(':'); + } + } + builder.append('|'); + count = 0; + for (Map.Entry> entry : fGroupDenies.entrySet()) + { + builder.append(entry.getKey()); + if (entry.getValue().size() != 0) + { + for (String cap : entry.getValue()) + { + builder.append(';'); + builder.append(Integer.toString(fCapabilityRegistry.getCapabilityID(cap), 16)); + } + } + if (count++ < fGroupDenies.size() - 1) + { + builder.append(':'); + } + } + return builder.toString(); + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.ACL#inherits() + */ + public boolean inherits() + { + return fInherit; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "[" + getStringRepresentation() + "]"; + } +} diff --git a/source/java/org/alfresco/repo/simple/permission/ACLTest.java b/source/java/org/alfresco/repo/simple/permission/ACLTest.java new file mode 100644 index 0000000000..14b62aae28 --- /dev/null +++ b/source/java/org/alfresco/repo/simple/permission/ACLTest.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.repo.simple.permission; + +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.simple.permission.ACL; +import org.alfresco.service.simple.permission.CapabilityRegistry; +import org.springframework.context.support.FileSystemXmlApplicationContext; + +import junit.framework.TestCase; + +/** + * Rudimentary test of ACLs. + * @author britt + */ +public class ACLTest extends TestCase +{ + private static FileSystemXmlApplicationContext fContext = null; + + private static PersonService fPersonService; + + private static AuthorityService fAuthorityService; + + private static AuthenticationService fAuthenticationService; + + private static AuthenticationComponent fAuthenticationComponent; + + private static CapabilityRegistry fCapabilityRegistry; + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception + { + if (fContext == null) + { + fContext = new FileSystemXmlApplicationContext("config/alfresco/application-context.xml"); + fPersonService = (PersonService)fContext.getBean("PersonService"); + fAuthorityService = (AuthorityService)fContext.getBean("AuthorityService"); + fAuthenticationService = (AuthenticationService)fContext.getBean("AuthenticationService"); + fAuthenticationComponent = (AuthenticationComponent)fContext.getBean("AuthenticationComponent"); + fAuthenticationComponent.setSystemUserAsCurrentUser(); + fCapabilityRegistry = (CapabilityRegistry)fContext.getBean("capabilityRegistry"); + } + // Set up sample users groups and roles. + fAuthenticationService.createAuthentication("Buffy", "Buffy".toCharArray()); + fPersonService.getPerson("Buffy"); + fAuthorityService.createAuthority(AuthorityType.GROUP, null, "Scoobies"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Buffy"); + fAuthenticationService.createAuthentication("Willow", "Willow".toCharArray()); + fPersonService.getPerson("Willow"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Willow"); + fAuthenticationService.createAuthentication("Xander", "Xander".toCharArray()); + fPersonService.getPerson("Xander"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Xander"); + fAuthenticationService.createAuthentication("Tara", "Tara".toCharArray()); + fPersonService.getPerson("Tara"); + fAuthenticationService.createAuthentication("Spike", "Spike".toCharArray()); + fPersonService.getPerson("Spike"); + fAuthorityService.createAuthority(AuthorityType.GROUP, null, "vampires"); + fAuthorityService.addAuthority("GROUP_vampires", "Spike"); + fAuthorityService.createAuthority(AuthorityType.GROUP, null, "soulless"); + fAuthorityService.addAuthority("GROUP_soulless", "Spike"); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception + { + fAuthenticationService.deleteAuthentication("Buffy"); + fAuthenticationService.deleteAuthentication("Willow"); + fAuthenticationService.deleteAuthentication("Xander"); + fAuthenticationService.deleteAuthentication("Tara"); + fAuthenticationService.deleteAuthentication("Spike"); + fPersonService.deletePerson("Buffy"); + fPersonService.deletePerson("Willow"); + fPersonService.deletePerson("Tara"); + fPersonService.deletePerson("Xander"); + fPersonService.deletePerson("Spike"); + fAuthorityService.deleteAuthority("GROUP_Scoobies"); + fAuthorityService.deleteAuthority("GROUP_vampires"); + fAuthorityService.deleteAuthority("GROUP_soulless"); + } + + public void testBasic() + { + try + { + System.out.println(fCapabilityRegistry.getAll()); + ACL acl = new ACLImpl(true); + acl.allow("GROUP_Scoobies", "read", "write", "delete", "shimmy"); + acl.deny("Xander", "delete"); + acl.allow("Tara", "shake"); + acl.allow("GROUP_vampires", "read", "write", "delete", "shimmy", "shake"); + acl.deny("Spike", "shake"); + acl.deny("GROUP_soulless", "delete"); + System.out.println(acl.getCapabilities("Spike")); + System.out.println(acl.getCapabilities("Tara")); + System.out.println(acl.getCapabilities("Xander")); + System.out.println(acl.getCapabilities("Buffy")); + String stringRep = acl.getStringRepresentation(); + System.out.println(stringRep); + ACL acl2 = new ACLImpl(stringRep); + System.out.println(acl2.getStringRepresentation()); + System.out.println(acl2.getCapabilities("Spike")); + System.out.println(acl2.getCapabilities("Tara")); + System.out.println(acl2.getCapabilities("Xander")); + System.out.println(acl2.getCapabilities("Buffy")); + System.out.println(acl2.getStringRepresentation()); + } + catch (Exception e) + { + e.printStackTrace(); + fail(); + } + } +} diff --git a/source/java/org/alfresco/repo/simple/permission/CapabilityRegistryImpl.java b/source/java/org/alfresco/repo/simple/permission/CapabilityRegistryImpl.java new file mode 100644 index 0000000000..60e56cb057 --- /dev/null +++ b/source/java/org/alfresco/repo/simple/permission/CapabilityRegistryImpl.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.repo.simple.permission; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.alfresco.service.simple.permission.CapabilityRegistry; + +/** + * Basic implementation of a capability registry. + * @author britt + */ +public class CapabilityRegistryImpl implements CapabilityRegistry +{ + private Map fIDToCapability; + + private Map fCapabilityToID; + + public CapabilityRegistryImpl() + { + fIDToCapability = new HashMap(); + fCapabilityToID = new HashMap(); + } + + public void setCapabilities(Set capabilities) + { + int count = 0; + for (String cap : capabilities) + { + Integer id = count++; + fIDToCapability.put(id, cap); + fCapabilityToID.put(cap, id); + } + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.CapabilityRegistry#addCapability(java.lang.String) + */ + public void addCapability(String capability) + { + // TODO Make this do something in the future. + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.CapabilityRegistry#getAll() + */ + public Set getAll() + { + return fCapabilityToID.keySet(); + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.CapabilityRegistry#getCapabilityID(java.lang.String) + */ + public int getCapabilityID(String capability) + { + Integer id = fCapabilityToID.get(capability); + if (id == null) + { + return -1; + } + return id; + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.CapabilityRegistry#getCapabilityName(int) + */ + public String getCapabilityName(int id) + { + return fIDToCapability.get(id); + } + + /* (non-Javadoc) + * @see org.alfresco.service.simple.permission.CapabilityRegistry#removeCapability(java.lang.String) + */ + public void removeCapability(String capability) + { + // TODO Make this persistent. + Integer removed = fCapabilityToID.remove(capability); + fIDToCapability.remove(removed); + } +} diff --git a/source/java/org/alfresco/service/simple/permission/ACL.java b/source/java/org/alfresco/service/simple/permission/ACL.java new file mode 100644 index 0000000000..bfe6f2c2e7 --- /dev/null +++ b/source/java/org/alfresco/service/simple/permission/ACL.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.service.simple.permission; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; + +/** + * Interface for ACLs. ACLs express the capabilities granted to + * different agents (users, groups, or roles (one hopes that roles can go away as they are + * operationally just another name for a group)). ACLs contain explicit entries made of + * a capability and a list of agents plus an indication of whether the entry denies or allows + * the capability. Entries that deny override any entries that allow. + * @author britt + */ +public interface ACL extends Serializable +{ + /** + * Insert an allow entry for the agent, capabilities combination. + * Removes a denials explicitly for the agent and capabilities given. + * @param agent The agent, (user, group, role) + * @param capabilities The capabilities being granted. + */ + public void allow(String agent, String ... capabilities); + + /** + * Insert a deny entry for the agent, capabilities combination. + * Removes an allow explicitly for the agent and capabilities given. + * @param agent The agent, (user, group, role) + * @param capabilities + */ + public void deny(String agent, String ... capabilities); + + /** + * Does the given agent have the given capability + * @param agent The agent (user) + * @param capability The capability. + * @return Whether the agent can. + */ + public boolean can(String agent, String capability); + + /** + * Get the capabilities for the given agent. + * @param agent The agent. + * @return A set of capabilities. + */ + public Set getCapabilities(String agent); + + /** + * Get a string representation of this ACL, suitable for persistence. + * @return The string representation. + */ + public String getStringRepresentation(); + + /** + * Should this ACL be inherited. + * @return Whether it should. + */ + public boolean inherits(); +} diff --git a/source/java/org/alfresco/service/simple/permission/CapabilityRegistry.java b/source/java/org/alfresco/service/simple/permission/CapabilityRegistry.java new file mode 100644 index 0000000000..fa4994f028 --- /dev/null +++ b/source/java/org/alfresco/service/simple/permission/CapabilityRegistry.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.service.simple.permission; + +import java.util.Set; + +/** + * Interface for a registry of capabilities. + * @author britt + */ +public interface CapabilityRegistry +{ + /** + * Get all known capabilities. + * @return A list of all the capabilities. + */ + public Set getAll(); + + /** + * Get the integer id corresponding to the given capability. + * @return The id. + */ + public int getCapabilityID(String capability); + + /** + * Get the name of a capability from it's unique id. + * @param id + * @return The capability name or null if the id is invalid. + */ + public String getCapabilityName(int id); + + /** + * Add a capability. + * @param capability + */ + public void addCapability(String capability); + + /** + * Remove a capability from the system. + * @param capability + */ + public void removeCapability(String capability); +} diff --git a/source/java/org/alfresco/service/simple/permission/SimplePermissionService.java b/source/java/org/alfresco/service/simple/permission/SimplePermissionService.java new file mode 100644 index 0000000000..d15d72a68b --- /dev/null +++ b/source/java/org/alfresco/service/simple/permission/SimplePermissionService.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.service.simple.permission; + +import java.util.List; + +/** + * Interface for a simple permission mechanism. + * Nothing but String valued capabilities, and ACLs. + * @author britt + */ +public interface SimplePermissionService +{ + /** + * Can the current user perform the action indicated by the capability. + * @param capability The capability: marker for an ability to perform an action + * governed by an ACL. + * @param acl The ACL. If this is null then the permission is granted. + * @param owner The owner. The owner can always has the "changepermission" capability. + * @return Whether permission is granted. + */ + boolean can(String capability, ACL acl, String owner); + + /** + * Can the user (agent) specified perform the action indicated by the capability. + * @param agent The agent (user) to check. + * @param capability The capability to check. + * @param acl The ACL. If this is null then the permission is granted. + * @param owner The owner. + * @return Whether permission is granted. + */ + boolean can(String agent, String capability, ACL acl, String owner); + + /** + * Get the capabilities that this acl grants the current user. + * @param acl The ACL. + * @param owner The owner of the controlled entity. + * @return A list of capabilities. + */ + List getCapabilities(ACL acl, String owner); + + /** + * Get the capabilities that this agent grants the specifiec agent. + * @param agent The agent (user). + * @param acl The ACL. + * @param owner The owner of the controlled entity. + * @return A list of capabilities. + */ + List getCapabilities(String agent, ACL acl, String owner); +}