MT Share - initial checkpoint

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13459 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2009-03-03 22:25:50 +00:00
parent 8f1fe3f3df
commit b5dbd53461
26 changed files with 6240 additions and 4935 deletions

View File

@@ -8,6 +8,7 @@
<property name="feedDaoService" ref="feedDaoService"/>
<property name="feedControlDaoService" ref="feedControlDaoService"/>
<property name="authorityService" ref="AuthorityService"/>
<property name="tenantService" ref="tenantService"/>
<property name="userNamesAreCaseSensitive" value="${user.name.caseSensitive}"/>
<property name="feedGenerator" ref="feedGenerator"/>
<property name="maxFeedItems" value="100"/>
@@ -59,6 +60,7 @@
<property name="permissionService" ref="PermissionService"/>
<property name="transactionService" ref="transactionService"/>
<property name="personService" ref="personService"/>
<property name="tenantService" ref="tenantService"/>
</bean>
<bean id="baseFeedGenerator" class="org.alfresco.repo.activities.feed.AbstractFeedGenerator" abstract="true" init-method="init">

View File

@@ -56,6 +56,7 @@
<!--
Import activation extensions for Multi-Tenancy.
-->
<import resource="classpath:alfresco/mt/mt-base-context.xml"/>
<import resource="classpath*:alfresco/extension/mt/*-context.xml"/>
<!--

View File

@@ -319,34 +319,34 @@
</property>
</bean>
<bean name="companyHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider">
<bean name="baseHomeFolderProvider" class="org.alfresco.repo.security.person.AbstractHomeFolderProvider" abstract="true">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
<property name="tenantService">
<ref bean="tenantService" />
</property>
</bean>
<bean name="companyHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider" parent="baseHomeFolderProvider">
<property name="path">
<value>/${spaces.company_home.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
</bean>
<bean name="guestHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<bean name="guestHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider" parent="baseHomeFolderProvider">
<property name="path">
<value>/${spaces.company_home.childname}/${spaces.guest_home.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
<property name="userPermissions">
<set>
<value>Consumer</value>
@@ -354,25 +354,15 @@
</property>
</bean>
<bean name="bootstrapHomeFolderProvider" class="org.alfresco.repo.security.person.BootstrapHomeFolderProvider">
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
</bean>
<bean name="bootstrapHomeFolderProvider" class="org.alfresco.repo.security.person.BootstrapHomeFolderProvider" parent="baseHomeFolderProvider" />
<bean name="personalHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<bean name="personalHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider" parent="baseHomeFolderProvider">
<property name="path">
<value>/${spaces.company_home.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
<property name="inheritsPermissionsOnCreate">
<value>false</value>
</property>
@@ -388,19 +378,13 @@
</property>
</bean>
<bean name="userHomesHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider">
<property name="serviceRegistry">
<ref bean="ServiceRegistry" />
</property>
<bean name="userHomesHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider" parent="baseHomeFolderProvider">
<property name="path">
<value>/${spaces.company_home.childname}/${spaces.user_homes.childname}</value>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
<property name="homeFolderManager">
<ref bean="homeFolderManager" />
</property>
<property name="inheritsPermissionsOnCreate">
<value>false</value>
</property>
@@ -449,6 +433,9 @@
<property name="userNameLength">
<value>6</value>
</property>
<property name="tenantService">
<ref bean="tenantService"/>
</property>
</bean>
<!-- Used for generating passwords -->

View File

@@ -383,7 +383,7 @@
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/workflow/invitation-moderated_processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">true</prop>
<prop key="redeploy">false</prop>
</props>

View File

@@ -7,26 +7,7 @@
<!-- MT Admin Service Implementation -->
<!-- -->
<bean id="tenantAdminService" class="org.alfresco.repo.tenant.MultiTAdminServiceImpl">
<!--
<property name="nodeService" ref="NodeService"/>
-->
<property name="nodeService" ref="dbNodeServiceImpl"/> <!-- TODO - go direct, until we expose deleteStore via public NodeService API -->
<property name="dictionaryComponent" ref="dictionaryService"/>
<property name="authenticationComponent" ref="authenticationComponent"/>
<property name="repoAdminService" ref="RepoAdminService"/>
<property name="tenantService" ref="tenantService"/>
<property name="transactionService" ref="transactionComponent"/>
<property name="attributeService" ref="AttributeService"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
<property name="tenantFileContentStore" ref="tenantFileContentStore"/>
<property name="workflowService" ref="WorkflowService"/>
<property name="repositoryExporterService" ref="repositoryExporterComponent"/>
<property name="workflowDeployer" ref="workflowBootstrap"/>
<property name="moduleService" ref="moduleService"/>
</bean>
<bean id="tenantAdminService" parent="baseMultiTAdminService" />
<bean id="tenantInterpreter" class="org.alfresco.repo.tenant.TenantInterpreter">
<property name="transactionService" ref="transactionComponent"/>

View File

@@ -0,0 +1,28 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="baseMultiTAdminService" class="org.alfresco.repo.tenant.MultiTAdminServiceImpl" abstract="true">
<!--
<property name="nodeService" ref="NodeService"/>
-->
<property name="nodeService" ref="dbNodeServiceImpl"/> <!-- TODO - go direct, until we expose deleteStore via public NodeService API -->
<property name="dictionaryComponent" ref="dictionaryService"/>
<property name="authenticationComponent" ref="authenticationComponent"/>
<property name="repoAdminService" ref="RepoAdminService"/>
<property name="tenantService" ref="tenantService"/>
<property name="transactionService" ref="transactionComponent"/>
<property name="attributeService" ref="AttributeService"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
<property name="tenantFileContentStore" ref="tenantFileContentStore"/>
<property name="workflowService" ref="WorkflowService"/>
<property name="repositoryExporterService" ref="repositoryExporterComponent"/>
<property name="moduleService" ref="moduleService"/>
<property name="siteAVMBootstrap" ref="siteAVMBootstrap"/>
</bean>
</beans>

View File

@@ -828,7 +828,7 @@
<value>org.alfresco.service.cmr.avm.AVMService</value>
</property>
<property name="target">
<ref bean="avmServiceBase"/>
<ref bean="avmServiceMT"/>
</property>
<property name="interceptorNames">
<list>
@@ -838,6 +838,15 @@
</property>
</bean>
<bean id="avmServiceMT" class="org.alfresco.repo.avm.MultiTAVMService">
<property name="avmService">
<ref bean="avmServiceBase"/>
</property>
<property name="tenantService">
<ref bean="tenantService"/>
</property>
</bean>
<bean id="avmServiceBase" class="org.alfresco.repo.avm.AVMServiceImpl">
<property name="avmRepository">
<ref bean="avmRepository"/>

View File

@@ -74,6 +74,7 @@
<property name="sitesXPath">
<value>./${spaces.company_home.childname}/st:sites</value>
</property>
<property name="tenantService" ref="tenantService"/>
</bean>
<bean id="siteServiceScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.site.script.ScriptSiteService">

View File

@@ -18,6 +18,8 @@
<property name="nodeService" ref="NodeService"/>
<property name="searchService" ref="SearchService"/>
<property name="namespaceService" ref="NamespaceService"/>
<property name="tenantService" ref="tenantService"/>
<property name="tenantAdminService" ref="tenantAdminService"/>
</bean>
<bean id="workflowServiceImpl" class="org.alfresco.repo.workflow.WorkflowServiceImpl">

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -38,6 +38,7 @@ import org.alfresco.repo.activities.feed.control.FeedControlDaoService;
import org.alfresco.repo.activities.post.ActivityPostDAO;
import org.alfresco.repo.activities.post.ActivityPostDaoService;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.activities.FeedControl;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -69,6 +70,8 @@ public class ActivityServiceImpl implements ActivityService
private AuthorityService authorityService;
private FeedGenerator feedGenerator;
private TenantService tenantService;
private int maxFeedItems = 100;
private boolean userNamesAreCaseSensitive = false;
@@ -108,32 +111,37 @@ public class ActivityServiceImpl implements ActivityService
this.feedGenerator = feedGenerator;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public void postActivity(String activityType, String network, String appTool, String activityData)
public void postActivity(String activityType, String siteId, String appTool, String activityData)
{
postActivity(activityType, network, appTool, activityData, ActivityPostDAO.STATUS.PENDING);
postActivity(activityType, siteId, appTool, activityData, ActivityPostDAO.STATUS.PENDING);
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
*/
public void postActivity(String activityType, String network, String appTool, NodeRef nodeRef)
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
StringBuffer sb = new StringBuffer();
sb.append("{").append("\"nodeRef\":\"").append(nodeRef.toString()).append("\"").append("}");
postActivity(activityType, network, appTool, sb.toString(), ActivityPostDAO.STATUS.PENDING);
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostDAO.STATUS.PENDING);
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public void postActivity(String activityType, String network, String appTool, NodeRef nodeRef, String name)
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
@@ -142,13 +150,13 @@ public class ActivityServiceImpl implements ActivityService
.append("\"name\":\"").append(name).append("\"")
.append("}");
postActivity(activityType, network, appTool, sb.toString(), ActivityPostDAO.STATUS.PENDING);
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostDAO.STATUS.PENDING);
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.activities.ActivityService#postActivity(java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, org.alfresco.service.cmr.repository.NodeRef)
*/
public void postActivity(String activityType, String network, String appTool, NodeRef nodeRef, String name, QName typeQName, NodeRef parentNodeRef)
public void postActivity(String activityType, String siteId, String appTool, NodeRef nodeRef, String name, QName typeQName, NodeRef parentNodeRef)
{
// primarily for delete node activities - eg. delete document, delete folder
@@ -163,23 +171,23 @@ public class ActivityServiceImpl implements ActivityService
.append("\"parentNodeRef\":\"").append(parentNodeRef.toString()).append("\"")
.append("}");
postActivity(activityType, network, appTool, sb.toString(), ActivityPostDAO.STATUS.PENDING);
postActivity(activityType, siteId, appTool, sb.toString(), ActivityPostDAO.STATUS.PENDING);
}
private void postActivity(String activityType, String siteNetwork, String appTool, String activityData, ActivityPostDAO.STATUS status)
private void postActivity(String activityType, String siteId, String appTool, String activityData, ActivityPostDAO.STATUS status)
{
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
try
{
// optional - default to empty string
if (siteNetwork == null)
if (siteId == null)
{
siteNetwork = "";
siteId = "";
}
else if (siteNetwork.length() > MAX_LEN_SITE_ID)
else if (siteId.length() > MAX_LEN_SITE_ID)
{
throw new AlfrescoRuntimeException("Invalid site network - exceeds " + MAX_LEN_SITE_ID + " chars: " + siteNetwork);
throw new AlfrescoRuntimeException("Invalid siteId - exceeds " + MAX_LEN_SITE_ID + " chars: " + siteId);
}
// optional - default to empty string
@@ -235,7 +243,9 @@ public class ActivityServiceImpl implements ActivityService
Date postDate = new Date();
ActivityPostDAO activityPost = new ActivityPostDAO();
activityPost.setUserId(currentUser);
activityPost.setSiteNetwork(siteNetwork);
activityPost.setSiteNetwork(tenantService.getName(siteId));
activityPost.setAppTool(appTool);
activityPost.setActivityData(activityData);
activityPost.setActivityType(activityType);
@@ -297,6 +307,8 @@ public class ActivityServiceImpl implements ActivityService
List<ActivityFeedDAO> activityFeeds = null;
if (siteId != null)
{
siteId = tenantService.getName(siteId);
activityFeeds = feedDaoService.selectUserFeedEntries(feedUserId, format, siteId);
}
else
@@ -312,6 +324,8 @@ public class ActivityServiceImpl implements ActivityService
{
break;
}
activityFeed.setSiteNetwork(tenantService.getBaseName(activityFeed.getSiteNetwork()));
activityFeedEntries.add(activityFeed.getJSONString());
}
}
@@ -343,6 +357,8 @@ public class ActivityServiceImpl implements ActivityService
try
{
siteId = tenantService.getName(siteId);
List<ActivityFeedDAO> activityFeeds = feedDaoService.selectSiteFeedEntries(siteId, format);
int count = 0;
@@ -353,6 +369,8 @@ public class ActivityServiceImpl implements ActivityService
{
break;
}
activityFeed.setSiteNetwork(tenantService.getBaseName(activityFeed.getSiteNetwork()));
activityFeedEntries.add(activityFeed.getJSONString());
}
}
@@ -504,4 +522,16 @@ public class ActivityServiceImpl implements ActivityService
throw are;
}
}
private FeedControl getTenantFeedControl(FeedControl feedControl)
{
// TODO
return null;
}
private FeedControl getBaseFeedControl(FeedControl feedControl)
{
// TODO
return null;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -33,6 +33,7 @@ import org.alfresco.repo.activities.post.ActivityPostDAO;
import org.alfresco.repo.activities.post.ActivityPostDaoService;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -65,6 +66,7 @@ public class PostLookup
private PermissionService permissionService;
private TransactionService transactionService;
private PersonService personService;
private TenantService tenantService;
public void setPostDaoService(ActivityPostDaoService postDaoService)
{
@@ -91,6 +93,11 @@ public class PostLookup
this.personService = personService;
}
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
/**
* Perform basic checks to ensure that the necessary dependencies were injected.
*/
@@ -101,6 +108,7 @@ public class PostLookup
PropertyCheck.mandatory(this, "permissionService", permissionService);
PropertyCheck.mandatory(this, "transactionService", transactionService);
PropertyCheck.mandatory(this, "personService", personService);
PropertyCheck.mandatory(this, "tenantService", tenantService);
}
public void execute() throws JobExecutionException
@@ -118,46 +126,57 @@ public class PostLookup
logger.info("Update: " + activityPosts.size() + " activity posts");
}
for (ActivityPostDAO activityPost : activityPosts)
for (final ActivityPostDAO activityPost : activityPosts)
{
try
{
postDaoService.startTransaction();
JSONObject jo = new JSONObject(new JSONTokener(activityPost.getActivityData()));
String postUserId = activityPost.getUserId();
final JSONObject jo = new JSONObject(new JSONTokener(activityPost.getActivityData()));
final String postUserId = activityPost.getUserId();
if (! jo.isNull("nodeRef"))
// MT share
String tenantDomain = tenantService.getUserDomain(postUserId);
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
String nodeRefStr = jo.getString("nodeRef");
NodeRef nodeRef = new NodeRef(nodeRefStr);
// lookup additional node data
JSONObject activityData = lookupNode(nodeRef, postUserId, jo);
activityPost.setActivityData(activityData.toString());
}
else
{
// lookup additional person data
Pair<String, String> firstLastName = lookupPerson(postUserId);
if (firstLastName != null)
public Object doWork() throws Exception
{
jo.put("firstName", firstLastName.getFirst());
jo.put("lastName", firstLastName.getSecond());
if (! jo.isNull("nodeRef"))
{
String nodeRefStr = jo.getString("nodeRef");
NodeRef nodeRef = new NodeRef(nodeRefStr);
activityPost.setActivityData(jo.toString());
// lookup additional node data
JSONObject activityData = lookupNode(nodeRef, postUserId, jo);
activityPost.setActivityData(activityData.toString());
}
else
{
// lookup additional person data
Pair<String, String> firstLastName = lookupPerson(postUserId);
if (firstLastName != null)
{
jo.put("firstName", firstLastName.getFirst());
jo.put("lastName", firstLastName.getSecond());
activityPost.setActivityData(jo.toString());
}
}
activityPost.setLastModified(new Date());
postDaoService.updatePost(activityPost.getId(), activityPost.getSiteNetwork(), activityPost.getActivityData(), ActivityPostDAO.STATUS.POSTED);
if (logger.isDebugEnabled())
{
activityPost.setStatus(ActivityPostDAO.STATUS.POSTED.toString()); // for debug output
logger.debug("Updated: " + activityPost);
}
return null;
}
}
activityPost.setLastModified(new Date());
postDaoService.updatePost(activityPost.getId(), activityPost.getSiteNetwork(), activityPost.getActivityData(), ActivityPostDAO.STATUS.POSTED);
if (logger.isDebugEnabled())
{
activityPost.setStatus(ActivityPostDAO.STATUS.POSTED.toString()); // for debug output
logger.debug("Updated: " + activityPost);
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
postDaoService.commitTransaction();
}
@@ -201,38 +220,32 @@ public class PostLookup
private Pair<String, String> lookupPerson(final String postUserId) throws JSONException
{
return AuthenticationUtil.runAs(new RunAsWork<Pair<String, String>>()
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
// wrap to make the request in a transaction
RetryingTransactionCallback<Pair<String, String>> lookup = new RetryingTransactionCallback<Pair<String, String>>()
{
public Pair<String, String> doWork() throws Exception
public Pair<String, String> execute() throws Throwable
{
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
String firstName = "";
String lastName = "";
// wrap to make the request in a transaction
RetryingTransactionCallback<Pair<String, String>> lookup = new RetryingTransactionCallback<Pair<String, String>>()
if (personService.personExists(postUserId))
{
public Pair<String, String> execute() throws Throwable
{
String firstName = "";
String lastName = "";
NodeRef personRef = personService.getPerson(postUserId);
if (personService.personExists(postUserId))
{
NodeRef personRef = personService.getPerson(postUserId);
firstName = (String)nodeService.getProperty(personRef, ContentModel.PROP_FIRSTNAME);
lastName = (String)nodeService.getProperty(personRef, ContentModel.PROP_LASTNAME);
firstName = (String)nodeService.getProperty(personRef, ContentModel.PROP_FIRSTNAME);
lastName = (String)nodeService.getProperty(personRef, ContentModel.PROP_LASTNAME);
return new Pair<String, String>(firstName, lastName);
}
return new Pair<String, String>(firstName, lastName);
}
return null;
}
};
// execute in txn
return txnHelper.doInTransaction(lookup, true);
return null;
}
}, AuthenticationUtil.getSystemUserName());
};
// execute in txn
return txnHelper.doInTransaction(lookup, true);
}
private JSONObject lookupNode(final NodeRef nodeRef, final String postUserId, final JSONObject jo) throws JSONException

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* 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
@@ -24,6 +24,7 @@
*/
package org.alfresco.repo.security.authentication;
import org.alfresco.repo.tenant.TenantService;
import org.apache.commons.lang.RandomStringUtils;
/**
@@ -36,6 +37,13 @@ public class BasicUserNameGenerator implements UserNameGenerator
// user name length property
private int userNameLength;
private TenantService tenantService;
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
/**
* Set the user name length
*
@@ -53,6 +61,11 @@ public class BasicUserNameGenerator implements UserNameGenerator
*/
public String generateUserName()
{
return RandomStringUtils.randomNumeric(userNameLength);
String userName = RandomStringUtils.randomNumeric(userNameLength);
if (tenantService.isEnabled())
{
userName = tenantService.getDomainUser(userName, tenantService.getCurrentUserDomain());
}
return userName;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* 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
@@ -27,9 +27,11 @@ package org.alfresco.repo.security.person;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -67,6 +69,11 @@ public abstract class AbstractHomeFolderProvider implements HomeFolderProvider,
*/
private ServiceRegistry serviceRegistry;
/**
* Tenant service - required for MT-enabled environment, else optional
*/
private TenantService tenantService;
/**
* The path to a folder
*/
@@ -75,7 +82,7 @@ public abstract class AbstractHomeFolderProvider implements HomeFolderProvider,
/**
* Cache the result of the path look up.
*/
private NodeRef pathNodeRef;
private Map<String, NodeRef> pathNodeRefs; // MT-aware
/**
* The owner to set on creation of a home folder (if unset this will be the uid).
@@ -110,6 +117,8 @@ public abstract class AbstractHomeFolderProvider implements HomeFolderProvider,
public AbstractHomeFolderProvider()
{
super();
pathNodeRefs = new ConcurrentHashMap<String, NodeRef>();
}
/**
@@ -228,6 +237,16 @@ public abstract class AbstractHomeFolderProvider implements HomeFolderProvider,
this.serviceRegistry = serviceRegistry;
}
/**
* Set the tenant service
*
* @param tenantService
*/
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
/**
* Inherit permissions when home folder are created?
*
@@ -289,15 +308,19 @@ public abstract class AbstractHomeFolderProvider implements HomeFolderProvider,
}
/**
* Cache path to node resolution/
* Cache path to node resolution
*
* @return
*/
protected synchronized NodeRef getPathNodeRef()
protected NodeRef getPathNodeRef()
{
String tenantDomain = (tenantService != null ? tenantService.getCurrentUserDomain() : TenantService.DEFAULT_DOMAIN);
NodeRef pathNodeRef = pathNodeRefs.get(tenantDomain);
if (pathNodeRef == null)
{
pathNodeRef = resolvePath(path);
pathNodeRefs.put(tenantDomain, pathNodeRef);
}
return pathNodeRef;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* 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
@@ -41,6 +41,7 @@ import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.PermissionServiceSPI;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
@@ -233,7 +234,28 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
* @return NodeRef of the person as specified by the username
* @throws NoSuchPersonException
*/
public NodeRef getPerson(String userName)
public NodeRef getPerson(final String userName)
{
// MT share - for activity service system callback
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<NodeRef>()
{
public NodeRef doWork() throws Exception
{
return getPersonImpl(userName);
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
}
else
{
return getPersonImpl(userName);
}
}
private NodeRef getPersonImpl(String userName)
{
NodeRef personNode = getPersonOrNull(userName);
if (personNode == null)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* 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
@@ -35,6 +35,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.ActivityType;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileFolderService;
@@ -107,6 +108,7 @@ public class SiteServiceImpl implements SiteService, SiteModel
private TaggingService taggingService;
private AuthorityService authorityService;
private DictionaryService dictionaryService;
private TenantService tenantService;
/**
* Set the path to the location of the sites root folder. For example:
@@ -211,6 +213,16 @@ public class SiteServiceImpl implements SiteService, SiteModel
this.dictionaryService = dictionaryService;
}
/**
* Set the tenant service
*
* @param tenantService tenant service
*/
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
/**
* Checks that all necessary properties and services have been provided.
*/
@@ -587,7 +599,30 @@ public class SiteServiceImpl implements SiteService, SiteModel
/**
* @see org.alfresco.service.cmr.site.SiteService#getSite(java.lang.String)
*/
public SiteInfo getSite(String shortName)
public SiteInfo getSite(final String shortName)
{
// MT share - for activity service system callback
if (tenantService.isEnabled() && (AuthenticationUtil.SYSTEM_USER_NAME.equals(AuthenticationUtil.getRunAsUser())) && tenantService.isTenantName(shortName))
{
final String tenantDomain = tenantService.getDomain(shortName);
final String sName = tenantService.getBaseName(shortName, true);
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<SiteInfo>()
{
public SiteInfo doWork() throws Exception
{
SiteInfo site = getSiteImpl(sName);
return new SiteInfoImpl(site.getSitePreset(), shortName, site.getTitle(), site.getDescription(), site.getVisibility(), site.getCustomProperties(), site.getNodeRef());
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
}
else
{
return getSiteImpl(shortName);
}
}
private SiteInfo getSiteImpl(String shortName)
{
SiteInfo result = null;
@@ -714,7 +749,29 @@ public class SiteServiceImpl implements SiteService, SiteModel
/**
* @see org.alfresco.service.cmr.site.SiteService#listMembers(String, String, String, boolean)
*/
public Map<String, String> listMembers(String shortName, String nameFilter, String roleFilter, boolean collapseGroups)
public Map<String, String> listMembers(String shortName, final String nameFilter, final String roleFilter, final boolean collapseGroups)
{
// MT share - for activity service system callback
if (tenantService.isEnabled() && (AuthenticationUtil.SYSTEM_USER_NAME.equals(AuthenticationUtil.getRunAsUser())) && tenantService.isTenantName(shortName))
{
final String tenantDomain = tenantService.getDomain(shortName);
final String sName = tenantService.getBaseName(shortName, true);
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Map<String, String>>()
{
public Map<String, String> doWork() throws Exception
{
return listMembersImpl(sName, nameFilter, roleFilter, collapseGroups);
}
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
}
else
{
return listMembersImpl(shortName, nameFilter, roleFilter, collapseGroups);
}
}
private Map<String, String> listMembersImpl(String shortName, String nameFilter, String roleFilter, boolean collapseGroups)
{
NodeRef siteNodeRef = getSiteNodeRef(shortName);
if (siteNodeRef == null)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -50,6 +50,7 @@ import org.alfresco.repo.node.db.DbNodeServiceImpl;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteAVMBootstrap;
import org.alfresco.repo.workflow.WorkflowDeployer;
import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.attributes.AttributeService;
@@ -93,8 +94,10 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
private TenantRoutingFileContentStore tenantFileContentStore;
private WorkflowService workflowService;
private RepositoryExporterService repositoryExporterService;
private WorkflowDeployer workflowDeployer;
private ModuleService moduleService;
private SiteAVMBootstrap siteAVMBootstrap;
private List<WorkflowDeployer> workflowDeployers = new ArrayList<WorkflowDeployer>();
/*
* Tenant domain/ids are unique strings that are case-insensitive. Tenant ids must be valid filenames.
@@ -182,9 +185,13 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
this.repositoryExporterService = repositoryExporterService;
}
/**
* @deprecated see setWorkflowDeployers
*/
public void setWorkflowDeployer(WorkflowDeployer workflowDeployer)
{
this.workflowDeployer = workflowDeployer;
// NOOP
logger.warn(WARN_MSG);
}
public void setModuleService(ModuleService moduleService)
@@ -192,6 +199,11 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
this.moduleService = moduleService;
}
public void setSiteAVMBootstrap(SiteAVMBootstrap siteAVMBootstrap)
{
this.siteAVMBootstrap = siteAVMBootstrap;
}
public static final String PROTOCOL_STORE_USER = "user";
public static final String PROTOCOL_STORE_WORKSPACE = "workspace";
public static final String PROTOCOL_STORE_SYSTEM = "system";
@@ -211,6 +223,7 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
private List<TenantDeployer> tenantDeployers = new ArrayList<TenantDeployer>();
private static final String WARN_MSG = "Please update your alfresco/extension/mt/mt-admin-context.xml to use baseMultiTAdminService (see latest alfresco/extension/mt/mt-admin-context.xml.sample)";
protected void checkProperties()
{
@@ -224,9 +237,22 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
PropertyCheck.mandatory(this, "TenantFileContentStore", tenantFileContentStore);
PropertyCheck.mandatory(this, "WorkflowService", workflowService);
PropertyCheck.mandatory(this, "RepositoryExporterService", repositoryExporterService);
PropertyCheck.mandatory(this, "WorkflowDeployer", workflowDeployer);
PropertyCheck.mandatory(this, "ModuleService - see updated alfresco/extension/mt/mt-admin-context.xml.sample", moduleService);
// for backwards compatibility only
if (moduleService == null)
{
// default for now
logger.warn(WARN_MSG);
moduleService = (ModuleService)ctx.getBean("moduleService");
}
if (siteAVMBootstrap == null)
{
// default for now
logger.warn(WARN_MSG);
siteAVMBootstrap = (SiteAVMBootstrap)ctx.getBean("siteAVMBootstrap");
}
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
@@ -350,6 +376,8 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
ImporterBootstrap spacesImporterBootstrap = (ImporterBootstrap)ctx.getBean("spacesBootstrap");
bootstrapSpacesTenantStore(spacesImporterBootstrap, tenantDomain);
siteAVMBootstrap.bootstrap();
// notify listeners that tenant has been created & hence enabled
for (TenantDeployer tenantDeployer : tenantDeployers)
{
@@ -357,7 +385,10 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
}
// bootstrap workflows
workflowDeployer.init();
for (WorkflowDeployer workflowDeployer : workflowDeployers)
{
workflowDeployer.init();
}
// bootstrap modules (if any)
moduleService.startModules();
@@ -415,7 +446,10 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
}
// bootstrap workflows
workflowDeployer.init();
for (WorkflowDeployer workflowDeployer : workflowDeployers)
{
workflowDeployer.init();
}
// bootstrap modules (if any)
moduleService.startModules();
@@ -1050,7 +1084,7 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
{
if (deployer == null)
{
throw new AlfrescoRuntimeException("Deployer must be provided");
throw new AlfrescoRuntimeException("TenantDeployer must be provided");
}
if (! tenantDeployers.contains(deployer))
@@ -1063,7 +1097,7 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
{
if (deployer == null)
{
throw new AlfrescoRuntimeException("Deployer must be provided");
throw new AlfrescoRuntimeException("TenantDeployer must be provided");
}
if (tenantDeployers != null)
@@ -1072,6 +1106,19 @@ public class MultiTAdminServiceImpl implements TenantAdminService, ApplicationCo
}
}
public void register(WorkflowDeployer workflowDeployer)
{
if (workflowDeployer == null)
{
throw new AlfrescoRuntimeException("WorkflowDeployer must be provided");
}
if (! workflowDeployers.contains(workflowDeployer))
{
workflowDeployers.add(workflowDeployer);
}
}
public void resetCache(String tenantDomain)
{
if (existsTenant(tenantDomain))

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -226,7 +226,7 @@ public class MultiTNodeServiceInterceptor extends DelegatingIntroductionIntercep
StoreRef storeRef = ref;
try
{
if (tenantService.isEnabled())
if (tenantService.isEnabled() && (! storeRef.getProtocol().equals(StoreRef.PROTOCOL_AVM)))
{
// MT: return tenant stores only (although for super System return all stores - as used by
// ConfigurationChecker, IndexRecovery, IndexBackup etc)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -174,6 +174,25 @@ public class MultiTServiceImpl implements TenantService
return name;
}
/* (non-Javadoc)
* @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.namespace.QName)
*/
public QName getName(QName name)
{
// Check that all the passed values are not null
ParameterCheck.mandatory("Name", name);
String tenantDomain = getCurrentUserDomain();
if (! tenantDomain.equals(DEFAULT_DOMAIN))
{
checkTenantEnabled(tenantDomain);
name = getName(name, tenantDomain);
}
return name;
}
/* (non-Javadoc)
* @see org.alfresco.repo.tenant.TenantService#getName(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -28,6 +28,7 @@ import java.io.File;
import java.util.Collections;
import java.util.List;
import org.alfresco.repo.workflow.WorkflowDeployer;
import org.apache.commons.logging.Log;
/**
@@ -93,6 +94,13 @@ public class SingleTAdminServiceImpl implements TenantAdminService
{
}
/**
* NO-OP
*/
public void register(WorkflowDeployer workflowDeployer)
{
}
/**
* @return Returns an empty list always
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* 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
@@ -69,6 +69,11 @@ public class SingleTServiceImpl implements TenantService
return storeRef;
}
public QName getName(QName name)
{
return name;
}
public QName getName(NodeRef inNodeRef, QName name)
{
return name;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -27,6 +27,7 @@ package org.alfresco.repo.tenant;
import java.io.File;
import java.util.List;
import org.alfresco.repo.workflow.WorkflowDeployer;
import org.apache.commons.logging.Log;
@@ -44,7 +45,7 @@ public interface TenantAdminService extends TenantUserService
public void stopTenants();
/*
* Deployer methods
* Tenant Deployer methods
*/
public void deployTenants(final TenantDeployer deployer, Log logger);
@@ -58,7 +59,13 @@ public interface TenantAdminService extends TenantUserService
public List<Tenant> getAllTenants();
/*
* Deployer methods
* Workflow Deployer methods
*/
public void register(WorkflowDeployer workflowDeployer);
/*
* Admin methods
*/
public void createTenant(String tenantDomain, char[] adminRawPassword);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
* 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
@@ -78,6 +78,11 @@ public interface TenantService extends TenantUserService
*/
public StoreRef getName(String username, StoreRef storeRef);
/**
* @return the reference <b>with</b> the tenant-specific ID attached
*/
public QName getName(QName name);
/**
* @return the reference <b>with</b> the tenant-specific ID attached
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* 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
@@ -40,6 +40,7 @@ import org.alfresco.repo.dictionary.RepositoryLocation;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -85,6 +86,7 @@ public class WorkflowDeployer extends AbstractLifecycleBean
private List<Properties> workflowDefinitions;
private List<String> models = new ArrayList<String>();
private List<String> resourceBundles = new ArrayList<String>();
private TenantAdminService tenantAdminService;
private TenantService tenantService;
private NodeService nodeService;
@@ -145,6 +147,16 @@ public class WorkflowDeployer extends AbstractLifecycleBean
this.dictionaryDAO = dictionaryDAO;
}
/**
* Sets the tenant admin service
*
* @param tenantService the tenant admin service
*/
public void setTenantAdminService(TenantAdminService tenantAdminService)
{
this.tenantAdminService = tenantAdminService;
}
/**
* Sets the tenant service
*
@@ -432,6 +444,8 @@ public class WorkflowDeployer extends AbstractLifecycleBean
return null;
}
}, AuthenticationUtil.getSystemUserName());
tenantAdminService.register(this);
}
@Override

View File

@@ -1261,6 +1261,12 @@ public class JBPMEngine extends BPMEngine
public List<WorkflowTask> doInJbpm(JbpmContext context)
{
Session session = context.getSession();
if ((query.getProcessName() != null) && (tenantService.isEnabled()))
{
query.setProcessName(tenantService.getName(query.getProcessName()));
}
Criteria criteria = createTaskQueryCriteria(session, query);
List<TaskInstance> tasks = criteria.list();
@@ -1505,7 +1511,19 @@ public class JBPMEngine extends BPMEngine
{
process = (process == null) ? root.createCriteria("processInstance") : process;
Criteria processDef = process.createCriteria("processDefinition");
processDef.add(Restrictions.eq("name", query.getProcessName().toPrefixString(namespaceService)));
String processName = null;
if (tenantService.isEnabled())
{
QName baseProcessName = tenantService.getBaseName(query.getProcessName(), true);
processName = tenantService.getName(baseProcessName.toPrefixString(namespaceService));
}
else
{
processName = query.getProcessName().toPrefixString(namespaceService);
}
processDef.add(Restrictions.eq("name", processName));
}
return process;

View File

@@ -7,26 +7,7 @@
<!-- MT Admin Service Implementation -->
<!-- -->
<bean id="tenantAdminService" class="org.alfresco.repo.tenant.MultiTAdminServiceImpl">
<!--
<property name="nodeService" ref="NodeService"/>
-->
<property name="nodeService" ref="dbNodeServiceImpl"/> <!-- TODO - go direct, until we expose deleteStore via public NodeService API -->
<property name="dictionaryComponent" ref="dictionaryService"/>
<property name="authenticationComponent" ref="authenticationComponent"/>
<property name="repoAdminService" ref="RepoAdminService"/>
<property name="tenantService" ref="tenantService"/>
<property name="transactionService" ref="transactionComponent"/>
<property name="attributeService" ref="AttributeService"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
<property name="tenantFileContentStore" ref="tenantFileContentStore"/>
<property name="workflowService" ref="WorkflowService"/>
<property name="repositoryExporterService" ref="repositoryExporterComponent"/>
<property name="workflowDeployer" ref="workflowBootstrap"/>
<property name="moduleService" ref="moduleService"/>
</bean>
<bean id="tenantAdminService" parent="baseMultiTAdminService" />
<bean id="tenantInterpreter" class="org.alfresco.repo.tenant.TenantInterpreter">
<property name="transactionService" ref="transactionComponent"/>