mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Various changes to Invite Service
- added functionality to forbid a user from cancelling a pending invite, if he/she is not a Site Manager for the site associated with that invite - added CancelInviteAction workflow action class, with functionality to clean up disabled invitee account and invitee person node when (upon cancellation) there are no outstanding invites for that invitee. - added various unit tests to InviteServiceTest for above functionality - added automatic redeployment of invite process definition in setup(...) method of InviteServiceTest class - other minor refinements to InviteServiceTest - some minor refactoring to Invite Service to prevent code duplication amongst various invite web scripts and workflow action classes git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10894 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
<webscript>
|
<webscript>
|
||||||
<shortname>Invite</shortname>
|
<shortname>Invite</shortname>
|
||||||
<description>Processes Inviter actions ('start' or 'cancel' invite)</description>
|
<description>Processes Inviter actions ('start' or 'cancel' invite)</description>
|
||||||
<url>/api/invite/start?inviteeFirstName={inviteeFirstName}&inviteeLastName={inviteeLastName}&inviteeEmail={inviteeEmailAddress}&siteShortName={siteShortName}&inviteeSiteRole={inviteeSiteRole}</url>
|
<url>/api/invite/start?inviteeFirstName={inviteeFirstName}&inviteeLastName={inviteeLastName}&inviteeEmail={inviteeEmailAddress}&siteShortName={siteShortName}&inviteeSiteRole={inviteeSiteRole}&serverPath={serverPath}&acceptUrl={acceptUrl}&rejectUrl={rejectUrl}</url>
|
||||||
<url>/api/invite/cancel?inviteId={inviteId}</url>
|
<url>/api/invite/cancel?inviteId={inviteId}</url>
|
||||||
<format default="json"/>
|
<format default="json"/>
|
||||||
<authentication>user</authentication>
|
<authentication>user</authentication>
|
||||||
<transaction>required</transaction>
|
<transaction>required</transaction>
|
||||||
</webscript>
|
</webscript>
|
||||||
|
@@ -332,14 +332,14 @@
|
|||||||
class="org.alfresco.repo.web.scripts.invite.Invite"
|
class="org.alfresco.repo.web.scripts.invite.Invite"
|
||||||
parent="webscript">
|
parent="webscript">
|
||||||
<property name="workflowService" ref="WorkflowService"/>
|
<property name="workflowService" ref="WorkflowService"/>
|
||||||
<property name="personService" ref="personService"/>
|
<property name="personService" ref="PersonService"/>
|
||||||
<property name="authenticationService" ref="authenticationService"/>
|
<property name="authenticationService" ref="AuthenticationService"/>
|
||||||
<property name="mutableAuthenticationDao" ref="authenticationDao"/>
|
<property name="mutableAuthenticationDao" ref="authenticationDao"/>
|
||||||
<property name="siteService" ref="SiteService"/>
|
<property name="siteService" ref="SiteService"/>
|
||||||
<property name="nodeService" ref="NodeService"/>
|
<property name="nodeService" ref="NodeService"/>
|
||||||
|
<property name="namespaceService" ref="NamespaceService"/>
|
||||||
<property name="userNameGenerator" ref="userNameGenerator"/>
|
<property name="userNameGenerator" ref="userNameGenerator"/>
|
||||||
<property name="passwordGenerator" ref="passwordGenerator"/>
|
<property name="passwordGenerator" ref="passwordGenerator"/>
|
||||||
<property name="namespaceService" ref="NamespaceService"/>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
@@ -62,6 +62,9 @@
|
|||||||
<transition name="reject" to="inviteRejected">
|
<transition name="reject" to="inviteRejected">
|
||||||
<action class="org.alfresco.repo.web.scripts.invite.RejectInviteAction"/>
|
<action class="org.alfresco.repo.web.scripts.invite.RejectInviteAction"/>
|
||||||
</transition>
|
</transition>
|
||||||
|
<transition name="cancel" to="end">
|
||||||
|
<action class="org.alfresco.repo.web.scripts.invite.CancelInviteAction"/>
|
||||||
|
</transition>
|
||||||
</task-node>
|
</task-node>
|
||||||
|
|
||||||
<task-node name="inviteAccepted">
|
<task-node name="inviteAccepted">
|
||||||
|
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have 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.web.scripts.invite;
|
||||||
|
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
||||||
|
import org.alfresco.repo.site.SiteModel;
|
||||||
|
import org.alfresco.repo.site.SiteService;
|
||||||
|
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
|
||||||
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
|
import org.alfresco.web.scripts.Status;
|
||||||
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
|
import org.jbpm.graph.exe.ExecutionContext;
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class contains logic that gets executed when
|
||||||
|
* the wf:invitePendingTask in the invite workflow gets cancelled
|
||||||
|
* along the "cancel" transition
|
||||||
|
*
|
||||||
|
* @author glen johnson at alfresco com
|
||||||
|
*/
|
||||||
|
public class CancelInviteAction extends JBPMSpringActionHandler
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 776961141883350908L;
|
||||||
|
|
||||||
|
private MutableAuthenticationDao mutableAuthenticationDao;
|
||||||
|
private PersonService personService;
|
||||||
|
private WorkflowService workflowService;
|
||||||
|
private SiteService siteService;
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initialiseHandler(BeanFactory factory)
|
||||||
|
{
|
||||||
|
ServiceRegistry services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||||
|
mutableAuthenticationDao = (MutableAuthenticationDao) factory.getBean("authenticationDao");
|
||||||
|
personService = (PersonService) services.getPersonService();
|
||||||
|
workflowService = (WorkflowService) services.getWorkflowService();
|
||||||
|
siteService = (SiteService) services.getSiteService();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void execute(final ExecutionContext executionContext) throws Exception
|
||||||
|
{
|
||||||
|
// get the invitee user name and site short name variables off the execution context
|
||||||
|
final String inviteeUserName = (String) executionContext.getVariable(
|
||||||
|
InviteWorkflowModel.wfVarInviteeUserName);
|
||||||
|
final String siteShortName = (String) executionContext.getVariable(
|
||||||
|
InviteWorkflowModel.wfVarSiteShortName);
|
||||||
|
final String inviteId = (String) executionContext.getVariable(
|
||||||
|
InviteWorkflowModel.wfVarWorkflowInstanceId);
|
||||||
|
|
||||||
|
// throw http status 'forbidden' Web Script Exception if current user is not a Site Manager of the site
|
||||||
|
// associated with the invite (identified by inviteID)
|
||||||
|
String currentUserName = AuthenticationUtil.getCurrentUserName();
|
||||||
|
String currentUserSiteRole = this.siteService.getMembersRole(siteShortName, currentUserName);
|
||||||
|
if ((currentUserSiteRole == null) || (currentUserSiteRole.equals(SiteModel.SITE_MANAGER) == false))
|
||||||
|
{
|
||||||
|
throw new WebScriptException(Status.STATUS_FORBIDDEN,
|
||||||
|
"Current user '" + currentUserName + "' cannot cancel invite having ID '" + inviteId
|
||||||
|
+ "' because he\\she is not a Site Manager of the site with short name:'" + siteShortName
|
||||||
|
+ "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up invitee's user account and person node if they are not in use i.e.
|
||||||
|
// account is still disabled and there are no pending invites outstanding for the
|
||||||
|
// invitee
|
||||||
|
InviteHelper.cleanUpStaleInviteeResources(inviteeUserName, mutableAuthenticationDao, personService,
|
||||||
|
workflowService);
|
||||||
|
}
|
||||||
|
}
|
@@ -31,6 +31,8 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
||||||
import org.alfresco.repo.security.authentication.PasswordGenerator;
|
import org.alfresco.repo.security.authentication.PasswordGenerator;
|
||||||
import org.alfresco.repo.security.authentication.UserNameGenerator;
|
import org.alfresco.repo.security.authentication.UserNameGenerator;
|
||||||
@@ -43,10 +45,10 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
|||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||||
|
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
@@ -400,13 +402,23 @@ public class Invite extends DeclarativeWebScript
|
|||||||
|
|
||||||
// create a person node for the invitee with generated invitee user name
|
// create a person node for the invitee with generated invitee user name
|
||||||
// and other provided person property values
|
// and other provided person property values
|
||||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
|
final Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
|
||||||
properties.put(ContentModel.PROP_USERNAME, inviteeUserName);
|
properties.put(ContentModel.PROP_USERNAME, inviteeUserName);
|
||||||
properties.put(ContentModel.PROP_FIRSTNAME, inviteeFirstName);
|
properties.put(ContentModel.PROP_FIRSTNAME, inviteeFirstName);
|
||||||
properties.put(ContentModel.PROP_LASTNAME, inviteeLastName);
|
properties.put(ContentModel.PROP_LASTNAME, inviteeLastName);
|
||||||
properties.put(ContentModel.PROP_EMAIL, inviteeEmail);
|
properties.put(ContentModel.PROP_EMAIL, inviteeEmail);
|
||||||
this.personService.createPerson(properties);
|
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
personService.createPerson(properties);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
return inviteeUserName;
|
return inviteeUserName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,8 +688,9 @@ public class Invite extends DeclarativeWebScript
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels pending invite. Note that only the Inviter should cancel the
|
* Cancels pending invite. Note that only a Site Manager of the
|
||||||
* pending invite.
|
* site associated with the pending invite should be able to cancel that
|
||||||
|
* invite
|
||||||
*
|
*
|
||||||
* @param model
|
* @param model
|
||||||
* model to add objects to, which will be passed to the template
|
* model to add objects to, which will be passed to the template
|
||||||
@@ -695,10 +708,31 @@ public class Invite extends DeclarativeWebScript
|
|||||||
"Given invite ID " + inviteId + " null or empty");
|
"Given invite ID " + inviteId + " null or empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancel the workflow with the given invite ID
|
try
|
||||||
// which is actually the workflow ID
|
{
|
||||||
this.workflowService.cancelWorkflow(inviteId);
|
// complete the wf:invitePendingTask along the 'cancel' transition because the invitation has been cancelled
|
||||||
|
InviteHelper.completeInviteTask(inviteId, InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING,
|
||||||
|
InviteWorkflowModel.WF_TRANSITION_CANCEL, this.workflowService);
|
||||||
|
}
|
||||||
|
catch (WorkflowException wfe)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// If the indirect cause of workflow exception is a WebScriptException object
|
||||||
|
// then throw this directly, otherwise it will not be picked up by unit tests
|
||||||
|
//
|
||||||
|
|
||||||
|
Throwable indirectCause = wfe.getCause().getCause();
|
||||||
|
if (indirectCause instanceof WebScriptException)
|
||||||
|
{
|
||||||
|
WebScriptException wse = (WebScriptException) indirectCause;
|
||||||
|
throw wse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw wfe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add model properties for template to render
|
// add model properties for template to render
|
||||||
model.put(MODEL_PROP_KEY_ACTION, ACTION_CANCEL);
|
model.put(MODEL_PROP_KEY_ACTION, ACTION_CANCEL);
|
||||||
model.put(MODEL_PROP_KEY_INVITE_ID, inviteId);
|
model.put(MODEL_PROP_KEY_INVITE_ID, inviteId);
|
||||||
|
@@ -29,6 +29,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.site.SiteInfo;
|
import org.alfresco.repo.site.SiteInfo;
|
||||||
import org.alfresco.repo.site.SiteService;
|
import org.alfresco.repo.site.SiteService;
|
||||||
import org.alfresco.repo.template.TemplateNode;
|
import org.alfresco.repo.template.TemplateNode;
|
||||||
@@ -95,7 +98,7 @@ public class InviteHelper
|
|||||||
|
|
||||||
// set process name to "wf:invite" so that only tasks associated with
|
// set process name to "wf:invite" so that only tasks associated with
|
||||||
// invite workflow instances are returned by query
|
// invite workflow instances are returned by query
|
||||||
wfTaskQuery.setProcessName(QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invite"));
|
wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
|
||||||
|
|
||||||
// set query to only pick up invite workflow instances
|
// set query to only pick up invite workflow instances
|
||||||
// associated with the given invitee user name
|
// associated with the given invitee user name
|
||||||
@@ -105,7 +108,7 @@ public class InviteHelper
|
|||||||
|
|
||||||
// set query to only pick up in-progress invite pending tasks
|
// set query to only pick up in-progress invite pending tasks
|
||||||
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
|
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
|
||||||
wfTaskQuery.setTaskName(InviteWorkflowModel.WF_TASK_INVITE_PENDING);
|
wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING);
|
||||||
|
|
||||||
// query for invite workflow task associate
|
// query for invite workflow task associate
|
||||||
List<WorkflowTask> inviteStartTasks = workflowService
|
List<WorkflowTask> inviteStartTasks = workflowService
|
||||||
@@ -178,4 +181,88 @@ public class InviteHelper
|
|||||||
|
|
||||||
return inviteInfo;
|
return inviteInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up invitee user account and person node when no longer in use.
|
||||||
|
* They are deemed to no longer be in use when the invitee user account
|
||||||
|
* is still disabled and there are no outstanding pending invites for that invitee.
|
||||||
|
*
|
||||||
|
* @param inviteeUserName
|
||||||
|
* @param authenticationDao
|
||||||
|
* @param personService
|
||||||
|
* @param workflowService
|
||||||
|
*/
|
||||||
|
public static void cleanUpStaleInviteeResources(final String inviteeUserName,
|
||||||
|
final MutableAuthenticationDao authenticationDao, final PersonService personService,
|
||||||
|
final WorkflowService workflowService)
|
||||||
|
{
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
// see if there are any pending invites (invite workflow instances with invitePending task in-progress)
|
||||||
|
// outstanding for given invitee user name
|
||||||
|
List<WorkflowTask> pendingTasks = InviteHelper.findInvitePendingTasks(inviteeUserName, workflowService);
|
||||||
|
boolean invitesPending = (pendingTasks != null) && (pendingTasks.size() > 0);
|
||||||
|
|
||||||
|
// if invitee's user account is still disabled and there are no pending invites outstanding
|
||||||
|
// for the invitee, then remove the account and delete the invitee's person node
|
||||||
|
if ((authenticationDao.userExists(inviteeUserName))
|
||||||
|
&& (authenticationDao.getEnabled(inviteeUserName) == false)
|
||||||
|
&& (invitesPending == false))
|
||||||
|
{
|
||||||
|
// delete the invitee's user account
|
||||||
|
authenticationDao.deleteUser(inviteeUserName);
|
||||||
|
|
||||||
|
// delete the invitee's person node if one exists
|
||||||
|
if (personService.personExists(inviteeUserName))
|
||||||
|
{
|
||||||
|
personService.deletePerson(inviteeUserName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete the specified Invite Workflow Task for the invite workflow
|
||||||
|
* instance associated with the given invite ID, and follow the given
|
||||||
|
* transition upon completing the task
|
||||||
|
*
|
||||||
|
* @param inviteId the invite ID of the invite workflow instance for which
|
||||||
|
* we want to complete the given task
|
||||||
|
* @param fullTaskName qualified name of invite workflow task to complete
|
||||||
|
* @param transitionId the task transition to take on completion of
|
||||||
|
* the task (or null, for the default transition)
|
||||||
|
*/
|
||||||
|
public static void completeInviteTask(String inviteId, QName fullTaskName, String transitionId,
|
||||||
|
final WorkflowService workflowService)
|
||||||
|
{
|
||||||
|
// create workflow task query
|
||||||
|
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
|
||||||
|
|
||||||
|
// set the given invite ID as the workflow process ID in the workflow query
|
||||||
|
wfTaskQuery.setProcessId(inviteId);
|
||||||
|
|
||||||
|
// find incomplete invite workflow tasks with given task name
|
||||||
|
wfTaskQuery.setActive(Boolean.TRUE);
|
||||||
|
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
|
||||||
|
wfTaskQuery.setTaskName(fullTaskName);
|
||||||
|
|
||||||
|
// set process name to "wf:invite" so that only
|
||||||
|
// invite workflow instances are considered by this query
|
||||||
|
wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
|
||||||
|
|
||||||
|
// query for invite workflow tasks with the constructed query
|
||||||
|
List<WorkflowTask> wf_invite_tasks = workflowService
|
||||||
|
.queryTasks(wfTaskQuery);
|
||||||
|
|
||||||
|
// end all tasks found with this name
|
||||||
|
for (WorkflowTask workflowTask : wf_invite_tasks)
|
||||||
|
{
|
||||||
|
workflowService.endTask(workflowTask.id, transitionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,14 +25,10 @@
|
|||||||
package org.alfresco.repo.web.scripts.invite;
|
package org.alfresco.repo.web.scripts.invite;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
|
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
import org.alfresco.web.scripts.DeclarativeWebScript;
|
import org.alfresco.web.scripts.DeclarativeWebScript;
|
||||||
import org.alfresco.web.scripts.Status;
|
import org.alfresco.web.scripts.Status;
|
||||||
import org.alfresco.web.scripts.WebScriptException;
|
import org.alfresco.web.scripts.WebScriptException;
|
||||||
@@ -140,7 +136,8 @@ public class InviteResponse extends DeclarativeWebScript
|
|||||||
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
|
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
|
||||||
|
|
||||||
// complete the wf:invitePendingTask along the 'accept' transition because the invitation has been accepted
|
// complete the wf:invitePendingTask along the 'accept' transition because the invitation has been accepted
|
||||||
completeInviteTask(inviteId, InviteWorkflowModel.WF_TASK_INVITE_PENDING, InviteWorkflowModel.WF_TRANSITION_ACCEPT);
|
InviteHelper.completeInviteTask(inviteId, InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING,
|
||||||
|
InviteWorkflowModel.WF_TRANSITION_ACCEPT, this.workflowService);
|
||||||
|
|
||||||
// add model properties for template to render
|
// add model properties for template to render
|
||||||
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_ACCEPT);
|
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_ACCEPT);
|
||||||
@@ -167,49 +164,11 @@ public class InviteResponse extends DeclarativeWebScript
|
|||||||
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
|
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
|
||||||
|
|
||||||
// complete the wf:invitePendingTask task along the 'reject' transition because the invitation has been rejected
|
// complete the wf:invitePendingTask task along the 'reject' transition because the invitation has been rejected
|
||||||
completeInviteTask(inviteId, InviteWorkflowModel.WF_TASK_INVITE_PENDING, InviteWorkflowModel.WF_TRANSITION_REJECT);
|
InviteHelper.completeInviteTask(inviteId, InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING,
|
||||||
|
InviteWorkflowModel.WF_TRANSITION_REJECT, this.workflowService);
|
||||||
|
|
||||||
// add model properties for template to render
|
// add model properties for template to render
|
||||||
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_REJECT);
|
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_REJECT);
|
||||||
model.put(MODEL_PROP_KEY_SITE_SHORT_NAME, siteShortName);
|
model.put(MODEL_PROP_KEY_SITE_SHORT_NAME, siteShortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Complete the specified Invite Workflow Task for the invite workflow
|
|
||||||
* instance associated with the given invite ID, and follow the given
|
|
||||||
* transition upon completing the task
|
|
||||||
*
|
|
||||||
* @param inviteId the invite ID of the invite workflow instance for which
|
|
||||||
* we want to complete the given task
|
|
||||||
* @param fullTaskName qualified name of invite workflow task to complete
|
|
||||||
* @param transitionId the task transition to take on completion of
|
|
||||||
* the task (or null, for the default transition)
|
|
||||||
*/
|
|
||||||
private void completeInviteTask(String inviteId, QName fullTaskName, String transitionId)
|
|
||||||
{
|
|
||||||
// create workflow task query
|
|
||||||
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
|
|
||||||
|
|
||||||
// set the given invite ID as the workflow process ID in the workflow query
|
|
||||||
wfTaskQuery.setProcessId(inviteId);
|
|
||||||
|
|
||||||
// find incomplete invite workflow tasks with given task name
|
|
||||||
wfTaskQuery.setActive(Boolean.TRUE);
|
|
||||||
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
|
|
||||||
wfTaskQuery.setTaskName(fullTaskName);
|
|
||||||
|
|
||||||
// set process name to "wf:invite" so that only
|
|
||||||
// invite workflow instances are considered by this query
|
|
||||||
wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
|
|
||||||
|
|
||||||
// query for invite workflow tasks with the constructed query
|
|
||||||
List<WorkflowTask> wf_invite_tasks = this.workflowService
|
|
||||||
.queryTasks(wfTaskQuery);
|
|
||||||
|
|
||||||
// end all tasks found with this name
|
|
||||||
for (WorkflowTask workflowTask : wf_invite_tasks)
|
|
||||||
{
|
|
||||||
this.workflowService.endTask(workflowTask.id, transitionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
||||||
@@ -36,6 +37,8 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|||||||
import org.alfresco.repo.site.SiteInfo;
|
import org.alfresco.repo.site.SiteInfo;
|
||||||
import org.alfresco.repo.site.SiteModel;
|
import org.alfresco.repo.site.SiteModel;
|
||||||
import org.alfresco.repo.site.SiteService;
|
import org.alfresco.repo.site.SiteService;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
@@ -47,6 +50,8 @@ import org.alfresco.service.cmr.security.PersonService;
|
|||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.PropertyMap;
|
import org.alfresco.util.PropertyMap;
|
||||||
import org.alfresco.util.URLEncoder;
|
import org.alfresco.util.URLEncoder;
|
||||||
import org.alfresco.web.scripts.Status;
|
import org.alfresco.web.scripts.Status;
|
||||||
@@ -55,6 +60,7 @@ import org.alfresco.web.scripts.TestWebScriptServer.PutRequest;
|
|||||||
import org.alfresco.web.scripts.TestWebScriptServer.Response;
|
import org.alfresco.web.scripts.TestWebScriptServer.Response;
|
||||||
import org.apache.commons.lang.RandomStringUtils;
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit Test to test Invite Web Script API
|
* Unit Test to test Invite Web Script API
|
||||||
@@ -72,6 +78,8 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private WorkflowService workflowService;
|
private WorkflowService workflowService;
|
||||||
private MutableAuthenticationDao mutableAuthenticationDao;
|
private MutableAuthenticationDao mutableAuthenticationDao;
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
private TransactionService transactionService;
|
||||||
|
|
||||||
// stores invitee email addresses, one entry for each "start invite" operation
|
// stores invitee email addresses, one entry for each "start invite" operation
|
||||||
// invoked, so that resources created for each invitee for each test
|
// invoked, so that resources created for each invitee for each test
|
||||||
@@ -116,7 +124,19 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
this.workflowService = (WorkflowService) getServer().getApplicationContext().getBean("WorkflowService");
|
this.workflowService = (WorkflowService) getServer().getApplicationContext().getBean("WorkflowService");
|
||||||
this.mutableAuthenticationDao = (MutableAuthenticationDao) getServer().getApplicationContext()
|
this.mutableAuthenticationDao = (MutableAuthenticationDao) getServer().getApplicationContext()
|
||||||
.getBean("authenticationDao");
|
.getBean("authenticationDao");
|
||||||
|
this.namespaceService = (NamespaceService) getServer().getApplicationContext().getBean("NamespaceService");
|
||||||
|
this.transactionService = (TransactionService) getServer().getApplicationContext()
|
||||||
|
.getBean("TransactionService");
|
||||||
|
|
||||||
|
// redeploy invite process definition in case it has been modified
|
||||||
|
WorkflowDefinition inviteWfDefinition = this.workflowService.getDefinitionByName(
|
||||||
|
"jbpm$" + InviteWorkflowModel.WF_PROCESS_INVITE.toPrefixString(this.namespaceService));
|
||||||
|
this.workflowService.undeployDefinition(inviteWfDefinition.id);
|
||||||
|
ClassPathResource inviteWfResource = new ClassPathResource(
|
||||||
|
"alfresco/workflow/invite_processdefinition.xml");
|
||||||
|
workflowService.deployDefinition(
|
||||||
|
"jbpm", inviteWfResource.getInputStream(), MimetypeMap.MIMETYPE_XML);
|
||||||
|
|
||||||
// Create new invitee email address list
|
// Create new invitee email address list
|
||||||
this.inviteeEmailAddrs = new ArrayList<String>();
|
this.inviteeEmailAddrs = new ArrayList<String>();
|
||||||
|
|
||||||
@@ -354,6 +374,26 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
return startInvite(inviteeFirstName, inviteeLastName, inviteeEmail, inviteeSiteRole, siteShortName,
|
return startInvite(inviteeFirstName, inviteeLastName, inviteeEmail, inviteeSiteRole, siteShortName,
|
||||||
expectedStatus);
|
expectedStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JSONObject cancelInvite(String inviteId, int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
String cancelInviteUrl = URL_INVITE + "/"
|
||||||
|
+ INVITE_ACTION_CANCEL + "?inviteId=" + inviteId;
|
||||||
|
|
||||||
|
Response response = sendRequest(new GetRequest(cancelInviteUrl), expectedStatus);;
|
||||||
|
JSONObject result = new JSONObject(response.getContentAsString());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject rejectInvite(String inviteId, String inviteTicket, int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
// Invitee rejects invitation to a Site from Inviter
|
||||||
|
String rejectInviteUrl = URL_INVITE + "/" + inviteId + "/" + inviteTicket + "/reject";
|
||||||
|
Response response = sendRequest(new PutRequest(rejectInviteUrl, (byte[])null, null), expectedStatus);
|
||||||
|
JSONObject result = new JSONObject(response.getContentAsString());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private JSONObject getInvitesByInviteId(String inviteId, int expectedStatus)
|
private JSONObject getInvitesByInviteId(String inviteId, int expectedStatus)
|
||||||
throws Exception
|
throws Exception
|
||||||
@@ -465,7 +505,7 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
|
|
||||||
}, USER_INVITER);
|
}, USER_INVITER);
|
||||||
|
|
||||||
JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmailAddr, INVITEE_SITE_ROLE,
|
startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmailAddr, INVITEE_SITE_ROLE,
|
||||||
SITE_SHORT_NAME_INVITE_1, Status.STATUS_CONFLICT);
|
SITE_SHORT_NAME_INVITE_1, Status.STATUS_CONFLICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,9 +543,7 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
String inviteId = result.getString("inviteId");
|
String inviteId = result.getString("inviteId");
|
||||||
|
|
||||||
// Inviter cancels pending invitation
|
// Inviter cancels pending invitation
|
||||||
String cancelInviteUrl = URL_INVITE + "/"
|
cancelInvite(inviteId, Status.STATUS_OK);
|
||||||
+ INVITE_ACTION_CANCEL + "?inviteId=" + inviteId;
|
|
||||||
Response response = sendRequest(new GetRequest(cancelInviteUrl), Status.STATUS_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAcceptInvite() throws Exception
|
public void testAcceptInvite() throws Exception
|
||||||
@@ -520,7 +558,7 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
|
|
||||||
// Invitee accepts invitation to a Site from Inviter
|
// Invitee accepts invitation to a Site from Inviter
|
||||||
String acceptInviteUrl = URL_INVITE + "/" + inviteId + "/" + inviteTicket + "/accept";
|
String acceptInviteUrl = URL_INVITE + "/" + inviteId + "/" + inviteTicket + "/accept";
|
||||||
Response response = sendRequest(new PutRequest(acceptInviteUrl, (byte[])null, null), Status.STATUS_OK);
|
sendRequest(new PutRequest(acceptInviteUrl, (byte[])null, null), Status.STATUS_OK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// test that invitation represented by invite ID (of invitation started
|
// test that invitation represented by invite ID (of invitation started
|
||||||
@@ -548,9 +586,7 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
String inviteId = result.getString("inviteId");
|
String inviteId = result.getString("inviteId");
|
||||||
String inviteTicket = result.getString("inviteTicket");
|
String inviteTicket = result.getString("inviteTicket");
|
||||||
|
|
||||||
// Invitee rejects invitation to a Site from Inviter
|
rejectInvite(inviteId, inviteTicket, Status.STATUS_OK);
|
||||||
String rejectInviteUrl = URL_INVITE + "/" + inviteId + "/" + inviteTicket + "/reject";
|
|
||||||
Response response = sendRequest(new PutRequest(rejectInviteUrl, (byte[])null, null), Status.STATUS_OK);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// test that invite represented by invite ID (of invitation started
|
// test that invite represented by invite ID (of invitation started
|
||||||
@@ -593,7 +629,7 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
public void testGetInvitesByInviterUserName() throws Exception
|
public void testGetInvitesByInviterUserName() throws Exception
|
||||||
{
|
{
|
||||||
// inviter starts invite workflow
|
// inviter starts invite workflow
|
||||||
JSONObject startInviteResult = startInvite(INVITEE_FIRSTNAME,
|
startInvite(INVITEE_FIRSTNAME,
|
||||||
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK);
|
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK);
|
||||||
|
|
||||||
// get pending invites matching inviter user name used in invite started
|
// get pending invites matching inviter user name used in invite started
|
||||||
@@ -658,11 +694,104 @@ public class InviteServiceTest extends BaseWebScriptTest
|
|||||||
assertEquals(siteShortName, inviteJSONObj.getJSONObject("site").get("shortName"));
|
assertEquals(siteShortName, inviteJSONObj.getJSONObject("site").get("shortName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInviteForbiddenWhenInviterNotSiteManager() throws Exception
|
public void testStartInviteForbiddenWhenInviterNotSiteManager() throws Exception
|
||||||
{
|
{
|
||||||
// inviter2 starts invite workflow, but he/she is not the site manager of the given site
|
// inviter2 starts invite workflow, but he/she is not the site manager of the given site
|
||||||
AuthenticationUtil.setCurrentUser(USER_INVITER_2);
|
AuthenticationUtil.setCurrentUser(USER_INVITER_2);
|
||||||
startInvite(INVITEE_FIRSTNAME,
|
startInvite(INVITEE_FIRSTNAME,
|
||||||
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_3, Status.STATUS_FORBIDDEN);
|
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_3, Status.STATUS_FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCancelInviteForbiddenWhenInviterNotSiteManager() throws Exception
|
||||||
|
{
|
||||||
|
// inviter (who is Site Manager of the given site) starts invite workflow
|
||||||
|
JSONObject result = startInvite(INVITEE_FIRSTNAME,
|
||||||
|
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_3, Status.STATUS_OK);
|
||||||
|
|
||||||
|
// get hold of invite ID of started invite
|
||||||
|
String inviteId = result.getString("inviteId");
|
||||||
|
|
||||||
|
// when inviter 2 (who is not Site Manager of the given site) tries to cancel invite
|
||||||
|
// http status FORBIDDEN must be returned
|
||||||
|
AuthenticationUtil.setCurrentUser(USER_INVITER_2);
|
||||||
|
cancelInvite(inviteId, Status.STATUS_FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInviteeResourcesDeletedUponRejectWhenNoInvitePending() throws Exception
|
||||||
|
{
|
||||||
|
// inviter starts invite workflow
|
||||||
|
JSONObject result = startInvite(INVITEE_FIRSTNAME,
|
||||||
|
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK);
|
||||||
|
|
||||||
|
// get hold of properties of started invite
|
||||||
|
String inviteId = result.getString("inviteId");
|
||||||
|
String inviteTicket = result.getString("inviteTicket");
|
||||||
|
final String inviteeUserName = result.getString("inviteeUserName");
|
||||||
|
|
||||||
|
rejectInvite(inviteId, inviteTicket, Status.STATUS_OK);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
assertEquals(false, mutableAuthenticationDao.userExists(inviteeUserName));
|
||||||
|
assertEquals(false, personService.personExists(inviteeUserName));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInviteeResourcesNotDeletedUponRejectWhenInvitesPending() throws Exception
|
||||||
|
{
|
||||||
|
// inviter invites invitee to site 1
|
||||||
|
JSONObject result = startInvite(INVITEE_FIRSTNAME,
|
||||||
|
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK);
|
||||||
|
|
||||||
|
// get hold of properties of started invite
|
||||||
|
String invite1Id = result.getString("inviteId");
|
||||||
|
String invite1Ticket = result.getString("inviteTicket");
|
||||||
|
String inviteeEmail = result.getString("inviteeEmail");
|
||||||
|
final String inviteeUserName = result.getString("inviteeUserName");
|
||||||
|
|
||||||
|
// inviter invites invitee to site 2
|
||||||
|
startInvite(INVITEE_FIRSTNAME,
|
||||||
|
INVITEE_LASTNAME, inviteeEmail, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_2, Status.STATUS_OK);
|
||||||
|
|
||||||
|
rejectInvite(invite1Id, invite1Ticket, Status.STATUS_OK);
|
||||||
|
|
||||||
|
boolean inviteeUserExists = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
|
||||||
|
{
|
||||||
|
public Boolean doWork() throws Exception
|
||||||
|
{
|
||||||
|
RetryingTransactionHelper tranHelper = transactionService.getRetryingTransactionHelper();
|
||||||
|
Boolean result = tranHelper.doInTransaction(new RetryingTransactionCallback<Boolean>()
|
||||||
|
{
|
||||||
|
public Boolean execute() throws Throwable
|
||||||
|
{
|
||||||
|
Boolean result = mutableAuthenticationDao.userExists(inviteeUserName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
|
// test that the invitee's user account still exists (has not been deleted
|
||||||
|
assertEquals(true, inviteeUserExists);
|
||||||
|
|
||||||
|
boolean inviteePersonExists = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
|
||||||
|
{
|
||||||
|
public Boolean doWork() throws Exception
|
||||||
|
{
|
||||||
|
Boolean result = personService.personExists(inviteeUserName);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
|
assertEquals(true, inviteePersonExists);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,13 +16,12 @@ public interface InviteWorkflowModel {
|
|||||||
public static final QName WF_INVITE_TASK_INVITE_PENDING = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invitePendingTask");
|
public static final QName WF_INVITE_TASK_INVITE_PENDING = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invitePendingTask");
|
||||||
public static final QName WF_TASK_ACCEPT_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "acceptInviteTask");
|
public static final QName WF_TASK_ACCEPT_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "acceptInviteTask");
|
||||||
public static final QName WF_TASK_REJECT_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "rejectInviteTask");
|
public static final QName WF_TASK_REJECT_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "rejectInviteTask");
|
||||||
public static final QName WF_TASK_INVITE_PENDING = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invitePendingTask");
|
|
||||||
|
|
||||||
|
|
||||||
// transition names
|
// transition names
|
||||||
public static final String WF_TRANSITION_SEND_INVITE = "sendInvite";
|
public static final String WF_TRANSITION_SEND_INVITE = "sendInvite";
|
||||||
public static final String WF_TRANSITION_ACCEPT = "accept";
|
public static final String WF_TRANSITION_ACCEPT = "accept";
|
||||||
public static final String WF_TRANSITION_REJECT = "reject";
|
public static final String WF_TRANSITION_REJECT = "reject";
|
||||||
|
public static final String WF_TRANSITION_CANCEL = "cancel";
|
||||||
public static final String WF_TRANSITION_ACCEPT_INVITE_END = "end";
|
public static final String WF_TRANSITION_ACCEPT_INVITE_END = "end";
|
||||||
public static final String WF_TRANSITION_REJECT_INVITE_END = "end";
|
public static final String WF_TRANSITION_REJECT_INVITE_END = "end";
|
||||||
|
|
||||||
@@ -40,4 +39,8 @@ public interface InviteWorkflowModel {
|
|||||||
public static final QName WF_PROP_SENT_INVITE_DATE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "sentInviteDate");
|
public static final QName WF_PROP_SENT_INVITE_DATE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "sentInviteDate");
|
||||||
public static final QName WF_PROP_INVITEE_GEN_PASSWORD = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeGenPassword");
|
public static final QName WF_PROP_INVITEE_GEN_PASSWORD = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeGenPassword");
|
||||||
|
|
||||||
|
// workflow execution context variable names
|
||||||
|
public static final String wfVarInviteeUserName = "wf_inviteeUserName";
|
||||||
|
public static final String wfVarSiteShortName = "wf_siteShortName";
|
||||||
|
public static final String wfVarWorkflowInstanceId = "workflowinstanceid";
|
||||||
}
|
}
|
||||||
|
@@ -24,16 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.web.scripts.invite;
|
package org.alfresco.repo.web.scripts.invite;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|
||||||
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|
||||||
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
|
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
|
||||||
import org.jbpm.graph.exe.ExecutionContext;
|
import org.jbpm.graph.exe.ExecutionContext;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
|
|
||||||
@@ -71,35 +66,12 @@ public class RejectInviteAction extends JBPMSpringActionHandler
|
|||||||
public void execute(final ExecutionContext executionContext) throws Exception
|
public void execute(final ExecutionContext executionContext) throws Exception
|
||||||
{
|
{
|
||||||
// get the invitee user name
|
// get the invitee user name
|
||||||
final String inviteeUserName = (String) executionContext.getVariable("wf_inviteeUserName");
|
final String inviteeUserName = (String) executionContext.getVariable(InviteWorkflowModel.wfVarInviteeUserName);
|
||||||
|
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
||||||
{
|
|
||||||
public Object doWork() throws Exception
|
|
||||||
{
|
|
||||||
// see if there are any pending invites (invite workflow instances with invitePending task in-progress)
|
|
||||||
// outstanding for invitee who has responded here with an invite rejection
|
|
||||||
List<WorkflowTask> pendingTasks = InviteHelper.findInvitePendingTasks(inviteeUserName, workflowService);
|
|
||||||
boolean invitesPending = (pendingTasks != null) && (pendingTasks.size() > 0);
|
|
||||||
|
|
||||||
// if invitee's user account is still disabled and there are no pending invites outstanding
|
|
||||||
// for the invitee, then remove the account and delete the invitee's person node
|
|
||||||
if ((RejectInviteAction.this.mutableAuthenticationDao.userExists(inviteeUserName))
|
|
||||||
&& (RejectInviteAction.this.mutableAuthenticationDao.getEnabled(inviteeUserName) == false)
|
|
||||||
&& (invitesPending == false))
|
|
||||||
{
|
|
||||||
// delete the invitee's user account
|
|
||||||
mutableAuthenticationDao.deleteUser(inviteeUserName);
|
|
||||||
|
|
||||||
// delete the invitee's person node if one exists
|
|
||||||
if (personService.personExists(inviteeUserName))
|
|
||||||
{
|
|
||||||
personService.deletePerson(inviteeUserName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
// clean up invitee's user account and person node if they are not in use i.e.
|
||||||
}
|
// account is still disabled and there are no pending invites outstanding for the
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
// invitee
|
||||||
|
InviteHelper.cleanUpStaleInviteeResources(inviteeUserName, mutableAuthenticationDao, personService,
|
||||||
|
workflowService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user