diff --git a/config/alfresco/bootstrap/alfrescoAuthorityStore.xml b/config/alfresco/bootstrap/alfrescoAuthorityStore.xml
index 8febc87fb4..4c6125cc69 100644
--- a/config/alfresco/bootstrap/alfrescoAuthorityStore.xml
+++ b/config/alfresco/bootstrap/alfrescoAuthorityStore.xml
@@ -58,6 +58,72 @@
Read
+
+
+
+
+
+
+
+ AUTH.ALF
+ AUTH.ALF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ APP.DEFAULT
+ APP.DEFAULT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/ehcache-default.xml b/config/alfresco/ehcache-default.xml
index 6aa9af1a79..021dc71817 100644
--- a/config/alfresco/ehcache-default.xml
+++ b/config/alfresco/ehcache-default.xml
@@ -382,7 +382,7 @@
@@ -390,7 +390,7 @@
diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties
index 5ec5daa8b6..e379a0afb4 100644
--- a/config/alfresco/messages/patch-service.properties
+++ b/config/alfresco/messages/patch-service.properties
@@ -274,3 +274,7 @@ patch.zonedAuthorities.description=Adds the remodelled cm:authority container to
patch.authorityMigration.description=Copies any old authorities from the user store to the spaces store.
patch.authorityMigration.result=Migrated {0} authorities to the spaces store.
+
+patch.authorityDefaultZonesPatch.description=Adds groups and people to the appropriate zones for wcm, share and everything else.
+patch.authorityDefaultZonesPatch.result=Unzoned groups and people added to the default zones.
+
diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index 9c25c30fda..80cd95e18e 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -1807,5 +1807,30 @@
+
+
+ patch.authorityDefaultZonesPatch
+ patch.authorityDefaultZonesPatch.description
+ 0
+ 2013
+ 2014
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml
index 48596f0498..77a7115472 100644
--- a/config/alfresco/public-services-security-context.xml
+++ b/config/alfresco/public-services-security-context.xml
@@ -693,10 +693,11 @@
org.alfresco.service.cmr.security.AuthorityService.hasAdminAuthority=ACL_ALLOW
org.alfresco.service.cmr.security.AuthorityService.isAdminAuthority=ACL_ALLOW
org.alfresco.service.cmr.security.AuthorityService.getAuthorities=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.getAuthoritiesForUser=ACL_METHOD.ROLE_ADMINISTRATOR
org.alfresco.service.cmr.security.AuthorityService.getAllAuthorities=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.findAuthoritiesByShortName=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.findAuthorities=ACL_ALLOW
org.alfresco.service.cmr.security.AuthorityService.getAllRootAuthorities=ACL_ALLOW
- org.alfresco.service.cmr.security.AuthorityService.findAuthoritiesByShortName=ACL_ALLOW
- org.alfresco.service.cmr.security.AuthorityService.findAuthorities=ACL_ALLOW
org.alfresco.service.cmr.security.AuthorityService.createAuthority=ACL_METHOD.ROLE_ADMINISTRATOR
org.alfresco.service.cmr.security.AuthorityService.addAuthority=ACL_METHOD.ROLE_ADMINISTRATOR
org.alfresco.service.cmr.security.AuthorityService.removeAuthority=ACL_METHOD.ROLE_ADMINISTRATOR
@@ -706,9 +707,15 @@
org.alfresco.service.cmr.security.AuthorityService.getShortName=ACL_ALLOW
org.alfresco.service.cmr.security.AuthorityService.getName=ACL_ALLOW
org.alfresco.service.cmr.security.AuthorityService.authorityExists=ACL_ALLOW
- org.alfresco.service.cmr.security.AuthorityService.getAuthoritiesForUser=ACL_METHOD.ROLE_ADMINISTRATOR
org.alfresco.service.cmr.security.AuthorityService.setAuthorityDisplayName=ACL_METHOD.ROLE_ADMINISTRATOR
org.alfresco.service.cmr.security.AuthorityService.getAuthorityDisplayName=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.getOrCreateZone=ACL_METHOD.ROLE_ADMINISTRATOR
+ org.alfresco.service.cmr.security.AuthorityService.getAuthorityZones=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.getAllAuthoritiesInZone=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.getAllRootAuthoritiesInZone=ACL_ALLOW
+ org.alfresco.service.cmr.security.AuthorityService.addAuthorityToZones=ACL_METHOD.ROLE_ADMINISTRATOR
+ org.alfresco.service.cmr.security.AuthorityService.removeAuthorityFromZones=ACL_METHOD.ROLE_ADMINISTRATOR
+ org.alfresco.service.cmr.security.AuthorityService.getDefaultZones=ACL_ALLOW
diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties
index 046e12648c..900c70e119 100644
--- a/config/alfresco/version.properties
+++ b/config/alfresco/version.properties
@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number
-version.schema=2013
+version.schema=2014
diff --git a/source/java/org/alfresco/repo/admin/patch/impl/AuthorityDefaultZonesPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/AuthorityDefaultZonesPatch.java
new file mode 100644
index 0000000000..83aaab497c
--- /dev/null
+++ b/source/java/org/alfresco/repo/admin/patch/impl/AuthorityDefaultZonesPatch.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2005-2009 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 received 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.admin.patch.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.alfresco.repo.admin.patch.AbstractPatch;
+import org.alfresco.repo.domain.hibernate.HibernateSessionHelper;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
+import org.alfresco.service.cmr.security.AuthorityService;
+import org.alfresco.service.cmr.security.AuthorityType;
+import org.alfresco.service.cmr.site.SiteInfo;
+import org.alfresco.service.cmr.site.SiteService;
+
+/**
+ * Patch to assign users and groups to default zones
+ *
+ * @author andyh
+ */
+public class AuthorityDefaultZonesPatch extends AbstractPatch
+{
+ /** Success message. */
+ private static final String MSG_SUCCESS = "patch.authorityDefaultZonesPatch.result";
+
+ /** The authority service. */
+ private AuthorityService authorityService;
+
+ private AVMService avmService;
+
+ private SiteService siteService;
+
+ private HibernateSessionHelper hibernateSessionHelper;
+
+ /**
+ * Sets the authority service.
+ *
+ * @param authorityService
+ * the authority service
+ */
+ public void setAuthorityService(AuthorityService authorityService)
+ {
+ this.authorityService = authorityService;
+ }
+
+ /**
+ * Set the avm service
+ * @param avmService
+ */
+ public void setAvmService(AVMService avmService)
+ {
+ this.avmService = avmService;
+ }
+
+ /**
+ * Set the site service
+ * @param siteService
+ */
+ public void setSiteService(SiteService siteService)
+ {
+ this.siteService = siteService;
+ }
+
+ /**
+ * @param hibernateSessionHelper
+ */
+ public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper)
+ {
+ this.hibernateSessionHelper = hibernateSessionHelper;
+ }
+
+ @Override
+ protected String applyInternal() throws Exception
+ {
+ setZonesForPeople();
+ setZonesForGroups();
+
+ return MSG_SUCCESS;
+
+ }
+
+ private void setZonesForPeople()
+ {
+ Set defaultZones = new HashSet(2, 1.0f);
+ defaultZones.add(AuthorityService.ZONE_APP_DEFAULT);
+ defaultZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+
+ List personActions = new ArrayList(1);
+ personActions.add(new Action(null, defaultZones, ActionType.ADD));
+
+ setZones(AuthorityType.USER, personActions);
+
+ }
+
+ private void setZonesForGroups()
+ {
+ Set defaultZones = new HashSet(2, 1.0f);
+ defaultZones.add(AuthorityService.ZONE_APP_DEFAULT);
+ defaultZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+
+ Set wcmZones = new HashSet(2, 1.0f);
+ wcmZones.add(AuthorityService.ZONE_APP_WCM);
+ wcmZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+
+ Set shareZones = new HashSet(2, 1.0f);
+ shareZones.add(AuthorityService.ZONE_APP_SHARE);
+ shareZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+
+ List stores = avmService.getStores();
+ List sites = siteService.listSites(null, null);
+
+ List groupActions = new ArrayList(stores.size() * 4 + sites.size() * 5 + 1);
+ for (AVMStoreDescriptor store : stores)
+ {
+ groupActions.add(new Action("GROUP_"+store.getName()+"-ContentManager", wcmZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_"+store.getName()+"-ContentPublisher", wcmZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_"+store.getName()+"-ContentContributor", wcmZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_"+store.getName()+"-ContentReviewer", wcmZones, ActionType.ADD));
+ }
+ for (SiteInfo site : sites)
+ {
+ groupActions.add(new Action("GROUP_site_" + site.getShortName(), shareZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteManager", shareZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteCollaborator", shareZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteContributor", shareZones, ActionType.ADD));
+ groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteConsumer", shareZones, ActionType.ADD));
+ }
+ groupActions.add(new Action(null, defaultZones, ActionType.ADD));
+
+ setZones(AuthorityType.GROUP, groupActions);
+
+ }
+
+ private void setZones(AuthorityType authorityType, List actions)
+ {
+
+ //hibernateSessionHelper.mark();
+ Set authorities = authorityService.getAllAuthorities(authorityType);
+ //hibernateSessionHelper.reset();
+ for (String authority : authorities)
+ {
+ for (Action action : actions)
+ {
+ if (action.name != null)
+ {
+ if (action.name.equals(authority))
+ {
+ fixAuthority(action.actionType, action.zones, authority);
+ break;
+ }
+ }
+ else
+ {
+ fixAuthority(action.actionType, action.zones, authority);
+ break;
+ }
+ }
+ //hibernateSessionHelper.reset();
+ }
+ }
+
+ private void fixAuthority(ActionType actionType, Set zones, String authority)
+ {
+ Set current;
+ switch (actionType)
+ {
+ case ADD:
+ authorityService.addAuthorityToZones(authority, zones);
+ break;
+ case SET:
+ current = authorityService.getAuthorityZones(authority);
+ authorityService.removeAuthorityFromZones(authority, current);
+ authorityService.addAuthorityToZones(authority, zones);
+ break;
+ case SET_IF_UNSET:
+ current = authorityService.getAuthorityZones(authority);
+ if (current.size() == 0)
+ {
+ authorityService.addAuthorityToZones(authority, zones);
+
+ }
+ break;
+ }
+ }
+
+ private enum ActionType
+ {
+ ADD, SET, SET_IF_UNSET;
+ }
+
+ private static class Action
+ {
+ String name;
+
+ Set zones;
+
+ ActionType actionType;
+
+ Action(String name, Set zones, ActionType actionType)
+ {
+ this.name = name;
+ this.zones = zones;
+ this.actionType = actionType;
+ }
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
index 7ade1a1b15..c63d954974 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/index/IndexInfo.java
@@ -815,11 +815,11 @@ public class IndexInfo implements IndexMonitor
{
indexEntries.put(id, new IndexEntry(IndexType.DELTA, id, "", TransactionStatus.ACTIVE, "", 0, 0, false));
}
- // Downgrade lock
- getReadLock();
+
}
finally
- {
+ { // Downgrade lock
+ getReadLock();
releaseWriteLock();
}
}
@@ -1075,11 +1075,11 @@ public class IndexInfo implements IndexMonitor
getWriteLock();
try
{
- mainIndexReader = null;
- getReadLock();
+ mainIndexReader = null;
}
finally
{
+ getReadLock();
releaseWriteLock();
}
}
@@ -1110,10 +1110,11 @@ public class IndexInfo implements IndexMonitor
mainIndexReader = createMainIndexReader();
}
- getReadLock();
+
}
finally
{
+ getReadLock();
releaseWriteLock();
}
}
@@ -1162,10 +1163,10 @@ public class IndexInfo implements IndexMonitor
try
{
mainIndexReader = null;
- getReadLock();
}
finally
{
+ getReadLock();
releaseWriteLock();
}
}
@@ -1195,10 +1196,10 @@ public class IndexInfo implements IndexMonitor
mainIndexReader = createMainIndexReader();
}
- getReadLock();
}
finally
{
+ getReadLock();
releaseWriteLock();
}
}
@@ -1294,10 +1295,10 @@ public class IndexInfo implements IndexMonitor
}
dumpInfo();
}
- getReadLock();
}
finally
{
+ getReadLock();
releaseWriteLock();
}
}
@@ -3073,10 +3074,10 @@ public class IndexInfo implements IndexMonitor
return true;
}
});
- getReadLock();
}
finally
{
+ getReadLock();
releaseWriteLock();
}
}
@@ -3342,10 +3343,10 @@ public class IndexInfo implements IndexMonitor
}
});
- getReadLock();
}
finally
{
+ getReadLock();
releaseWriteLock();
}
diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java b/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java
index 500c1b236e..46f9390c17 100644
--- a/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java
+++ b/source/java/org/alfresco/repo/security/authority/AuthorityDAO.java
@@ -45,9 +45,9 @@ public interface AuthorityDAO
*
* @param name
* @param authorityDisplayName
- * @param authorityZone
+ * @param authorityZones
*/
- void createAuthority(String name, String authorityDisplayName, String authorityZone);
+ void createAuthority(String name, String authorityDisplayName, Set authorityZones);
/**
* Delete an authority.
@@ -163,10 +163,10 @@ public interface AuthorityDAO
*
* @param name
* the authority long name
- * @return the the name of the zone containing the specified authority, {@link AuthorityService#DEFAULT_ZONE} if the
+ * @return the set of names of all zones containing the specified authority, an empty set if the
* authority exists but has no zone, or null
if the authority does not exist.
*/
- public String getAuthorityZone(String name);
+ public Set getAuthorityZones(String name);
/**
* Gets the names of all authorities in a zone, optionally filtered by type.
@@ -178,4 +178,26 @@ public interface AuthorityDAO
* @return the names of all authorities in a zone, optionally filtered by type
*/
public Set getAllAuthoritiesInZone(String zoneName, AuthorityType type);
+
+ /**
+ * Add an authority to zones
+ * @param authorityName
+ * @param zones
+ */
+ public void addAuthorityToZones(String authorityName, Set zones);
+
+ /**
+ * Remove an authority from zones.
+ * @param authorityName
+ * @param zones
+ */
+ public void removeAuthorityFromZones(String authorityName, Set zones);
+
+ /**
+ * Get all root authorities in a zone
+ * @param zoneName
+ * @param type (optional)
+ * @return the set of authority names
+ */
+ public Set getAllRootAuthoritiesInZone(String zoneName, AuthorityType type);
}
diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java b/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java
index 67b96ccca6..56ef3aaa1d 100644
--- a/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java
+++ b/source/java/org/alfresco/repo/security/authority/AuthorityDAOImpl.java
@@ -122,37 +122,36 @@ public class AuthorityDAOImpl implements AuthorityDAO
throw new UnknownAuthorityException("An authority was not found for " + parentName);
}
AuthorityType authorityType = AuthorityType.getAuthorityType(childName);
- if (!authorityType.equals(AuthorityType.USER) && !authorityType.equals(AuthorityType.GROUP)
- && !(authorityType.equals(AuthorityType.ROLE) && AuthorityType.getAuthorityType(parentName).equals(
- AuthorityType.ROLE)))
+ if (!authorityType.equals(AuthorityType.USER)
+ && !authorityType.equals(AuthorityType.GROUP)
+ && !(authorityType.equals(AuthorityType.ROLE) && AuthorityType.getAuthorityType(parentName).equals(AuthorityType.ROLE)))
{
- throw new AlfrescoRuntimeException("Authorities of the type " + authorityType
- + " may not be added to other authorities");
+ throw new AlfrescoRuntimeException("Authorities of the type " + authorityType + " may not be added to other authorities");
}
NodeRef childRef = getAuthorityOrNull(childName);
if (childRef == null)
{
throw new UnknownAuthorityException("An authority was not found for " + childName);
}
- nodeService.addChild(parentRef, childRef, ContentModel.ASSOC_MEMBER, QName.createQName("cm", childName,
- namespacePrefixResolver));
+ nodeService.addChild(parentRef, childRef, ContentModel.ASSOC_MEMBER, QName.createQName("cm", childName, namespacePrefixResolver));
authorityLookupCache.clear();
}
- public void createAuthority(String name, String authorityDisplayName, String authorityZone)
+ public void createAuthority(String name, String authorityDisplayName, Set authorityZones)
{
HashMap props = new HashMap();
props.put(ContentModel.PROP_AUTHORITY_NAME, name);
props.put(ContentModel.PROP_AUTHORITY_DISPLAY_NAME, authorityDisplayName);
NodeRef childRef;
NodeRef authorityContainerRef = getAuthorityContainer();
- childRef = nodeService.createNode(authorityContainerRef, ContentModel.ASSOC_CHILDREN,
- QName.createQName("cm", name, namespacePrefixResolver), ContentModel.TYPE_AUTHORITY_CONTAINER, props)
- .getChildRef();
- if (authorityZone != null)
+ childRef = nodeService.createNode(authorityContainerRef, ContentModel.ASSOC_CHILDREN, QName.createQName("cm", name, namespacePrefixResolver),
+ ContentModel.TYPE_AUTHORITY_CONTAINER, props).getChildRef();
+ if (authorityZones != null)
{
- nodeService.addChild(getOrCreateZone(authorityZone), childRef, ContentModel.ASSOC_IN_ZONE, QName
- .createQName("cm", name, namespacePrefixResolver));
+ for (String authorityZone : authorityZones)
+ {
+ nodeService.addChild(getOrCreateZone(authorityZone), childRef, ContentModel.ASSOC_IN_ZONE, QName.createQName("cm", name, namespacePrefixResolver));
+ }
}
authorityLookupCache.clear();
}
@@ -175,14 +174,13 @@ public class AuthorityDAOImpl implements AuthorityDAO
return Collections. emptySet();
}
Set authorities = new HashSet();
- for (NodeRef nodeRef : nodeService.getNodesWithoutParentAssocsOfType(this.storeRef,
- ContentModel.TYPE_AUTHORITY_CONTAINER, ContentModel.ASSOC_MEMBER))
+ for (NodeRef nodeRef : nodeService.getNodesWithoutParentAssocsOfType(this.storeRef, ContentModel.TYPE_AUTHORITY_CONTAINER, ContentModel.ASSOC_MEMBER))
{
addAuthorityNameIfMatches(authorities, nodeRef, type, null);
}
return authorities;
}
-
+
public Set getAllAuthorities(AuthorityType type)
{
return findAuthorities(type, null);
@@ -193,8 +191,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
Pattern pattern = null;
if (namePattern != null)
{
- String regExpString = SearchLanguageConversion.convert(SearchLanguageConversion.DEF_LUCENE,
- SearchLanguageConversion.DEF_REGEX, namePattern);
+ String regExpString = SearchLanguageConversion.convert(SearchLanguageConversion.DEF_LUCENE, SearchLanguageConversion.DEF_REGEX, namePattern);
pattern = Pattern.compile(regExpString, Pattern.CASE_INSENSITIVE);
}
HashSet authorities = new HashSet();
@@ -204,11 +201,11 @@ public class AuthorityDAOImpl implements AuthorityDAO
{
for (NodeRef nodeRef : personService.getAllPeople())
{
- addAuthorityNameIfMatches(authorities, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
- ContentModel.PROP_USERNAME)), type, pattern);
+ addAuthorityNameIfMatches(authorities, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_USERNAME)), type,
+ pattern);
}
}
-
+
// For other types, we just look directly under the authority container
if (type == null || !type.equals(AuthorityType.USER))
{
@@ -284,8 +281,8 @@ public class AuthorityDAOImpl implements AuthorityDAO
private void addAuthorityNameIfMatches(Set authorities, NodeRef nodeRef, AuthorityType type, Pattern pattern)
{
- addAuthorityNameIfMatches(authorities, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef,
- ContentModel.PROP_AUTHORITY_NAME)), type, pattern);
+ addAuthorityNameIfMatches(authorities, DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_AUTHORITY_NAME)), type,
+ pattern);
}
private void addAuthorityNameIfMatches(Set authorities, String authorityName, AuthorityType type, Pattern pattern)
@@ -307,10 +304,9 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
- private void findAuthorities(AuthorityType type, String name, Set authorities, boolean parents,
- boolean recursive)
+ private void findAuthorities(AuthorityType type, String name, Set authorities, boolean parents, boolean recursive)
{
- AuthorityType localType = AuthorityType.getAuthorityType(name);
+ AuthorityType localType = AuthorityType.getAuthorityType(name);
if (localType.equals(AuthorityType.GUEST))
{
// Nothing to do
@@ -332,26 +328,23 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
- private void findAuthorities(AuthorityType type, Pattern pattern, NodeRef nodeRef, Set authorities,
- boolean parents, boolean recursive, boolean includeNode)
+ private void findAuthorities(AuthorityType type, Pattern pattern, NodeRef nodeRef, Set authorities, boolean parents, boolean recursive, boolean includeNode)
{
QName currentType = nodeService.getType(nodeRef);
boolean isAuthority = dictionaryService.isSubClass(currentType, ContentModel.TYPE_AUTHORITY);
if (includeNode && isAuthority)
{
- String authorityName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService
- .getProperty(nodeRef, dictionaryService.isSubClass(currentType,
- ContentModel.TYPE_AUTHORITY_CONTAINER) ? ContentModel.PROP_AUTHORITY_NAME
- : ContentModel.PROP_USERNAME));
+ String authorityName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, dictionaryService.isSubClass(currentType,
+ ContentModel.TYPE_AUTHORITY_CONTAINER) ? ContentModel.PROP_AUTHORITY_NAME : ContentModel.PROP_USERNAME));
addAuthorityNameIfMatches(authorities, authorityName, type, pattern);
}
// Loop over children if we want immediate children or are in recursive mode
if (!includeNode || (recursive && isAuthority))
{
- List cars = parents ? nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_MEMBER,
- RegexQNamePattern.MATCH_ALL) : nodeService.getChildAssocs(nodeRef);
+ List cars = parents ? nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_MEMBER, RegexQNamePattern.MATCH_ALL) : nodeService
+ .getChildAssocs(nodeRef);
for (ChildAssociationRef car : cars)
{
@@ -361,7 +354,6 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
-
private NodeRef getAuthorityOrNull(String name)
{
if (AuthorityType.getAuthorityType(name).equals(AuthorityType.USER))
@@ -372,10 +364,26 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
return personService.getPerson(name);
}
+ else if (AuthorityType.getAuthorityType(name).equals(AuthorityType.GUEST))
+ {
+ if (!personService.personExists(name))
+ {
+ return null;
+ }
+ return personService.getPerson(name);
+ }
+ else if (AuthorityType.getAuthorityType(name).equals(AuthorityType.ADMIN))
+ {
+ if (!personService.personExists(name))
+ {
+ return null;
+ }
+ return personService.getPerson(name);
+ }
else
{
- List results = nodeService.getChildAssocs(getAuthorityContainer(),
- ContentModel.ASSOC_CHILDREN, QName.createQName("cm", name, namespacePrefixResolver));
+ List results = nodeService.getChildAssocs(getAuthorityContainer(), ContentModel.ASSOC_CHILDREN, QName.createQName("cm", name,
+ namespacePrefixResolver));
return results.isEmpty() ? null : results.get(0).getChildRef();
}
}
@@ -399,8 +407,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
private NodeRef getSystemContainer(QName assocQName)
{
NodeRef rootNodeRef = nodeService.getRootNode(this.storeRef);
- List results = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL,
- qnameAssocSystem);
+ List results = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL, qnameAssocSystem);
NodeRef sysNodeRef = null;
if (results.size() == 0)
{
@@ -476,14 +483,12 @@ public class AuthorityDAOImpl implements AuthorityDAO
{
NodeRef zoneContainerRef = getZoneContainer();
QName zoneQName = QName.createQName("cm", zoneName, namespacePrefixResolver);
- List results = nodeService.getChildAssocs(zoneContainerRef, ContentModel.ASSOC_CHILDREN,
- zoneQName);
+ List results = nodeService.getChildAssocs(zoneContainerRef, ContentModel.ASSOC_CHILDREN, zoneQName);
if (results.isEmpty())
{
HashMap props = new HashMap();
props.put(ContentModel.PROP_NAME, zoneName);
- return nodeService.createNode(zoneContainerRef, ContentModel.ASSOC_CHILDREN, zoneQName,
- ContentModel.TYPE_ZONE, props).getChildRef();
+ return nodeService.createNode(zoneContainerRef, ContentModel.ASSOC_CHILDREN, zoneQName, ContentModel.TYPE_ZONE, props).getChildRef();
}
else
{
@@ -491,29 +496,37 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
- public String getAuthorityZone(String name)
+ public Set getAuthorityZones(String name)
{
+ HashSet zones = new HashSet();
NodeRef childRef = getAuthorityOrNull(name);
if (childRef == null)
{
return null;
}
- List results = nodeService.getParentAssocs(childRef, ContentModel.ASSOC_IN_ZONE,
- RegexQNamePattern.MATCH_ALL);
+ List results = nodeService.getParentAssocs(childRef, ContentModel.ASSOC_IN_ZONE, RegexQNamePattern.MATCH_ALL);
if (results.isEmpty())
{
-
- return AuthorityService.DEFAULT_ZONE;
+ return zones;
}
- NodeRef zoneRef = results.get(0).getParentRef();
- Serializable value = nodeService.getProperty(zoneRef, ContentModel.PROP_NAME);
- if (value == null)
+
+ for (ChildAssociationRef current : results)
{
- return null;
+ NodeRef zoneRef = current.getParentRef();
+ Serializable value = nodeService.getProperty(zoneRef, ContentModel.PROP_NAME);
+ if (value == null)
+ {
+ continue;
+ }
+ else
+ {
+ String zone = DefaultTypeConverter.INSTANCE.convert(String.class, value);
+ zones.add(zone);
+ }
}
- return DefaultTypeConverter.INSTANCE.convert(String.class, value);
+ return zones;
}
-
+
public Set getAllAuthoritiesInZone(String zoneName, AuthorityType type)
{
HashSet authorities = new HashSet();
@@ -525,6 +538,51 @@ public class AuthorityDAOImpl implements AuthorityDAO
return authorities;
}
+ public void addAuthorityToZones(String authorityName, Set zones)
+ {
+ if ((zones != null) && (zones.size() > 0))
+ {
+ NodeRef authRef = getAuthorityOrNull(authorityName);
+ if (authRef != null)
+ {
+
+ for (String zone : zones)
+ {
+ // Add the person to an authentication zone (corresponding to an external user registry)
+ // Let's preserve case on this child association
+ nodeService.addChild(getOrCreateZone(zone), authRef, ContentModel.ASSOC_IN_ZONE, QName.createQName("cm", authorityName, namespacePrefixResolver));
+ }
+ }
+ }
+ }
+
+ public void removeAuthorityFromZones(String authorityName, Set zones)
+ {
+ if ((zones != null) && (zones.size() > 0))
+ {
+ NodeRef authRef = getAuthorityOrNull(authorityName);
+ List results = nodeService.getParentAssocs(authRef, ContentModel.ASSOC_IN_ZONE, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef current : results)
+ {
+ NodeRef zoneRef = current.getParentRef();
+ Serializable value = nodeService.getProperty(zoneRef, ContentModel.PROP_NAME);
+ if (value == null)
+ {
+ continue;
+ }
+ else
+ {
+ String testZone = DefaultTypeConverter.INSTANCE.convert(String.class, value);
+ if (zones.contains(testZone))
+ {
+ nodeService.removeChildAssociation(current);
+ }
+ }
+ }
+ }
+
+ }
+
private static class CacheKey implements Serializable
{
/**
@@ -537,7 +595,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
String name;
boolean parents;
-
+
boolean recursive;
CacheKey(AuthorityType type, String name, boolean parents, boolean recursive)
@@ -591,7 +649,13 @@ public class AuthorityDAOImpl implements AuthorityDAO
return true;
}
-
-
+ }
+
+ public Set getAllRootAuthoritiesInZone(String zoneName, AuthorityType type)
+ {
+ Set roots = getAllRootAuthorities(type);
+ Set inZone = getAllAuthoritiesInZone(zoneName, type);
+ roots.retainAll(inZone);
+ return roots;
}
}
diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java b/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java
index de66c5845f..c9e6007144 100644
--- a/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java
+++ b/source/java/org/alfresco/repo/security/authority/AuthorityServiceImpl.java
@@ -53,6 +53,8 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
{
private static Log logger = LogFactory.getLog(AuthorityServiceImpl.class);
+ private static Set DEFAULT_ZONES = new HashSet();
+
private PersonService personService;
private NodeService nodeService;
@@ -73,6 +75,12 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
private Set adminGroups = Collections.emptySet();
+ static
+ {
+ DEFAULT_ZONES.add(AuthorityService.ZONE_APP_DEFAULT);
+ DEFAULT_ZONES.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+ }
+
public AuthorityServiceImpl()
{
super();
@@ -290,7 +298,7 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
public String createAuthority(AuthorityType type, String shortName)
{
- return createAuthority(type, shortName, shortName, null);
+ return createAuthority(type, shortName, shortName, getDefaultZones());
}
public void deleteAuthority(String name)
@@ -373,11 +381,11 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
}
public String createAuthority(AuthorityType type, String shortName, String authorityDisplayName,
- String authorityZone)
+ Set authorityZones)
{
checkTypeIsMutable(type);
String name = getName(type, shortName);
- authorityDAO.createAuthority(name, authorityDisplayName, authorityZone);
+ authorityDAO.createAuthority(name, authorityDisplayName, authorityZones);
return name;
}
@@ -398,9 +406,9 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
authorityDAO.setAuthorityDisplayName(authorityName, authorityDisplayName);
}
- public String getAuthorityZone(String name)
+ public Set getAuthorityZones(String name)
{
- return authorityDAO.getAuthorityZone(name);
+ return authorityDAO.getAuthorityZones(name);
}
public NodeRef getOrCreateZone(String zoneName)
@@ -412,4 +420,25 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
{
return authorityDAO.getAllAuthoritiesInZone(zoneName, type);
}
+
+ public void addAuthorityToZones(String authorityName, Set zones)
+ {
+ authorityDAO.addAuthorityToZones(authorityName, zones);
+
+ }
+
+ public void removeAuthorityFromZones(String authorityName, Set zones)
+ {
+ authorityDAO.removeAuthorityFromZones(authorityName, zones);
+ }
+
+ public Set getDefaultZones()
+ {
+ return DEFAULT_ZONES;
+ }
+
+ public Set getAllRootAuthoritiesInZone(String zoneName, AuthorityType type)
+ {
+ return authorityDAO.getAllRootAuthoritiesInZone(zoneName, type);
+ }
}
diff --git a/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java b/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java
index cd8f5f53f3..538dc23fac 100644
--- a/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java
+++ b/source/java/org/alfresco/repo/security/authority/AuthorityServiceTest.java
@@ -26,6 +26,7 @@ package org.alfresco.repo.security.authority;
import java.io.Serializable;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -159,6 +160,93 @@ public class AuthorityServiceTest extends TestCase
super.tearDown();
}
+
+ public void testZones()
+ {
+ assertNull(pubAuthorityService.getAuthorityZones("GROUP_DEFAULT"));
+ assertNull(pubAuthorityService.getAuthorityZones("GROUP_NULL"));
+ assertNull(pubAuthorityService.getAuthorityZones("GROUP_EMPTY"));
+ assertNull(pubAuthorityService.getAuthorityZones("GROUP_1"));
+ assertNull(pubAuthorityService.getAuthorityZones("GROUP_2"));
+ assertNull(pubAuthorityService.getAuthorityZones("GROUP_3"));
+
+ pubAuthorityService.createAuthority(AuthorityType.GROUP, "DEFAULT");
+ Set zones = pubAuthorityService.getAuthorityZones("GROUP_DEFAULT");
+ assertEquals(2, zones.size());
+ pubAuthorityService.removeAuthorityFromZones("GROUP_DEFAULT", zones);
+ assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_DEFAULT").size());
+ pubAuthorityService.addAuthorityToZones("GROUP_DEFAULT", zones);
+ assertEquals(2, pubAuthorityService.getAuthorityZones("GROUP_DEFAULT").size());
+
+ HashSet newZones = null;
+ pubAuthorityService.createAuthority(AuthorityType.GROUP, "NULL", "NULL", newZones);
+ assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_NULL").size());
+
+ newZones = new HashSet();
+ pubAuthorityService.createAuthority(AuthorityType.GROUP, "EMPTY", "EMPTY", newZones);
+ assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_EMPTY").size());
+
+ newZones.add("One");
+ pubAuthorityService.createAuthority(AuthorityType.GROUP, "1", "1", newZones);
+ assertEquals(1, pubAuthorityService.getAuthorityZones("GROUP_1").size());
+
+ newZones.add("Two");
+ pubAuthorityService.createAuthority(AuthorityType.GROUP, "2", "2", newZones);
+ assertEquals(2, pubAuthorityService.getAuthorityZones("GROUP_2").size());
+
+ newZones.add("Three");
+ pubAuthorityService.createAuthority(AuthorityType.GROUP, "3", "3", newZones);
+ assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+
+ HashSet toRemove = null;
+ pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove);
+ assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+
+ toRemove = new HashSet();
+ pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove);
+ assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+
+ toRemove.add("Three");
+ pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove);
+ assertEquals(2, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+
+ toRemove.add("Two");
+ pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove);
+ assertEquals(1, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+
+ toRemove.add("One");
+ pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove);
+ assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+
+ pubAuthorityService.addAuthorityToZones("GROUP_3", newZones);
+ assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size());
+ assertEquals(3, pubAuthorityService.getAllAuthoritiesInZone("One", null).size());
+ assertEquals(2, pubAuthorityService.getAllAuthoritiesInZone("Two", null).size());
+ assertEquals(1, pubAuthorityService.getAllAuthoritiesInZone("Three", null).size());
+ assertEquals(3, pubAuthorityService.getAllAuthoritiesInZone("One", AuthorityType.GROUP).size());
+ assertEquals(2, pubAuthorityService.getAllAuthoritiesInZone("Two", AuthorityType.GROUP).size());
+ assertEquals(1, pubAuthorityService.getAllAuthoritiesInZone("Three", AuthorityType.GROUP).size());
+
+ assertEquals(3, pubAuthorityService.getAllRootAuthoritiesInZone("One", null).size());
+ assertEquals(2, pubAuthorityService.getAllRootAuthoritiesInZone("Two", null).size());
+ assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("Three", null).size());
+ assertEquals(3, pubAuthorityService.getAllRootAuthoritiesInZone("One", AuthorityType.GROUP).size());
+ assertEquals(2, pubAuthorityService.getAllRootAuthoritiesInZone("Two", AuthorityType.GROUP).size());
+ assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("Three", AuthorityType.GROUP).size());
+
+ // I am not convinced of the definition of root within zone ...
+
+ pubAuthorityService.addAuthority("GROUP_1", "GROUP_2");
+ pubAuthorityService.addAuthority("GROUP_1", "GROUP_3");
+
+ assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("One", null).size());
+ assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Two", null).size());
+ assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Three", null).size());
+ assertEquals(1, pubAuthorityService.getAllRootAuthoritiesInZone("One", AuthorityType.GROUP).size());
+ assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Two", AuthorityType.GROUP).size());
+ assertEquals(0, pubAuthorityService.getAllRootAuthoritiesInZone("Three", AuthorityType.GROUP).size());
+ }
+
public void testGroupWildcards()
{
long before, after;
@@ -937,7 +1025,7 @@ public class AuthorityServiceTest extends TestCase
pubAuthorityService.setAuthorityDisplayName(authOne, "Selfish Crocodile");
assertEquals(pubAuthorityService.getAuthorityDisplayName(authOne), "Selfish Crocodile");
- String authTwo = pubAuthorityService.createAuthority(AuthorityType.GROUP, "Two", "Lamp posts", null);
+ String authTwo = pubAuthorityService.createAuthority(AuthorityType.GROUP, "Two", "Lamp posts", authorityService.getDefaultZones());
assertEquals(pubAuthorityService.getAuthorityDisplayName(authTwo), "Lamp posts");
pubAuthorityService.setAuthorityDisplayName(authTwo, "Happy Hippos");
assertEquals(pubAuthorityService.getAuthorityDisplayName(authTwo), "Happy Hippos");
diff --git a/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java b/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java
index bbe63d501a..a1d5f122a7 100644
--- a/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java
+++ b/source/java/org/alfresco/repo/security/authority/SimpleAuthorityServiceImpl.java
@@ -190,11 +190,6 @@ public class SimpleAuthorityServiceImpl implements AuthorityService
return "";
}
- public String createAuthority(AuthorityType type, String shortName, String authorityDisplayName,
- String authorityZone)
- {
- return "";
- }
public void deleteAuthority(String name)
{
@@ -298,16 +293,41 @@ public class SimpleAuthorityServiceImpl implements AuthorityService
public Set getAllAuthoritiesInZone(String zoneName, AuthorityType type)
{
- return Collections.emptySet();
- }
-
- public String getAuthorityZone(String name)
- {
- return AuthorityService.DEFAULT_ZONE;
+ return Collections.emptySet();
}
public NodeRef getOrCreateZone(String zoneName)
{
return null;
}
+
+ public void addAuthorityToZones(String authorityName, Set zones)
+ {
+
+ }
+
+ public String createAuthority(AuthorityType type, String shortName, String authorityDisplayName, Set authorityZones)
+ {
+ return "";
+ }
+
+ public Set getAllRootAuthoritiesInZone(String zoneName, AuthorityType type)
+ {
+ return Collections.emptySet();
+ }
+
+ public Set getAuthorityZones(String name)
+ {
+ return Collections.emptySet();
+ }
+
+ public Set getDefaultZones()
+ {
+ return Collections.emptySet();
+ }
+
+ public void removeAuthorityFromZones(String authorityName, Set zones)
+ {
+
+ }
}
diff --git a/source/java/org/alfresco/repo/security/authority/script/ScriptAuthorityService.java b/source/java/org/alfresco/repo/security/authority/script/ScriptAuthorityService.java
index b49be3cb65..96de1bde77 100644
--- a/source/java/org/alfresco/repo/security/authority/script/ScriptAuthorityService.java
+++ b/source/java/org/alfresco/repo/security/authority/script/ScriptAuthorityService.java
@@ -76,7 +76,7 @@ public class ScriptAuthorityService extends BaseScopableProcessorExtension
public ScriptGroup[] getAllRootGroups(boolean includeInternal)
{
Set groups = new LinkedHashSet(0);
- Set authorities = authorityService.getAllRootAuthorities(AuthorityType.GROUP);
+ Set authorities = authorityService.getAllRootAuthoritiesInZone(AuthorityService.ZONE_APP_DEFAULT, AuthorityType.GROUP);
for(String authority : authorities)
{
ScriptGroup group = new ScriptGroup(authority, authorityService);
@@ -128,7 +128,7 @@ public class ScriptAuthorityService extends BaseScopableProcessorExtension
*/
public ScriptGroup createRootGroup(String shortName, String displayName)
{
- authorityService.createAuthority(AuthorityType.GROUP, shortName, displayName, null);
+ authorityService.createAuthority(AuthorityType.GROUP, shortName, displayName, authorityService.getDefaultZones());
return getGroup(shortName);
}
diff --git a/source/java/org/alfresco/repo/security/authority/script/ScriptGroup.java b/source/java/org/alfresco/repo/security/authority/script/ScriptGroup.java
index 090bf477d7..01528ae64b 100644
--- a/source/java/org/alfresco/repo/security/authority/script/ScriptGroup.java
+++ b/source/java/org/alfresco/repo/security/authority/script/ScriptGroup.java
@@ -297,7 +297,7 @@ public class ScriptGroup implements Authority, Serializable
*/
public ScriptGroup createGroup(String shortName, String displayName)
{
- String authorityName = authorityService.createAuthority(AuthorityType.GROUP, shortName, displayName, null);
+ String authorityName = authorityService.createAuthority(AuthorityType.GROUP, shortName, displayName, authorityService.getDefaultZones());
authorityService.addAuthority(fullName, authorityName);
ScriptGroup childGroup = new ScriptGroup(authorityName, authorityService);
clearCaches();
diff --git a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java
index cc65139f7e..023c8c813d 100644
--- a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java
+++ b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java
@@ -173,12 +173,11 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
PropertyCheck.mandatory(this, "personCache", personCache);
PropertyCheck.mandatory(this, "personDao", personDao);
-
- this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode"));
+ this.policyComponent
+ .bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this, "onCreateNode"));
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), ContentModel.TYPE_PERSON, new JavaBehaviour(this,
"beforeDeleteNode"));
-
-
+
}
public UserNameMatcher getUserNameMatcher()
@@ -257,7 +256,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
if (tenantService.isEnabled() && (AuthenticationUtil.SYSTEM_USER_NAME.equals(AuthenticationUtil.getRunAsUser())) && tenantService.isTenantUser(userName))
{
final String tenantDomain = tenantService.getUserDomain(userName);
-
+
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork()
{
public NodeRef doWork() throws Exception
@@ -271,7 +270,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
return getPersonImpl(userName);
}
}
-
+
private NodeRef getPersonImpl(String userName)
{
NodeRef personNode = getPersonOrNull(userName);
@@ -583,10 +582,10 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
public NodeRef createPerson(Map properties)
{
- return createPerson(properties, null);
+ return createPerson(properties, authorityService.getDefaultZones());
}
- public NodeRef createPerson(Map properties, String zone)
+ public NodeRef createPerson(Map properties, Set zones)
{
String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USERNAME));
AuthorityType authorityType = AuthorityType.getAuthorityType(userName);
@@ -594,24 +593,24 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
{
throw new AlfrescoRuntimeException("Attempt to create person for an authority which is not a user");
}
-
+
tenantService.checkDomainUser(userName);
properties.put(ContentModel.PROP_USERNAME, userName);
properties.put(ContentModel.PROP_SIZE_CURRENT, 0L);
- NodeRef personRef = nodeService.createNode(
- getPeopleContainer(),
- ContentModel.ASSOC_CHILDREN,
- QName.createQName("cm", userName.toLowerCase(), namespacePrefixResolver), // Lowercase: ETHREEOH-1431
- ContentModel.TYPE_PERSON,
- properties).getChildRef();
-
- if (zone != null)
+ NodeRef personRef = nodeService.createNode(getPeopleContainer(), ContentModel.ASSOC_CHILDREN, QName.createQName("cm", userName.toLowerCase(), namespacePrefixResolver), // Lowercase:
+ // ETHREEOH-1431
+ ContentModel.TYPE_PERSON, properties).getChildRef();
+
+ if (zones != null)
{
- // Add the person to an authentication zone (corresponding to an external user registry)
- // Let's preserve case on this child association
- nodeService.addChild(authorityService.getOrCreateZone(zone), personRef, ContentModel.ASSOC_IN_ZONE, QName.createQName("cm", userName, namespacePrefixResolver));
+ for (String zone : zones)
+ {
+ // Add the person to an authentication zone (corresponding to an external user registry)
+ // Let's preserve case on this child association
+ nodeService.addChild(authorityService.getOrCreateZone(zone), personRef, ContentModel.ASSOC_IN_ZONE, QName.createQName("cm", userName, namespacePrefixResolver));
+ }
}
return personRef;
}
diff --git a/source/java/org/alfresco/repo/security/person/PersonTest.java b/source/java/org/alfresco/repo/security/person/PersonTest.java
index aac48a0c7f..1163bb09fb 100644
--- a/source/java/org/alfresco/repo/security/person/PersonTest.java
+++ b/source/java/org/alfresco/repo/security/person/PersonTest.java
@@ -26,7 +26,9 @@ package org.alfresco.repo.security.person;
import java.io.Serializable;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -94,6 +96,67 @@ public class PersonTest extends BaseSpringTest
super.onTearDownInTransaction();
}
+ public void testZones()
+ {
+ assertNull(authorityService.getAuthorityZones("derek"));
+ assertNull(authorityService.getAuthorityZones("null"));
+
+ personService.createPerson(createDefaultProperties("derek", "Derek", "Hulley", "dh@dh", "alfresco", rootNodeRef));
+ Set zones = authorityService.getAuthorityZones("derek");
+ assertEquals(2, zones.size());
+ authorityService.removeAuthorityFromZones("derek", zones);
+ assertEquals(0, authorityService.getAuthorityZones("derek").size());
+ authorityService.addAuthorityToZones("derek", zones);
+ assertEquals(2, authorityService.getAuthorityZones("derek").size());
+
+ HashSet newZones = null;
+ personService.createPerson(createDefaultProperties("null", "null", "null", "null", "null", rootNodeRef), newZones);
+ assertEquals(0, authorityService.getAuthorityZones("null").size());
+
+ newZones = new HashSet();
+ personService.createPerson(createDefaultProperties("empty", "empty", "empty", "empty", "empty", rootNodeRef), newZones);
+ assertEquals(0, authorityService.getAuthorityZones("empty").size());
+
+ newZones.add("One");
+ personService.createPerson(createDefaultProperties("1", "1", "1", "1", "1", rootNodeRef), newZones);
+ assertEquals(1, authorityService.getAuthorityZones("1").size());
+
+ newZones.add("Two");
+ personService.createPerson(createDefaultProperties("2", "2", "2", "2", "2", rootNodeRef), newZones);
+ assertEquals(2, authorityService.getAuthorityZones("2").size());
+
+ newZones.add("Three");
+ personService.createPerson(createDefaultProperties("3", "3", "3", "3", "3", rootNodeRef), newZones);
+ assertEquals(3, authorityService.getAuthorityZones("3").size());
+
+ HashSet toRemove = null;
+ authorityService.removeAuthorityFromZones("3", toRemove);
+ assertEquals(3, authorityService.getAuthorityZones("3").size());
+
+ toRemove = new HashSet();
+ authorityService.removeAuthorityFromZones("3", toRemove);
+ assertEquals(3, authorityService.getAuthorityZones("3").size());
+
+ toRemove.add("Three");
+ authorityService.removeAuthorityFromZones("3", toRemove);
+ assertEquals(2, authorityService.getAuthorityZones("3").size());
+
+ toRemove.add("Two");
+ authorityService.removeAuthorityFromZones("3", toRemove);
+ assertEquals(1, authorityService.getAuthorityZones("3").size());
+
+ toRemove.add("One");
+ authorityService.removeAuthorityFromZones("3", toRemove);
+ assertEquals(0, authorityService.getAuthorityZones("3").size());
+
+ authorityService.addAuthorityToZones("3", newZones);
+ assertEquals(3, authorityService.getAuthorityZones("3").size());
+ assertEquals(3, authorityService.getAllAuthoritiesInZone("One", null).size());
+ assertEquals(2, authorityService.getAllAuthoritiesInZone("Two", null).size());
+ assertEquals(1, authorityService.getAllAuthoritiesInZone("Three", null).size());
+
+ }
+
public void xtestPerformance()
{
personService.setCreateMissingPeople(false);
@@ -481,6 +544,8 @@ public class PersonTest extends BaseSpringTest
}
// It should work in a write transaction, though
transactionService.getRetryingTransactionHelper().doInTransaction(getMissingPersonWork, false, true);
+
+ transactionService.getRetryingTransactionHelper().doInTransaction(deletePersonWork, false, true);
}
public void testSplitPersonCleanup() throws Exception
diff --git a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java
index 52e28d4023..d3b98b2cc4 100644
--- a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java
+++ b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java
@@ -26,6 +26,7 @@ package org.alfresco.repo.security.sync;
import java.text.DateFormat;
import java.util.Date;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -162,21 +163,25 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
public void synchronize(boolean force)
{
Set visitedZoneIds = new TreeSet();
- for (String zoneId : this.applicationContextManager.getInstanceIds())
+ for (String id : this.applicationContextManager.getInstanceIds())
{
- ApplicationContext context = this.applicationContextManager.getApplicationContext(zoneId);
+ StringBuilder builder = new StringBuilder(32);
+ builder.append(AuthorityService.ZONE_AUTH_EXT_PREFIX);
+ builder.append(id);
+ String zoneId = builder.toString();
+ ApplicationContext context = this.applicationContextManager.getApplicationContext(id);
try
{
UserRegistry plugin = (UserRegistry) context.getBean(this.sourceBeanName);
if (!(plugin instanceof ActivateableBean) || ((ActivateableBean) plugin).isActive())
{
ChainingUserRegistrySynchronizer.logger.info("Synchronizing users and groups with user registry '"
- + zoneId + "'");
+ + id + "'");
if (force)
{
ChainingUserRegistrySynchronizer.logger
.warn("Forced synchronization with user registry '"
- + zoneId
+ + id
+ "'; some users and groups previously created by synchronization with this user registry may be removed.");
}
int personsProcessed = syncPersonsWithPlugin(zoneId, plugin, force, visitedZoneIds);
@@ -243,10 +248,11 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
else
{
// The person does not exist in this zone, but may exist in another zone
- String zone = this.authorityService.getAuthorityZone(personName);
- if (zone != null)
+ Set zones = this.authorityService.getAuthorityZones(personName);
+ if (zones != null)
{
- if (visitedZoneIds.contains(zone))
+ zones.retainAll(visitedZoneIds);
+ if (zones.size() > 0)
{
// A person that exists in a different zone with higher precedence
continue;
@@ -263,7 +269,7 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
// The person did not exist at all
ChainingUserRegistrySynchronizer.logger.info("Creating user '" + personName + "'");
}
- this.personService.createPerson(personProperties, zoneId);
+ this.personService.createPerson(personProperties, getZones(zoneId));
}
// Increment the count of processed people
processedCount++;
@@ -294,7 +300,7 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
return processedCount;
}
-
+
/**
* Synchronizes local groups (authorities) with a {@link UserRegistry} for a particular zone.
*
@@ -360,10 +366,11 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
else
{
String groupShortName = this.authorityService.getShortName(groupName);
- String groupZone = this.authorityService.getAuthorityZone(groupName);
- if (groupZone != null)
+ Set groupZones = this.authorityService.getAuthorityZones(groupName);
+ if (groupZones != null)
{
- if (visitedZoneIds.contains(groupZone))
+ groupZones.retainAll(visitedZoneIds);
+ if (groupZones.size() > 0)
{
// A group that exists in a different zone with higher precedence
continue;
@@ -382,7 +389,7 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
// create the group
this.authorityService.createAuthority(AuthorityType.getAuthorityType(groupName), groupShortName,
- (String) groupProperties.get(ContentModel.PROP_AUTHORITY_DISPLAY_NAME), zoneId);
+ (String) groupProperties.get(ContentModel.PROP_AUTHORITY_DISPLAY_NAME), getZones(zoneId));
Set children = group.getChildAssociations();
if (!children.isEmpty())
{
@@ -476,4 +483,12 @@ public class ChainingUserRegistrySynchronizer implements UserRegistrySynchronize
}
this.attributeService.setAttribute(path, zoneId, new LongAttributeValue(lastModifiedMillis));
}
+
+ private Set getZones(String zoneId)
+ {
+ HashSet zones = new HashSet(2, 1.0f);
+ zones.add(AuthorityService.ZONE_APP_DEFAULT);
+ zones.add(zoneId);
+ return zones;
+ }
}
diff --git a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java
index 54f1c3be5f..074f823d3c 100644
--- a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java
+++ b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java
@@ -347,7 +347,7 @@ public class ChainingUserRegistrySynchronizerTest extends BaseSpringTest
assertTrue(this.authorityService.authorityExists(longName));
// Check in correct zone
- assertEquals(zone, this.authorityService.getAuthorityZone(longName));
+ assertTrue(this.authorityService.getAuthorityZones(longName).contains(AuthorityService.ZONE_AUTH_EXT_PREFIX+zone));
if (AuthorityType.getAuthorityType(longName).equals(AuthorityType.GROUP))
{
// Check groups have expected members
@@ -378,7 +378,7 @@ public class ChainingUserRegistrySynchronizerTest extends BaseSpringTest
assertFalse(this.authorityService.authorityExists(longName));
// Check there is no zone
- assertNull(this.authorityService.getAuthorityZone(longName));
+ assertNull(this.authorityService.getAuthorityZones(longName));
if (!AuthorityType.getAuthorityType(longName).equals(AuthorityType.GROUP))
{
// Check person does not exist
diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java
index 39e5ffff4a..af3479d1a2 100644
--- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java
+++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java
@@ -26,6 +26,7 @@ package org.alfresco.repo.site;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -103,6 +104,8 @@ public class SiteServiceImpl implements SiteService, SiteModel
private static final int GROUP_PREFIX_LENGTH = PermissionService.GROUP_PREFIX.length();
private static final int GROUP_SITE_PREFIX_LENGTH = GROUP_SITE_PREFIX.length();
+ private static final Set ZONES;
+
/** Site home ref cache (Tennant aware) */
private Map siteHomeRefs = new ConcurrentHashMap(4);
@@ -139,6 +142,13 @@ public class SiteServiceImpl implements SiteService, SiteModel
private RetryingTransactionHelper retryingTransactionHelper;
private Comparator roleComparator ;
+ static
+ {
+ HashSet zones = new HashSet(2, 1.0f);
+ zones.add(AuthorityService.ZONE_APP_SHARE);
+ zones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+ ZONES = Collections.unmodifiableSet(zones);
+ }
/**
* Set the path to the location of the sites root folder. For example:
@@ -361,13 +371,13 @@ public class SiteServiceImpl implements SiteService, SiteModel
{
// Create the site's groups
String siteGroup = authorityService
- .createAuthority(AuthorityType.GROUP, getSiteGroup(shortName, false));
+ .createAuthority(AuthorityType.GROUP, getSiteGroup(shortName, false), getSiteGroup(shortName, false), ZONES);
Set permissions = permissionService.getSettablePermissions(SiteModel.TYPE_SITE);
for (String permission : permissions)
{
// Create a group for the permission
String permissionGroup = authorityService.createAuthority(AuthorityType.GROUP, getSiteRoleGroup(
- shortName, permission, false));
+ shortName, permission, false), getSiteRoleGroup(shortName, permission, false), ZONES);
authorityService.addAuthority(siteGroup, permissionGroup);
// Assign the group the relevant permission on the site
diff --git a/source/java/org/alfresco/service/cmr/security/AuthorityService.java b/source/java/org/alfresco/service/cmr/security/AuthorityService.java
index e45993d450..acda9dd928 100644
--- a/source/java/org/alfresco/service/cmr/security/AuthorityService.java
+++ b/source/java/org/alfresco/service/cmr/security/AuthorityService.java
@@ -27,9 +27,9 @@ package org.alfresco.service.cmr.security;
import java.util.Set;
import org.alfresco.service.Auditable;
+import org.alfresco.service.NotAuditable;
import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.namespace.QName;
/**
* The service that encapsulates authorities granted to users.
@@ -47,13 +47,32 @@ import org.alfresco.service.namespace.QName;
*/
@PublicService
public interface AuthorityService
-{
+{
+ /**
+ * The default application zone.
+ */
+ public static String ZONE_APP_DEFAULT = "APP.DEFAULT";
/**
- * The default zone that owns all authorities for which a zone is not explicitly specified in the authorityZone
- * property
+ * The WCM application zone.
*/
- public static final String DEFAULT_ZONE = "";
+ public static String ZONE_APP_WCM = "APP.WCM";
+
+ /**
+ * The SHARE application zone.
+ */
+ public static String ZONE_APP_SHARE = "APP.SHARE";
+
+ /**
+ * Default authentication
+ */
+ public static String ZONE_AUTH_ALFRESCO = "AUTH.ALF";
+
+ /**
+ * Prefix for external auth ids
+ */
+ public static String ZONE_AUTH_EXT_PREFIX = "AUTH.EXT.";
+
/**
* Check of the current user has admin authority.
@@ -160,8 +179,8 @@ public interface AuthorityService
* @return the full name of the authority (this will be the prefix, if any associated with the type appended with
* the short name)
*/
- @Auditable(parameters = {"type", "shortName", "authorityDisplayName", "authorityZone"})
- public String createAuthority(AuthorityType type, String shortName, String authorityDisplayName, String authorityZone);
+ @Auditable(parameters = {"type", "shortName", "authorityDisplayName", "authorityZones"})
+ public String createAuthority(AuthorityType type, String shortName, String authorityDisplayName, Set authorityZones);
/**
* Set an authority to include another authority. For example, adding a
@@ -312,7 +331,7 @@ public interface AuthorityService
* authority exists but has no zone, or null
if the authority does not exist.
*/
@Auditable(parameters = {"name"})
- public String getAuthorityZone(String name);
+ public Set getAuthorityZones(String name);
/**
* Gets the names of all authorities in a zone, optionally filtered by type.
@@ -325,4 +344,39 @@ public interface AuthorityService
*/
@Auditable(parameters = {"zoneName", "type"})
public Set getAllAuthoritiesInZone(String zoneName, AuthorityType type);
+
+ /**
+ * Gets the names of all authorities in a zone, optionally filtered by type.
+ *
+ * @param zoneName
+ * the zone name
+ * @param type
+ * the authority type to filter by or null
for all authority types
+ * @return the names of all authorities in a zone, optionally filtered by type
+ */
+ @Auditable(parameters = {"zoneName", "type"})
+ public Set getAllRootAuthoritiesInZone(String zoneName, AuthorityType type);
+
+ /**
+ * Add a zone to an authority.
+ * @param authorityName
+ * @param zone
+ */
+ @Auditable(parameters = {"authorityName", "zones"})
+ public void addAuthorityToZones(String authorityName, Set zones);
+
+ /**
+ * Remove a zone from an authority
+ * @param authorityName
+ * @param zone
+ */
+ @Auditable(parameters = {"authorityName", "zones"})
+ public void removeAuthorityFromZones(String authorityName, Set zones);
+
+ /**
+ * Get the name of the default zone.
+ * @return the default zone
+ */
+ @NotAuditable
+ public Set getDefaultZones();
}
diff --git a/source/java/org/alfresco/service/cmr/security/PersonService.java b/source/java/org/alfresco/service/cmr/security/PersonService.java
index 0328ef5b1f..0979ad3e76 100644
--- a/source/java/org/alfresco/service/cmr/security/PersonService.java
+++ b/source/java/org/alfresco/service/cmr/security/PersonService.java
@@ -146,13 +146,12 @@ public interface PersonService
*
* @param properties
* the properties
- * @param zone
- * an identifier for the external user registry owning the person information, or null
if
- * not applicable.
+ * @param zones
+ * a set if zones including the identifier for the external user registry owning the person information, or null
or an empty set
* @return the node ref
*/
- @Auditable(parameters = {"properties", "zone"})
- public NodeRef createPerson(Map properties, String zone);
+ @Auditable(parameters = {"properties", "zones"})
+ public NodeRef createPerson(Map properties, Set zones);
/**
* Delete the person identified by the given user name.
diff --git a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java
index c1c943ab91..9c1379467b 100644
--- a/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java
+++ b/source/java/org/alfresco/wcm/sandbox/SandboxFactory.java
@@ -25,6 +25,7 @@
package org.alfresco.wcm.sandbox;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -64,6 +65,8 @@ import org.apache.commons.logging.LogFactory;
*/
public final class SandboxFactory extends WCMUtil
{
+ private static final Set ZONES;
+
public static final String[] PERMISSIONS = new String[] {
PermissionService.WCM_CONTENT_MANAGER,
PermissionService.WCM_CONTENT_PUBLISHER,
@@ -80,6 +83,14 @@ public final class SandboxFactory extends WCMUtil
private VirtServerRegistry virtServerRegistry;
private AuthorityService authorityService;
+ static
+ {
+ HashSet zones = new HashSet(2, 1.0f);
+ zones.add(AuthorityService.ZONE_APP_WCM);
+ zones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
+ ZONES = Collections.unmodifiableSet(zones);
+ }
+
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
@@ -365,7 +376,7 @@ public final class SandboxFactory extends WCMUtil
String group = authorityService.getName(AuthorityType.GROUP, shortName);
if (!authorityService.authorityExists(group))
{
- authorityService.createAuthority(AuthorityType.GROUP, shortName);
+ authorityService.createAuthority(AuthorityType.GROUP, shortName, shortName, ZONES);
}
if (!isPermissionSet(dirRef, group, permission))
{
@@ -399,7 +410,7 @@ public final class SandboxFactory extends WCMUtil
String group = authorityService.getName(AuthorityType.GROUP, shortName);
if (!authorityService.authorityExists(group))
{
- authorityService.createAuthority(AuthorityType.GROUP, shortName);
+ authorityService.createAuthority(AuthorityType.GROUP, shortName, shortName, ZONES);
}
Set members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true);
if (!members.contains(user))