Invite REST API Service with (1) additional Unit Tests (2) latest round of fixes so all unit tests for "invite", "inviteresponse" and "invites" (pending invites) Java-backed Web Scripts pass (3) moving superseded invite.get.js and inviteresponse.get.js out of the way and "turning on" Java-backed Web Scripts

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9818 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Glen Johnson
2008-07-11 14:45:02 +00:00
parent edd806d89a
commit 022f0bed8f
8 changed files with 529 additions and 174 deletions

View File

@@ -1,6 +1,6 @@
<webscript>
<shortname>Invites</shortname>
<description>Returns pending invites filtered by Inviter user name, Invitee user name & Site short name</description>
<description>Returns pending invites filtered by Inviter user name, Invitee user name &amp; Site short name</description>
<url>/api/invites?inviterUserName={inviterUserName}&amp;inviteeUserName={inviteeUserName?}&amp;siteShortName={siteShortName?}</url>
<url>/api/invites?inviterUserName={inviterUserName?}&amp;inviteeUserName={inviteeUserName}&amp;siteShortName={siteShortName?}</url>
<url>/api/invites?inviterUserName={inviterUserName?}&amp;inviteeUserName={inviteeUserName?}&amp;siteShortName={siteShortName}</url>

View File

@@ -277,9 +277,55 @@
</property>
</bean>
<!-- -->
<!-- Invite Service REST API -->
<!-- -->
<!-- -->
<!-- Invite Web Script - Invoked by a Site Manager (Inviter) to either invite another person (Invitee) to -->
<!-- join a Site as a Site Collaborator, or to cancel a pending invitation that has already been sent out -->
<!-- -->
<bean id="webscript.org.alfresco.repository.invite.invite.get"
class="org.alfresco.repo.web.scripts.invite.Invite"
parent="webscript">
<property name="workflowService" ref="workflowServiceImpl"/>
<property name="personService" ref="personService"/>
<property name="authenticationService" ref="authenticationService"/>
<property name="mutableAuthenticationDao" ref="authenticationDao"/>
<property name="namespaceService" ref="namespaceService"/>
<property name="authenticationComponent" ref="authenticationComponent"/>
<property name="userNameGenerator" ref="userNameGenerator"/>
<property name="passwordGenerator" ref="passwordGenerator"/>
</bean>
<!-- -->
<!-- Invite Response Web Script - invoked by Invitee to either 'accept' an invitation from a -->
<!-- Site Manager (Inviter), or to reject an invitation that has already been sent out -->
<!-- -->
<bean id="webscript.org.alfresco.repository.invite.inviteresponse.get"
class="org.alfresco.repo.web.scripts.invite.InviteResponse"
parent="webscript">
<property name="workflowService" ref="workflowServiceImpl"/>
<property name="mutableAuthenticationDao" ref="authenticationDao"/>
<property name="siteService" ref="siteService"/>
<property name="personService" ref="personService"/>
</bean>
<!-- -->
<!-- Invites Web Script (pending invites) - returns pending invites matching the given -->
<!-- inviter user name, invitee user name, site short name, or invite ID URL request parameters -->
<!-- (at least one of the above parameters must be provided) -->
<!-- -->
<bean id="webscript.org.alfresco.repository.invite.invites.get"
class="org.alfresco.repo.web.scripts.invite.Invites"
parent="webscript">
<property name="workflowService" ref="workflowServiceImpl"/>
<property name="namespaceService" ref="namespaceService"/>
</bean>
<!-- Switch on debugger by setting log4j.logger.org.alfresco.repo.web.scripts.AlfrescoRhinoScriptDebugger to DEBUG -->
<bean id="rhinoScriptDebugger" class="org.alfresco.repo.web.scripts.AlfrescoRhinoScriptDebugger" init-method="start"/>
</beans>

View File

@@ -26,17 +26,23 @@ package org.alfresco.repo.web.scripts.invite;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.authentication.PasswordGenerator;
import org.alfresco.repo.security.authentication.UserNameGenerator;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.Status;
@@ -72,6 +78,8 @@ public class Invite extends DeclarativeWebScript
private PersonService personService;
private AuthenticationService authenticationService;
private MutableAuthenticationDao mutableAuthenticationDao;
private NamespaceService namespaceService;
private AuthenticationComponent authenticationComponent;
// user name and password generation beans
private UserNameGenerator usernameGenerator;
@@ -83,6 +91,7 @@ public class Invite extends DeclarativeWebScript
public static final String WF_PROP_SITE_SHORT_NAME = "wf:siteShortName";
private static final String WF_PROP_INVITEE_GEN_PASSWORD = "wf:inviteeGenPassword";
public static final String WF_INVITE_TASK_INVITE_TO_SITE = "wf:inviteToSiteTask";
public static final String WORKFLOW_DEFINITION_NAME = "jbpm$wf:invite";
/**
@@ -130,6 +139,27 @@ public class Invite extends DeclarativeWebScript
{
this.mutableAuthenticationDao = mutableAuthenticationDao;
}
/**
* Set the namespace service
*
* @param namespaceService the namespace service to set
*/
public void setNamespaceService(
NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/**
* Set the authentication component
*
* @param authenticationComponent the authentication component to set
*/
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
{
this.authenticationComponent = authenticationComponent;
}
/**
* Set the user name generator service
@@ -266,9 +296,14 @@ public class Invite extends DeclarativeWebScript
private void startInvite(Map<String, Object> model, String inviteeEmail,
String siteShortName)
{
// get the inviter user name (the name of user web script is executed under)
// - needs to be assigned here because various system calls further on
// - in this method set the current user to the system user
String inviterUserName = this.authenticationService.getCurrentUserName();
WorkflowDefinition wfDefinition = this.workflowService
.getDefinitionByName(WORKFLOW_DEFINITION_NAME);
// handle workflow definition does not exist
if (wfDefinition == null)
{
@@ -314,21 +349,55 @@ public class Invite extends DeclarativeWebScript
// create workflow properties
Map<QName, Serializable> workflowProps = new HashMap<QName, Serializable>(
4);
workflowProps.put(QName.createQName(WF_PROP_INVITER_USER_NAME),
this.authenticationService.getCurrentUserName());
workflowProps.put(QName.createQName(WF_PROP_INVITEE_USER_NAME),
workflowProps.put(QName.createQName(WF_PROP_INVITER_USER_NAME, this.namespaceService),
inviterUserName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_USER_NAME, this.namespaceService),
inviteeUserName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_GEN_PASSWORD),
generatedPassword);
workflowProps.put(QName.createQName(WF_PROP_SITE_SHORT_NAME), siteShortName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_GEN_PASSWORD, this.namespaceService),
String.valueOf(generatedPassword));
workflowProps.put(QName.createQName(WF_PROP_SITE_SHORT_NAME, this.namespaceService),
siteShortName);
// start the workflow
WorkflowPath wfPath = this.workflowService.startWorkflow(wfDefinition
.getId(), workflowProps);
// get the workflow instance and path IDs
String workflowId = wfPath.instance.id;
String wfPathId = wfPath.id;
// complete the start task
List<WorkflowTask> wfTasks = this.workflowService.getTasksForWorkflowPath(wfPathId);
// throw an exception if no tasks where found on the workflow path
if (wfTasks.size() == 0)
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"No workflow tasks where found on workflow path ID: " + wfPathId);
}
// first task in workflow task list associated with the workflow path id above
// should be "wf:inviteToSiteTask", otherwise throw web script exception
String wfTaskTitle = wfTasks.get(0).title;
if (!wfTaskTitle.equals(WF_INVITE_TASK_INVITE_TO_SITE))
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"First workflow task found on workflow path ID: " + wfPathId
+ " should be " + WF_INVITE_TASK_INVITE_TO_SITE);
}
// complete invite workflow start task
WorkflowTask wfStartTask = wfTasks.get(0);
// send out the invite
this.workflowService.signal(wfPath.id, TRANSITION_SEND_INVITE);
// attach empty package to start task, end it and follow transition
// thats sends out invite
NodeRef wfPackage = this.workflowService.createPackage(null);
Map<QName, Serializable> wfTaskProps = new HashMap<QName, Serializable>(1, 1.0f);
wfTaskProps.put(WorkflowModel.ASSOC_PACKAGE, wfPackage);
this.workflowService.updateTask(wfStartTask.id, wfTaskProps, null, null);
this.workflowService.endTask(wfStartTask.id, TRANSITION_SEND_INVITE);
// add model properties for template to render
model.put(MODEL_PROP_KEY_ACTION, ACTION_START);

View File

@@ -28,7 +28,9 @@ import java.util.HashMap;
import java.util.List;
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.SiteModel;
import org.alfresco.repo.site.SiteService;
import org.alfresco.service.cmr.security.PersonService;
@@ -42,19 +44,52 @@ import org.alfresco.web.scripts.WebScriptRequest;
/**
* Web Script invoked by Invitee to either accept (response='accept') an
* invitation from a Site Manager (Inviter) to join a Site as a Site
* Collaborator, or to reject (response='reject') an invitation that has
* already been sent out
* Collaborator, or to reject (response='reject') an invitation that has already
* been sent out
*
* @author glen dot johnson at alfresco dot com
*/
public class InviteResponse extends DeclarativeWebScript
{
/**
* Inner class providing functionality (which needs to run under admin
* rights) to set membership of invitee (given as invitee user name) to site
* (given as site short name) as given site role
*/
private class SetSiteMembershipWorker implements
AuthenticationUtil.RunAsWork<Boolean>
{
private String siteShortName;
private String inviteeUserName;
private String siteRole;
private SetSiteMembershipWorker(String siteShortName,
String inviteeUserName, String siteRole)
{
this.siteShortName = siteShortName;
this.inviteeUserName = inviteeUserName;
this.siteRole = siteRole;
}
/**
* Does the work to set the site membership
*/
public Boolean doWork() throws Exception
{
InviteResponse.this.siteService.setMembership(this.siteShortName,
this.inviteeUserName, this.siteRole);
return Boolean.TRUE;
}
}
private static final String RESPONSE_ACCEPT = "accept";
private static final String RESPONSE_REJECT = "reject";
private static final String TRANSITION_ACCEPT = "accept";
private static final String TRANSITION_REJECT = "reject";
private static final String MODEL_PROP_KEY_RESPONSE = "response";
private static final String MODEL_PROP_KEY_SITE_SHORT_NAME = "siteShortName";
private static final String USER_ADMIN = "admin";
// properties for services
private WorkflowService workflowService;
@@ -196,21 +231,22 @@ public class InviteResponse extends DeclarativeWebScript
String inviteeUserName, String siteShortName)
{
// get workflow paths associated with given workflow ID
List<WorkflowPath> wfPaths = this.workflowService.getWorkflowPaths(workflowId);
// throw web script exception if there is not at least one workflow path
List<WorkflowPath> wfPaths = this.workflowService
.getWorkflowPaths(workflowId);
// throw web script exception if there is not at least one workflow path
// associated with this workflow ID
if ((wfPaths == null) || (wfPaths.size() == 0))
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"There are no workflow paths associated with workflow ID: "
+ workflowId);
+ workflowId);
}
// get workflow path ID for path matching workflow ID
WorkflowPath wfPath = wfPaths.get(0);
String wfPathID = wfPath.id;
this.workflowService.signal(wfPathID, TRANSITION_ACCEPT);
// enable invitee person's user account because he/she has accepted the
@@ -218,8 +254,9 @@ public class InviteResponse extends DeclarativeWebScript
this.mutableAuthenticationDao.setEnabled(inviteeUserName, true);
// Add Invitee to Site as "Site Collaborator" role
this.siteService.setMembership(siteShortName, inviteeUserName,
SiteModel.SITE_COLLABORATOR);
RunAsWork<Boolean> setSiteMembershipWorker = new InviteResponse.SetSiteMembershipWorker(
siteShortName, inviteeUserName, SiteModel.SITE_COLLABORATOR);
AuthenticationUtil.runAs(setSiteMembershipWorker, USER_ADMIN);
// add model properties for template to render
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_ACCEPT);
@@ -244,21 +281,22 @@ public class InviteResponse extends DeclarativeWebScript
String inviteeUserName, String siteShortName)
{
// get workflow paths associated with given workflow ID
List<WorkflowPath> wfPaths = this.workflowService.getWorkflowPaths(workflowId);
// throw web script exception if there is not at least one workflow path
List<WorkflowPath> wfPaths = this.workflowService
.getWorkflowPaths(workflowId);
// throw web script exception if there is not at least one workflow path
// associated with this workflow ID
if ((wfPaths == null) || (wfPaths.size() == 0))
{
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"There are no workflow paths associated with workflow ID: "
+ workflowId);
+ workflowId);
}
// get workflow path ID for path matching workflow ID
WorkflowPath wfPath = wfPaths.get(0);
String wfPathID = wfPath.id;
this.workflowService.signal(wfPathID, TRANSITION_REJECT);
// delete the person created for invitee

View File

@@ -33,6 +33,7 @@ import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.util.PropertyMap;
import org.alfresco.web.scripts.Status;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -47,161 +48,324 @@ public class InviteServiceTest extends BaseWebScriptTest
private AuthenticationComponent authenticationComponent;
private PersonService personService;
private SiteService siteService;
private static final String USER_ADMIN = "admin";
private static final String USER_INVITER = "InviteeUser";
private static final String INVITEE_EMAIL = "inviter123@email.com";
private static final String SITE_SHORT_NAME_INVITE = "InviteSiteShortName";
private static final String URL_INVITE_SERVICE = "/api/invite";
private static final String URL_INVITERSP_SERVICE = "/api/inviteresponse";
private static final String URL_INVITES_SERVICE = "/api/invites";
private static final String INVITE_ACTION_START = "start";
private static final String INVITE_ACTION_CANCEL = "cancel";
private static final String INVITE_RSP_ACCEPT = "accept";
private static final String INVITE_RSP_REJECT = "reject";
@Override
protected void setUp() throws Exception
{
super.setUp();
this.authenticationService = (AuthenticationService) getServer()
.getApplicationContext().getBean("AuthenticationService");
this.authenticationComponent = (AuthenticationComponent) getServer()
.getApplicationContext().getBean("authenticationComponent");
this.personService = (PersonService) getServer()
.getApplicationContext().getBean("PersonService");
this.siteService = (SiteService) getServer().getApplicationContext()
.getBean("siteService");
// set current user as admin for person and site creation
this.authenticationComponent.setCurrentUser(USER_ADMIN);
this.authenticationService = (AuthenticationService)getServer().getApplicationContext().getBean("AuthenticationService");
this.authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent");
this.personService = (PersonService)getServer().getApplicationContext().getBean("PersonService");
this.siteService = (SiteService)getServer().getApplicationContext().getBean("siteService");
// Create inviter user
createUser(USER_INVITER);
// Create inviter person
createPerson(USER_INVITER);
// Create site for Inviter to invite Invitee to
// - only create the site if it doesn't already exist
SiteInfo siteInfo = this.siteService.getSite(SITE_SHORT_NAME_INVITE);
if (siteInfo == null)
{
this.siteService.createSite("InviteSitePreset", SITE_SHORT_NAME_INVITE, "InviteSiteTitle",
"InviteSiteDescription", true);
this.siteService.createSite("InviteSitePreset",
SITE_SHORT_NAME_INVITE, "InviteSiteTitle",
"InviteSiteDescription", true);
}
// Do tests as inviter user
this.authenticationComponent.setCurrentUser(USER_INVITER);
}
@Override
protected void tearDown() throws Exception
{
super.tearDown();
// admin user required to delete user
this.authenticationComponent.setCurrentUser(USER_ADMIN);
// delete the inviter user
personService.deletePerson(USER_INVITER);
// delete invite site
siteService.deleteSite(SITE_SHORT_NAME_INVITE);
// return back to inviter user
this.authenticationComponent.setCurrentUser(USER_INVITER);
}
private void createUser(String userName)
private void createPerson(String userName)
{
// if user with given user name doesn't already exist then create user
if (this.authenticationService.authenticationExists(userName) == false)
{
// create user
this.authenticationService.createAuthentication(userName, "password".toCharArray());
this.authenticationService.createAuthentication(userName,
"password".toCharArray());
}
// if person with given user name doesn't already exist then create
// person
if (this.personService.personExists(userName) == false)
{
// create person properties
PropertyMap personProps = new PropertyMap();
personProps.put(ContentModel.PROP_USERNAME, userName);
personProps.put(ContentModel.PROP_FIRSTNAME, "FirstName123");
personProps.put(ContentModel.PROP_LASTNAME, "LastName123");
personProps.put(ContentModel.PROP_EMAIL, "FirstName123.LastName123@email.com");
personProps.put(ContentModel.PROP_EMAIL,
"FirstName123.LastName123@email.com");
personProps.put(ContentModel.PROP_JOBTITLE, "JobTitle123");
personProps.put(ContentModel.PROP_JOBTITLE, "Organisation123");
// create person node for user
this.personService.createPerson(personProps);
}
}
}
private JSONObject startInvite(String inviteeEmail, String siteShortName, int expectedStatus)
throws Exception
private JSONObject startInvite(String inviteeEmail, String siteShortName,
int expectedStatus) throws Exception
{
// Inviter sends invitation to Invitee to join a Site
String startInviteUrl = URL_INVITE_SERVICE + "/" + INVITE_ACTION_START + "?inviteeEmail=" + inviteeEmail
+ "&siteShortName=" + siteShortName;
MockHttpServletResponse response = getRequest(startInviteUrl, expectedStatus);
String startInviteUrl = URL_INVITE_SERVICE + "/" + INVITE_ACTION_START
+ "?inviteeEmail=" + inviteeEmail + "&siteShortName="
+ siteShortName;
MockHttpServletResponse response = getRequest(startInviteUrl,
expectedStatus);
JSONObject result = new JSONObject(response.getContentAsString());
return result;
}
private JSONArray getInvitesByInviteId(String inviteId, int expectedStatus)
throws Exception
{
// construct get invites URL
String getInvitesUrl = URL_INVITES_SERVICE + "?inviteId=" + inviteId;
// invoke get invites web script
MockHttpServletResponse response = getRequest(getInvitesUrl,
expectedStatus);
JSONArray result = new JSONArray(response.getContentAsString());
return result;
}
private JSONArray getInvitesByInviterUserName(String inviterUserName, int expectedStatus)
throws Exception
{
// construct get invites URL
String getInvitesUrl = URL_INVITES_SERVICE + "?inviterUserName=" + inviterUserName;
JSONObject result = new JSONObject(response.getContentAsString());
// invoke get invites web script
MockHttpServletResponse response = getRequest(getInvitesUrl,
expectedStatus);
JSONArray result = new JSONArray(response.getContentAsString());
return result;
}
private JSONArray getInvitesByInviteeUserName(String inviteeUserName, int expectedStatus)
throws Exception
{
// construct get invites URL
String getInvitesUrl = URL_INVITES_SERVICE + "?inviteeUserName=" + inviteeUserName;
// invoke get invites web script
MockHttpServletResponse response = getRequest(getInvitesUrl,
expectedStatus);
JSONArray result = new JSONArray(response.getContentAsString());
return result;
}
private JSONArray getInvitesBySiteShortName(String siteShortName, int expectedStatus)
throws Exception
{
// construct get invites URL
String getInvitesUrl = URL_INVITES_SERVICE + "?siteShortName=" + siteShortName;
// invoke get invites web script
MockHttpServletResponse response = getRequest(getInvitesUrl,
expectedStatus);
JSONArray result = new JSONArray(response.getContentAsString());
return result;
}
public void testStartInvite() throws Exception
{
// admin user required to delete user
this.authenticationComponent.setCurrentUser(USER_ADMIN);
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE, Status.STATUS_OK);
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
assertEquals(INVITE_ACTION_START, result.get("action"));
assertEquals(SITE_SHORT_NAME_INVITE, result.get("siteShortName"));
}
public void testCancelInvite() throws Exception
{
// admin user required to delete user
this.authenticationComponent.setCurrentUser(USER_ADMIN);
// inviter starts invite workflow
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE, Status.STATUS_OK);
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get hold of workflow ID of started invite workflow instance
String workflowId = result.getString("workflowId");
// Inviter cancels pending invitation
String cancelInviteUrl = URL_INVITE_SERVICE + "/" + INVITE_ACTION_CANCEL + "?workflowId=" + workflowId;
MockHttpServletResponse response = getRequest(cancelInviteUrl, Status.STATUS_OK);
String cancelInviteUrl = URL_INVITE_SERVICE + "/"
+ INVITE_ACTION_CANCEL + "?workflowId=" + workflowId;
MockHttpServletResponse response = getRequest(cancelInviteUrl,
Status.STATUS_OK);
}
public void testAcceptInvite() throws Exception
{
// admin user required to delete user
this.authenticationComponent.setCurrentUser(USER_ADMIN);
// inviter starts invite workflow
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE, Status.STATUS_OK);
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get hold of workflow ID of started invite workflow instance
String workflowId = result.getString("workflowId");
// get hold of invitee user name that was generated as part of starting the invite
// get hold of invitee user name that was generated as part of starting
// the invite
String inviteeUserName = result.getString("inviteeUserName");
// Invitee accepts invitation to a Site from Inviter
String acceptInviteUrl = URL_INVITERSP_SERVICE + "/" + INVITE_RSP_ACCEPT + "?workflowId=" + workflowId
+ "&inviteeUserName=" + inviteeUserName + "&siteShortName=" + SITE_SHORT_NAME_INVITE;
MockHttpServletResponse response = getRequest(acceptInviteUrl, Status.STATUS_OK);
String acceptInviteUrl = URL_INVITERSP_SERVICE + "/"
+ INVITE_RSP_ACCEPT + "?workflowId=" + workflowId
+ "&inviteeUserName=" + inviteeUserName + "&siteShortName="
+ SITE_SHORT_NAME_INVITE;
MockHttpServletResponse response = getRequest(acceptInviteUrl,
Status.STATUS_OK);
}
public void testRejectInvite() throws Exception
{
// admin user required to delete user
this.authenticationComponent.setCurrentUser(USER_ADMIN);
// inviter starts invite workflow
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE, Status.STATUS_OK);
JSONObject result = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get hold of workflow ID of started invite workflow instance
String workflowId = result.getString("workflowId");
// get hold of invitee user name that was generated as part of starting the invite
// get hold of invitee user name that was generated as part of starting
// the invite
String inviteeUserName = result.getString("inviteeUserName");
// Invitee rejects invitation to a Site from Inviter
String rejectInviteUrl = URL_INVITERSP_SERVICE + "/" + INVITE_RSP_REJECT + "?workflowId=" + workflowId
+ "&inviteeUserName=" + inviteeUserName + "&siteShortName=" + SITE_SHORT_NAME_INVITE;
MockHttpServletResponse response = getRequest(rejectInviteUrl, Status.STATUS_OK);
String rejectInviteUrl = URL_INVITERSP_SERVICE + "/"
+ INVITE_RSP_REJECT + "?workflowId=" + workflowId
+ "&inviteeUserName=" + inviteeUserName + "&siteShortName="
+ SITE_SHORT_NAME_INVITE;
MockHttpServletResponse response = getRequest(rejectInviteUrl,
Status.STATUS_OK);
}
public void testGetInvitesByInviteId() throws Exception
{
// inviter starts invite workflow
JSONObject startInviteResult = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get hold of workflow ID of started invite workflow instance
String inviteId = startInviteResult.getString("workflowId");
assertEquals(true, ((inviteId != null) && (inviteId.length() != 0)));
// get pending invite matching inviteId from invite started above
JSONArray getInvitesResult = getInvitesByInviteId(inviteId, Status.STATUS_OK);
assertEquals(getInvitesResult.length(), 1);
JSONObject inviteJSONObj = getInvitesResult.getJSONObject(0);
assertEquals(inviteId, inviteJSONObj.get("inviteId"));
}
public void testGetInvitesByInviterUserName() throws Exception
{
// inviter starts invite workflow
JSONObject startInviteResult = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get pending invites matching inviter user name used in invite started above
JSONArray getInvitesResult = getInvitesByInviterUserName(USER_INVITER, Status.STATUS_OK);
assertEquals(true, getInvitesResult.length() > 0);
JSONObject inviteJSONObj = getInvitesResult.getJSONObject(0);
assertEquals(USER_INVITER, inviteJSONObj.get("inviterUserName"));
}
public void testGetInvitesByInviteeUserName() throws Exception
{
// inviter starts invite workflow
JSONObject startInviteResult = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get hold of invitee user name property of started invite workflow instance
String inviteeUserName = startInviteResult.getString("inviteeUserName");
assertEquals(true, ((inviteeUserName != null) && (inviteeUserName.length() != 0)));
// get pending invites matching invitee user name from invite started above
JSONArray getInvitesResult = getInvitesByInviteeUserName(inviteeUserName, Status.STATUS_OK);
assertEquals(true, getInvitesResult.length() > 0);
JSONObject inviteJSONObj = getInvitesResult.getJSONObject(0);
assertEquals(inviteeUserName, inviteJSONObj.get("inviteeUserName"));
}
public void testGetInvitesBySiteShortName() throws Exception
{
// inviter starts invite workflow
JSONObject startInviteResult = startInvite(INVITEE_EMAIL, SITE_SHORT_NAME_INVITE,
Status.STATUS_OK);
// get hold of site short name property of started invite workflow instance
String siteShortName = startInviteResult.getString("siteShortName");
assertEquals(true, ((siteShortName != null) && (siteShortName.length() != 0)));
// get pending invites matching site short name from invite started above
JSONArray getInvitesResult = getInvitesBySiteShortName(siteShortName, Status.STATUS_OK);
assertEquals(true, getInvitesResult.length() > 0);
JSONObject inviteJSONObj = getInvitesResult.getJSONObject(0);
assertEquals(siteShortName, inviteJSONObj.get("siteShortName"));
}
}

View File

@@ -24,7 +24,6 @@
*/
package org.alfresco.repo.web.scripts.invite;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -33,6 +32,8 @@ import java.util.Map;
import org.alfresco.service.cmr.workflow.WorkflowService;
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.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.Status;
@@ -41,19 +42,19 @@ import org.alfresco.web.scripts.WebScriptRequest;
/**
* Web Script which returns pending Site invitations matching at least one of
*
* (1a) inviter (inviter user name). i.e. pending invitations which have been sent
* by that inviter, but which have not been responded to (accepted or rejected)
* by the invitee, and have not been cancelled by that inviter
*
* (1b) invitee (invitee user name), i.e. pending invitations which have not been accepted or
* rejected yet by that inviter
*
* (1c) site (site short name), i.e. pending invitations sent out to join that Site.
* If only the site is given, then all pending invites are returned, irrespective of who
* the inviters or invitees are
*
* or
* (1a) inviter (inviter user name). i.e. pending invitations which have been
* sent by that inviter, but which have not been responded to (accepted or
* rejected) by the invitee, and have not been cancelled by that inviter
*
* (1b) invitee (invitee user name), i.e. pending invitations which have not
* been accepted or rejected yet by that inviter
*
* (1c) site (site short name), i.e. pending invitations sent out to join that
* Site. If only the site is given, then all pending invites are returned,
* irrespective of who the inviters or invitees are
*
* or
*
* (2) matching the given invite ID
*
@@ -67,23 +68,36 @@ public class Invites extends DeclarativeWebScript
private static final String PARAM_INVITEE_USER_NAME = "inviteeUserName";
private static final String PARAM_SITE_SHORT_NAME = "siteShortName";
private static final String PARAM_INVITE_ID = "inviteId";
// model key names
private static final String MODEL_KEY_NAME_INVITES = "invites";
// service instances
private WorkflowService workflowService;
private NamespaceService namespaceService;
/**
* Set the workflow service property
*
* @param workflowService the workflow service to set
* @param workflowService
* the workflow service to set
*/
public void setWorkflowService(WorkflowService workflowService)
{
this.workflowService = workflowService;
}
/**
* Set the namespace service
*
* @param namespaceService the namespace service to set
*/
public void setNamespaceService(
NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/*
* (non-Javadoc)
*
@@ -98,7 +112,7 @@ public class Invites extends DeclarativeWebScript
{
// initialise model to pass on for template to render
Map<String, Object> model = new HashMap<String, Object>();
// Get parameter names
String[] paramNames = req.getParameterNames();
@@ -108,110 +122,134 @@ public class Invites extends DeclarativeWebScript
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"No parameters have been provided on URL");
}
// get URL request parameters, checking if they have been provided
// check if 'inviterUserName' parameter provided
String inviterUserName = req.getParameter(PARAM_INVITER_USER_NAME);
boolean inviterUserNameProvided = (inviterUserName != null) && (inviterUserName.length() != 0);
boolean inviterUserNameProvided = (inviterUserName != null)
&& (inviterUserName.length() != 0);
// check if 'inviteeUserName' parameter provided
String inviteeUserName = req.getParameter(PARAM_INVITEE_USER_NAME);
boolean inviteeUserNameProvided = (inviteeUserName != null) && (inviteeUserName.length() != 0);
boolean inviteeUserNameProvided = (inviteeUserName != null)
&& (inviteeUserName.length() != 0);
// check if 'siteShortName' parameter provided
String siteShortName = req.getParameter(PARAM_SITE_SHORT_NAME);
boolean siteShortNameProvided = (siteShortName != null) && (siteShortName.length() != 0);
boolean siteShortNameProvided = (siteShortName != null)
&& (siteShortName.length() != 0);
// check if 'inviteId' parameter provided
String inviteId = req.getParameter(PARAM_INVITE_ID);
boolean inviteIdProvided = (inviteId != null) && (inviteId.length() != 0);
boolean inviteIdProvided = (inviteId != null)
&& (inviteId.length() != 0);
// throw web script exception if at least one of 'inviterUserName', 'inviteeUserName', 'siteShortName',
// throw web script exception if at least one of 'inviterUserName',
// 'inviteeUserName', 'siteShortName',
// 'inviteId' URL request parameters has not been provided
if (!(inviterUserNameProvided || inviteeUserNameProvided || siteShortNameProvided || inviteIdProvided))
if (!(inviterUserNameProvided || inviteeUserNameProvided
|| siteShortNameProvided || inviteIdProvided))
{
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
throw new WebScriptException(
Status.STATUS_BAD_REQUEST,
"At least one of the following URL request parameters must be provided in URL "
+ "'inviterUserName', 'inviteeUserName', 'siteShortName' or 'inviteId'");
+ "'inviterUserName', 'inviteeUserName', 'siteShortName' or 'inviteId'");
}
// query for workflow tasks by given parameters
// create workflow task query
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
// query only active workflows
wfTaskQuery.setActive(Boolean.TRUE);
// workflow query properties
HashMap<QName, Object> wfQueryProps = null;
// if 'inviteId' has been provided then set that as the workflow query process ID
// - since this is unique don't bother about setting the other workflow query
// if 'inviteId' has been provided then set that as the workflow query
// process ID
// - since this is unique don't bother about setting the other workflow
// query
// - properties
if (inviteIdProvided)
{
wfTaskQuery.setProcessId(inviteId);
}
else
// 'inviteId' has not been provided, so create the query properties from the invite URL request
// parameters
// - because this web script class will terminate with a web script exception if none of the required
// request parameters are provided, at least one of these query properties will be set
// at this point
} else
// 'inviteId' has not been provided, so create the query properties from
// the invite URL request
// parameters
// - because this web script class will terminate with a web script
// exception if none of the required
// request parameters are provided, at least one of these query
// properties will be set
// at this point
{
wfQueryProps = new HashMap<QName, Object>(3, 1.0f);
// workflow query properties
HashMap<QName, Object> wfQueryProps = new HashMap<QName, Object>(3,
1.0f);
if (inviterUserName != null)
{
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITER_USER_NAME), inviterUserName);
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITER_USER_NAME, this.namespaceService),
inviterUserName);
}
if (inviteeUserName != null)
{
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITEE_USER_NAME), inviteeUserName);
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITEE_USER_NAME, this.namespaceService),
inviteeUserName);
}
if (siteShortName != null)
{
wfQueryProps.put(QName.createQName(Invite.WF_PROP_SITE_SHORT_NAME), siteShortName);
wfQueryProps.put(QName.createQName(Invite.WF_PROP_SITE_SHORT_NAME, this.namespaceService),
siteShortName);
}
// set workflow task query parameters
wfTaskQuery.setProcessCustomProps(wfQueryProps);
wfTaskQuery.setTaskCustomProps(wfQueryProps);
}
// set process name to "wf:invite" so that only tasks associated with invite workflow instances
// query only active workflows
wfTaskQuery.setActive(Boolean.TRUE);
// pick up the start task
wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED);
wfTaskQuery.setTaskName(QName.createQName(Invite.WF_INVITE_TASK_INVITE_TO_SITE, this.namespaceService));
// set process name to "wf:invite" so that only tasks associated with
// invite workflow instances
// are returned by query
wfTaskQuery.setProcessName(QName.createQName(Invite.WORKFLOW_DEFINITION_NAME));
wfTaskQuery.setProcessName(QName.createQName("wf:invite", this.namespaceService));
// query for invite workflow tasks
List<WorkflowTask> wf_invite_tasks = this.workflowService.queryTasks(wfTaskQuery);
List<WorkflowTask> wf_invite_tasks = this.workflowService
.queryTasks(wfTaskQuery);
// InviteInfo List to place onto model
List<InviteInfo> inviteInfoList = new ArrayList<InviteInfo>();
// Put InviteInfo objects (containing workflow path properties
// wf:inviterUserName, wf:inviteeUserName, wf:siteShortName,
// and invite id property (from workflow instance id))
// wf:inviterUserName, wf:inviteeUserName, wf:siteShortName,
// and invite id property (from workflow instance id))
// onto model for each invite workflow task returned by the query
for (WorkflowTask workflowTask : wf_invite_tasks)
{
// get wf:inviterUserName, wf:inviteeUserName, wf:siteShortName
// properties from workflow path associated with workflow task
Map<QName, Serializable> pathProperties = this.workflowService.getPathProperties(workflowTask.path.id);
String inviterUserNameProp = (String)pathProperties.get(Invite.WF_PROP_INVITER_USER_NAME);
String inviteeUserNameProp = (String)pathProperties.get(Invite.WF_PROP_INVITEE_USER_NAME);
String siteShortNameProp = (String)pathProperties.get(Invite.WF_PROP_SITE_SHORT_NAME);
// get workflow instance id (associated with workflow task) to place as "inviteId" onto model
String inviterUserNameProp = (String) workflowTask.properties.get(
QName.createQName(Invite.WF_PROP_INVITER_USER_NAME, this.namespaceService));
String inviteeUserNameProp = (String) workflowTask.properties.get(
QName.createQName(Invite.WF_PROP_INVITEE_USER_NAME, this.namespaceService));
String siteShortNameProp = (String) workflowTask.properties.get(
QName.createQName(Invite.WF_PROP_SITE_SHORT_NAME, this.namespaceService));
// get workflow instance id (associated with workflow task) to place
// as "inviteId" onto model
String workflowId = workflowTask.path.instance.id;
// create and add InviteInfo to inviteInfoList
InviteInfo inviteInfo = new InviteInfo(inviterUserNameProp, inviteeUserNameProp, siteShortNameProp, workflowId);
InviteInfo inviteInfo = new InviteInfo(inviterUserNameProp,
inviteeUserNameProp, siteShortNameProp, workflowId);
inviteInfoList.add(inviteInfo);
}
// put the list of invite infos onto model to be passed onto template for rendering
// put the list of invite infos onto model to be passed onto template
// for rendering
model.put(MODEL_KEY_NAME_INVITES, inviteInfoList);
return model;
}
}