Extended zone support for multiple zones and added Authorities (including people) to zones. (MOB-762: Part 1)

WCM and Share groups are not in the default zones so they can be hidden in the UI.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14762 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind
2009-06-17 11:57:21 +00:00
parent 0e2e131279
commit e3df62325d
23 changed files with 862 additions and 151 deletions

View File

@@ -58,6 +58,72 @@
<view:permission>Read</view:permission>
</view:ace>
</view:acl>
<view:associations>
<sys:children>
<cm:zone view:childName="cm:AUTH.ALF">
<view:aspects>
<sys:referenceable />
</view:aspects>
<view:properties>
<sys:node-uuid>AUTH.ALF</sys:node-uuid>
<cm:name>AUTH.ALF</cm:name>
</view:properties>
<view:associations>
<cm:inZone>
<view:reference
view:pathref="${system.people_container.childname}/cm:${alfresco_user_store.adminusername}"
view:childName="cm:${alfresco_user_store.adminusername}" />
</cm:inZone>
<cm:inZone>
<view:reference
view:pathref="${system.people_container.childname}/cm:${alfresco_user_store.guestusername}"
view:childName="cm:${alfresco_user_store.guestusername}" />
</cm:inZone>
<cm:inZone>
<view:reference
view:pathref="${system.authorities_container.childname}/cm:GROUP_ALFRESCO_ADMINISTRATORS"
view:childName="cm:GROUP_ALFRESCO_ADMINISTRATORS" />
</cm:inZone>
<cm:inZone>
<view:reference
view:pathref="${system.authorities_container.childname}/cm:GROUP_EMAIL_CONTRIBUTORS"
view:childName="cm:GROUP_EMAIL_CONTRIBUTORS" />
</cm:inZone>
</view:associations>
</cm:zone>
<cm:zone view:childName="cm:APP.DEFAULT">
<view:aspects>
<sys:referenceable />
</view:aspects>
<view:properties>
<sys:node-uuid>APP.DEFAULT</sys:node-uuid>
<cm:name>APP.DEFAULT</cm:name>
</view:properties>
<view:associations>
<cm:inZone>
<view:reference
view:pathref="${system.people_container.childname}/cm:${alfresco_user_store.adminusername}"
view:childName="cm:${alfresco_user_store.adminusername}" />
</cm:inZone>
<cm:inZone>
<view:reference
view:pathref="${system.people_container.childname}/cm:${alfresco_user_store.guestusername}"
view:childName="cm:${alfresco_user_store.guestusername}" />
</cm:inZone>
<cm:inZone>
<view:reference
view:pathref="${system.authorities_container.childname}/cm:GROUP_ALFRESCO_ADMINISTRATORS"
view:childName="cm:GROUP_ALFRESCO_ADMINISTRATORS" />
</cm:inZone>
<cm:inZone>
<view:reference
view:pathref="${system.authorities_container.childname}/cm:GROUP_EMAIL_CONTRIBUTORS"
view:childName="cm:GROUP_EMAIL_CONTRIBUTORS" />
</cm:inZone>
</view:associations>
</cm:zone>
</sys:children>
</view:associations>
</sys:container>
</view:view>

View File

@@ -382,7 +382,7 @@
<!-- dictionary models -->
<cache
name="org.alfresco.cache.compiledModelsCache"
maxElementsInMemory="100"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
/>
@@ -390,7 +390,7 @@
<!-- dictionary namespaces -->
<cache
name="org.alfresco.cache.prefixesCache"
maxElementsInMemory="100"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
/>

View File

@@ -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.

View File

@@ -1808,4 +1808,29 @@
</property>
</bean>
<bean id="patch.authorityDefaultZonesPatch" class="org.alfresco.repo.admin.patch.impl.AuthorityDefaultZonesPatch" parent="basePatch" >
<property name="id"><value>patch.authorityDefaultZonesPatch</value></property>
<property name="description"><value>patch.authorityDefaultZonesPatch.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2013</value></property>
<property name="targetSchema"><value>2014</value></property>
<property name="authorityService">
<ref bean="authorityService" />
</property>
<property name="avmService">
<ref bean="avmService" />
</property>
<property name="siteService">
<ref bean="siteService" />
</property>
<property name="hibernateSessionHelper">
<ref bean="hibernateSessionHelper"/>
</property>
<property name="dependsOn">
<list>
<ref bean="patch.authorityMigration" />
</list>
</property>
</bean>
</beans>

View File

@@ -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.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.getAllRootAuthorities=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
</value>
</property>
</bean>

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number
version.schema=2013
version.schema=2014

View File

@@ -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<String> defaultZones = new HashSet<String>(2, 1.0f);
defaultZones.add(AuthorityService.ZONE_APP_DEFAULT);
defaultZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
List<Action> personActions = new ArrayList<Action>(1);
personActions.add(new Action(null, defaultZones, ActionType.ADD));
setZones(AuthorityType.USER, personActions);
}
private void setZonesForGroups()
{
Set<String> defaultZones = new HashSet<String>(2, 1.0f);
defaultZones.add(AuthorityService.ZONE_APP_DEFAULT);
defaultZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
Set<String> wcmZones = new HashSet<String>(2, 1.0f);
wcmZones.add(AuthorityService.ZONE_APP_WCM);
wcmZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
Set<String> shareZones = new HashSet<String>(2, 1.0f);
shareZones.add(AuthorityService.ZONE_APP_SHARE);
shareZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
List<AVMStoreDescriptor> stores = avmService.getStores();
List<SiteInfo> sites = siteService.listSites(null, null);
List<Action> groupActions = new ArrayList<Action>(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<Action> actions)
{
//hibernateSessionHelper.mark();
Set<String> 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<String> zones, String authority)
{
Set<String> 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<String> zones;
ActionType actionType;
Action(String name, Set<String> zones, ActionType actionType)
{
this.name = name;
this.zones = zones;
this.actionType = actionType;
}
}
}

View File

@@ -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();
}
}
@@ -1076,10 +1076,10 @@ public class IndexInfo implements IndexMonitor
try
{
mainIndexReader = null;
getReadLock();
}
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();
}

View File

@@ -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<String> 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 <code>null</code> if the authority does not exist.
*/
public String getAuthorityZone(String name);
public Set<String> 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<String> getAllAuthoritiesInZone(String zoneName, AuthorityType type);
/**
* Add an authority to zones
* @param authorityName
* @param zones
*/
public void addAuthorityToZones(String authorityName, Set<String> zones);
/**
* Remove an authority from zones.
* @param authorityName
* @param zones
*/
public void removeAuthorityFromZones(String authorityName, Set<String> zones);
/**
* Get all root authorities in a zone
* @param zoneName
* @param type (optional)
* @return the set of authority names
*/
public Set<String> getAllRootAuthoritiesInZone(String zoneName, AuthorityType type);
}

View File

@@ -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<String> authorityZones)
{
HashMap<QName, Serializable> props = new HashMap<QName, Serializable>();
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,8 +174,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
return Collections.<String> emptySet();
}
Set<String> authorities = new HashSet<String>();
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);
}
@@ -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<String> authorities = new HashSet<String>();
@@ -204,8 +201,8 @@ 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);
}
}
@@ -284,8 +281,8 @@ public class AuthorityDAOImpl implements AuthorityDAO
private void addAuthorityNameIfMatches(Set<String> 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<String> authorities, String authorityName, AuthorityType type, Pattern pattern)
@@ -307,8 +304,7 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
private void findAuthorities(AuthorityType type, String name, Set<String> authorities, boolean parents,
boolean recursive)
private void findAuthorities(AuthorityType type, String name, Set<String> authorities, boolean parents, boolean recursive)
{
AuthorityType localType = AuthorityType.getAuthorityType(name);
if (localType.equals(AuthorityType.GUEST))
@@ -332,26 +328,23 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
private void findAuthorities(AuthorityType type, Pattern pattern, NodeRef nodeRef, Set<String> authorities,
boolean parents, boolean recursive, boolean includeNode)
private void findAuthorities(AuthorityType type, Pattern pattern, NodeRef nodeRef, Set<String> 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<ChildAssociationRef> cars = parents ? nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_MEMBER,
RegexQNamePattern.MATCH_ALL) : nodeService.getChildAssocs(nodeRef);
List<ChildAssociationRef> 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<ChildAssociationRef> results = nodeService.getChildAssocs(getAuthorityContainer(),
ContentModel.ASSOC_CHILDREN, QName.createQName("cm", name, namespacePrefixResolver));
List<ChildAssociationRef> 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<ChildAssociationRef> results = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL,
qnameAssocSystem);
List<ChildAssociationRef> 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<ChildAssociationRef> results = nodeService.getChildAssocs(zoneContainerRef, ContentModel.ASSOC_CHILDREN,
zoneQName);
List<ChildAssociationRef> results = nodeService.getChildAssocs(zoneContainerRef, ContentModel.ASSOC_CHILDREN, zoneQName);
if (results.isEmpty())
{
HashMap<QName, Serializable> props = new HashMap<QName, Serializable>();
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,27 +496,35 @@ public class AuthorityDAOImpl implements AuthorityDAO
}
}
public String getAuthorityZone(String name)
public Set<String> getAuthorityZones(String name)
{
HashSet<String> zones = new HashSet<String>();
NodeRef childRef = getAuthorityOrNull(name);
if (childRef == null)
{
return null;
}
List<ChildAssociationRef> results = nodeService.getParentAssocs(childRef, ContentModel.ASSOC_IN_ZONE,
RegexQNamePattern.MATCH_ALL);
List<ChildAssociationRef> 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();
for (ChildAssociationRef current : results)
{
NodeRef zoneRef = current.getParentRef();
Serializable value = nodeService.getProperty(zoneRef, ContentModel.PROP_NAME);
if (value == null)
{
return null;
continue;
}
return DefaultTypeConverter.INSTANCE.convert(String.class, value);
else
{
String zone = DefaultTypeConverter.INSTANCE.convert(String.class, value);
zones.add(zone);
}
}
return zones;
}
public Set<String> getAllAuthoritiesInZone(String zoneName, AuthorityType type)
@@ -525,6 +538,51 @@ public class AuthorityDAOImpl implements AuthorityDAO
return authorities;
}
public void addAuthorityToZones(String authorityName, Set<String> 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<String> zones)
{
if ((zones != null) && (zones.size() > 0))
{
NodeRef authRef = getAuthorityOrNull(authorityName);
List<ChildAssociationRef> 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
{
/**
@@ -591,7 +649,13 @@ public class AuthorityDAOImpl implements AuthorityDAO
return true;
}
}
public Set<String> getAllRootAuthoritiesInZone(String zoneName, AuthorityType type)
{
Set<String> roots = getAllRootAuthorities(type);
Set<String> inZone = getAllAuthoritiesInZone(zoneName, type);
roots.retainAll(inZone);
return roots;
}
}

View File

@@ -53,6 +53,8 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
{
private static Log logger = LogFactory.getLog(AuthorityServiceImpl.class);
private static Set<String> DEFAULT_ZONES = new HashSet<String>();
private PersonService personService;
private NodeService nodeService;
@@ -73,6 +75,12 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
private Set<String> 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<String> 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<String> 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<String> zones)
{
authorityDAO.addAuthorityToZones(authorityName, zones);
}
public void removeAuthorityFromZones(String authorityName, Set<String> zones)
{
authorityDAO.removeAuthorityFromZones(authorityName, zones);
}
public Set<String> getDefaultZones()
{
return DEFAULT_ZONES;
}
public Set<String> getAllRootAuthoritiesInZone(String zoneName, AuthorityType type)
{
return authorityDAO.getAllRootAuthoritiesInZone(zoneName, type);
}
}

View File

@@ -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<String> 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<String> newZones = null;
pubAuthorityService.createAuthority(AuthorityType.GROUP, "NULL", "NULL", newZones);
assertEquals(0, pubAuthorityService.getAuthorityZones("GROUP_NULL").size());
newZones = new HashSet<String>();
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<String> toRemove = null;
pubAuthorityService.removeAuthorityFromZones("GROUP_3", toRemove);
assertEquals(3, pubAuthorityService.getAuthorityZones("GROUP_3").size());
toRemove = new HashSet<String>();
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");

View File

@@ -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<String> getAllAuthoritiesInZone(String zoneName, AuthorityType type)
{
return Collections.emptySet();
}
public String getAuthorityZone(String name)
{
return AuthorityService.DEFAULT_ZONE;
return Collections.<String>emptySet();
}
public NodeRef getOrCreateZone(String zoneName)
{
return null;
}
public void addAuthorityToZones(String authorityName, Set<String> zones)
{
}
public String createAuthority(AuthorityType type, String shortName, String authorityDisplayName, Set<String> authorityZones)
{
return "";
}
public Set<String> getAllRootAuthoritiesInZone(String zoneName, AuthorityType type)
{
return Collections.<String>emptySet();
}
public Set<String> getAuthorityZones(String name)
{
return Collections.<String>emptySet();
}
public Set<String> getDefaultZones()
{
return Collections.<String>emptySet();
}
public void removeAuthorityFromZones(String authorityName, Set<String> zones)
{
}
}

View File

@@ -76,7 +76,7 @@ public class ScriptAuthorityService extends BaseScopableProcessorExtension
public ScriptGroup[] getAllRootGroups(boolean includeInternal)
{
Set<ScriptGroup> groups = new LinkedHashSet<ScriptGroup>(0);
Set<String> authorities = authorityService.getAllRootAuthorities(AuthorityType.GROUP);
Set<String> 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);
}

View File

@@ -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();

View File

@@ -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()
@@ -583,10 +582,10 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
public NodeRef createPerson(Map<QName, Serializable> properties)
{
return createPerson(properties, null);
return createPerson(properties, authorityService.getDefaultZones());
}
public NodeRef createPerson(Map<QName, Serializable> properties, String zone)
public NodeRef createPerson(Map<QName, Serializable> properties, Set<String> zones)
{
String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USERNAME));
AuthorityType authorityType = AuthorityType.getAuthorityType(userName);
@@ -600,19 +599,19 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
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();
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)
if (zones != 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(authorityService.getOrCreateZone(zone), personRef, ContentModel.ASSOC_IN_ZONE, QName.createQName("cm", userName, namespacePrefixResolver));
}
}
return personRef;
}

View File

@@ -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<String> 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<String> newZones = null;
personService.createPerson(createDefaultProperties("null", "null", "null", "null", "null", rootNodeRef), newZones);
assertEquals(0, authorityService.getAuthorityZones("null").size());
newZones = new HashSet<String>();
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<String> toRemove = null;
authorityService.removeAuthorityFromZones("3", toRemove);
assertEquals(3, authorityService.getAuthorityZones("3").size());
toRemove = new HashSet<String>();
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

View File

@@ -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<String> visitedZoneIds = new TreeSet<String>();
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<String> 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++;
@@ -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<String> 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<String> 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<String> getZones(String zoneId)
{
HashSet<String> zones = new HashSet<String>(2, 1.0f);
zones.add(AuthorityService.ZONE_APP_DEFAULT);
zones.add(zoneId);
return zones;
}
}

View File

@@ -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

View File

@@ -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<String> ZONES;
/** Site home ref cache (Tennant aware) */
private Map<String, NodeRef> siteHomeRefs = new ConcurrentHashMap<String, NodeRef>(4);
@@ -139,6 +142,13 @@ public class SiteServiceImpl implements SiteService, SiteModel
private RetryingTransactionHelper retryingTransactionHelper;
private Comparator<String> roleComparator ;
static
{
HashSet<String> zones = new HashSet<String>(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<String> 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

View File

@@ -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.
@@ -48,12 +48,31 @@ 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<String> 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 <code>null</code> if the authority does not exist.
*/
@Auditable(parameters = {"name"})
public String getAuthorityZone(String name);
public Set<String> 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<String> 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 <code>null</code> for all authority types
* @return the names of all authorities in a zone, optionally filtered by type
*/
@Auditable(parameters = {"zoneName", "type"})
public Set<String> 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<String> zones);
/**
* Remove a zone from an authority
* @param authorityName
* @param zone
*/
@Auditable(parameters = {"authorityName", "zones"})
public void removeAuthorityFromZones(String authorityName, Set<String> zones);
/**
* Get the name of the default zone.
* @return the default zone
*/
@NotAuditable
public Set<String> getDefaultZones();
}

View File

@@ -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 <code>null</code> if
* not applicable.
* @param zones
* a set if zones including the identifier for the external user registry owning the person information, or <code>null</code> or an empty set
* @return the node ref
*/
@Auditable(parameters = {"properties", "zone"})
public NodeRef createPerson(Map<QName, Serializable> properties, String zone);
@Auditable(parameters = {"properties", "zones"})
public NodeRef createPerson(Map<QName, Serializable> properties, Set<String> zones);
/**
* Delete the person identified by the given user name.

View File

@@ -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<String> 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<String> zones = new HashSet<String>(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<String> members = authorityService.getContainedAuthorities(AuthorityType.USER, group, true);
if (!members.contains(user))