mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Latest cut of Invite Service/Workflow containing last bunch of fixes/modifications needed to get Web Script Unit Tests to pass
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@9597 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,8 +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/{action}?site={siteShortName}</url>
|
<url>/api/invite/start?inviteeEmail={inviteeEmailAddress}&siteShortName={siteShortName}</url>
|
||||||
<format default="html">extension</format>
|
<url>/api/invite/cancel?workflowId={workflowId}</url>
|
||||||
|
<format default="json"/>
|
||||||
<authentication>user</authentication>
|
<authentication>user</authentication>
|
||||||
<transaction>required</transaction>
|
<transaction>required</transaction>
|
||||||
</webscript>
|
</webscript>
|
@@ -1,33 +1,57 @@
|
|||||||
|
var WORKFLOW_DEFINITION_NAME = "jbpm$wf:invite";
|
||||||
|
var ACTION_START = "start";
|
||||||
|
var ACTION_CANCEL = "cancel";
|
||||||
|
var TRANSITION_SEND_INVITE = "sendInvite";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the Invite workflow
|
* Starts the Invite workflow
|
||||||
*
|
*
|
||||||
* @method start
|
* @method start
|
||||||
* @static
|
* @static
|
||||||
|
* @param inviteeEmail string email address of invitee
|
||||||
* @param siteShortName string short name of site that the invitee is being
|
* @param siteShortName string short name of site that the invitee is being
|
||||||
* invited to by the inviter
|
* invited to by the inviter
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function start(siteShortName)
|
function start(inviteeEmail, siteShortName)
|
||||||
{
|
{
|
||||||
var wfDefinition = workflow.getDefinitionByName("wf:invite");
|
var wfDefinition = workflow.getDefinitionByName(WORKFLOW_DEFINITION_NAME);
|
||||||
|
|
||||||
// create invitee with generated user name and password, and with a
|
// handle workflow definition does not exist
|
||||||
|
if (wfDefinition === null)
|
||||||
|
{
|
||||||
|
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "Workflow definition "
|
||||||
|
+ "for name " + WORKFLOW_DEFINITION_NAME + " does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create invitee person with generated user name and password, and with a
|
||||||
// disabled user account
|
// disabled user account
|
||||||
var invitee = people.createPerson(true, false);
|
var invitee = people.createPerson(true, false);
|
||||||
|
invitee.properties["cm:email"] = inviteeEmail;
|
||||||
|
invitee.save();
|
||||||
|
|
||||||
// create workflow properties, containing inviter and invitee user name,
|
var inviteeUserName = invitee.properties.userName;
|
||||||
// and site short name
|
|
||||||
|
// create workflow properties
|
||||||
var workflowProps = [];
|
var workflowProps = [];
|
||||||
workflowProps["inviterUserName"] = person.properties.userName;
|
workflowProps["wf:inviterUserName"] = person.properties.userName;
|
||||||
workflowProps["inviteeUserName"] = invitee.properties.userName;
|
workflowProps["wf:inviteeUserName"] = inviteeUserName;
|
||||||
workflowProps["siteShortName"] = siteShortName;
|
workflowProps["wf:inviteeGenPassword"] = invitee.properties.generatedPassword;
|
||||||
wfDefinition.startWorkflow(null, workflowProps);
|
workflowProps["wf:siteShortName"] = siteShortName;
|
||||||
|
|
||||||
// add action context info to model
|
// start the workflow
|
||||||
model.action = "start";
|
var wfPath = wfDefinition.startWorkflow(workflowProps);
|
||||||
|
var workflowId = wfPath.instance.id;
|
||||||
|
|
||||||
|
// send out the invite
|
||||||
|
wfPath.signal(TRANSITION_SEND_INVITE);
|
||||||
|
|
||||||
|
// add action info to model for template processing
|
||||||
|
model.action = ACTION_START;
|
||||||
|
model.workflowId = workflowId;
|
||||||
model.inviteeUserName = inviteeUserName;
|
model.inviteeUserName = inviteeUserName;
|
||||||
model.siteShortName = siteShortName;
|
model.siteShortName = siteShortName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,10 +66,20 @@ function start(siteShortName)
|
|||||||
function cancel(workflowId)
|
function cancel(workflowId)
|
||||||
{
|
{
|
||||||
var workflowInstance = workflow.getInstance(workflowId);
|
var workflowInstance = workflow.getInstance(workflowId);
|
||||||
|
|
||||||
|
// handle workflow instance for given workflow ID does not exist
|
||||||
|
if (workflowInstance === null)
|
||||||
|
{
|
||||||
|
status.setCode(status.STATUS_BAD_REQUEST, "Workflow instance for given "
|
||||||
|
+ "workflow ID " + workflowId + " does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel the workflow
|
||||||
workflowInstance.cancel();
|
workflowInstance.cancel();
|
||||||
|
|
||||||
// add action context info to model
|
// add action info to model for template
|
||||||
model.action = "cancel";
|
model.action = ACTION_CANCEL;
|
||||||
model.workflowId = workflowId;
|
model.workflowId = workflowId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,60 +91,77 @@ function cancel(workflowId)
|
|||||||
*/
|
*/
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
// check that the action ('start' or 'cancel') has been provided on the URL
|
// extract action string from URL
|
||||||
// and that URL parameters have been provided
|
var action = null;
|
||||||
if ((url.extension === null) || (args.length == 0))
|
var actionStartIndex = url.service.lastIndexOf("/") + 1;
|
||||||
|
if (actionStartIndex <= url.service.length() - 1)
|
||||||
{
|
{
|
||||||
// handle action not provided or no parameters given
|
action = url.service.substring(actionStartIndex, url.service.length());
|
||||||
status.code = 400;
|
|
||||||
status.message = "Action has not been provided in URL or " +
|
|
||||||
"no parameters have been provided on URL";
|
|
||||||
status.redirect = true;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// handle action provided in URL ('start' or 'cancel')
|
|
||||||
var action = url.extension;
|
|
||||||
|
|
||||||
// handle if provided 'action' is 'start'
|
// check that the action has been provided on the URL
|
||||||
if (action == "start")
|
// and that URL parameters have been provided
|
||||||
|
if ((action === null) || (action.length == 0))
|
||||||
{
|
{
|
||||||
// check for 'siteShortName' parameter
|
// handle action not provided on URL
|
||||||
|
status.setCode(status.STATUS_BAD_REQUEST, "Action has not been provided in URL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle no parameters given on URL
|
||||||
|
if (args.length == 0)
|
||||||
|
{
|
||||||
|
status.setCode(status.STATUS_BAD_REQUEST, "No parameters have been provided on URL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle action 'start'
|
||||||
|
if (action == ACTION_START)
|
||||||
|
{
|
||||||
|
// check for 'inviteeEmail' parameter not provided
|
||||||
|
if ((args["inviteeEmail"] === null) || (args["inviteeEmail"].length == 0))
|
||||||
|
{
|
||||||
|
// handle inviteeEmail URL parameter not provided
|
||||||
|
status.setCode(status.STATUS_BAD_REQUEST, "'inviteeEmail' parameter " +
|
||||||
|
"has not been provided in URL for action '" + ACTION_START + "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for 'siteShortName' parameter not provided
|
||||||
if ((args["siteShortName"] === null) || (args["siteShortName"].length == 0))
|
if ((args["siteShortName"] === null) || (args["siteShortName"].length == 0))
|
||||||
{
|
{
|
||||||
// handle siteShortName URL parameter not provided
|
// handle siteShortName URL parameter not provided
|
||||||
status.code = 400;
|
status.setCode(status.STATUS_BAD_REQUEST, "'siteShortName' parameter " +
|
||||||
status.message = "'siteShortName' parameter has not been provided in URL for action 'start'";
|
"has not been provided in URL for action '" + ACTION_START + "'");
|
||||||
status.redirect = true;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start(args["siteShortName"]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process action 'start' with provided parameters
|
||||||
|
var inviteeEmail = args["inviteeEmail"];
|
||||||
|
var siteShortName = args["siteShortName"];
|
||||||
|
start(inviteeEmail, siteShortName);
|
||||||
}
|
}
|
||||||
// else handle if provided 'action' is 'cancel'
|
// else handle if provided 'action' is 'cancel'
|
||||||
else if (action == "cancel")
|
else if (action == ACTION_CANCEL)
|
||||||
{
|
{
|
||||||
// check for 'workflowId' parameter
|
// check for 'workflowId' parameter not provided
|
||||||
if ((args["workflowId"] === null) || (args["workflowId"].length == 0))
|
if ((args["workflowId"] === null) || (args["workflowId"].length == 0))
|
||||||
{
|
{
|
||||||
// handle workflowId URL parameter not provided
|
// handle workflowId URL parameter not provided
|
||||||
status.code = 400;
|
status.setCode(status.STATUS_BAD_REQUEST, "'workflowId' parameter has "
|
||||||
status.message = "'workflowId' parameter has not been provided in URL for action 'cancel'";
|
+ "not been provided in URL for action '" + ACTION_CANCEL +"'");
|
||||||
status.redirect = true;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cancel(args["workflowId"]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process action 'cancel' with provided parameters
|
||||||
|
var workflowId = args["workflowId"];
|
||||||
|
cancel(workflowId);
|
||||||
}
|
}
|
||||||
// handle action not recognised
|
// handle action not recognised
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status.code = 400;
|
status.setCode(status.STATUS_BAD_REQUEST, "Action, '" + action + "', "
|
||||||
status.message = "Action, '" + action + "', provided in URL has not been recognised.";
|
+ "provided in URL has not been recognised.");
|
||||||
status.redirect = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"action" : "${action}",
|
||||||
|
<#if workflowId??>
|
||||||
|
"workflowId" : "${workflowId}",
|
||||||
|
<#else>
|
||||||
|
"workflowId" : undefined,
|
||||||
|
</#if>
|
||||||
|
<#if inviteeUserName??>
|
||||||
|
"inviteeUserName" : "${inviteeUserName}",
|
||||||
|
<#else>
|
||||||
|
"inviteeUserName" : undefined,
|
||||||
|
</#if>
|
||||||
|
<#if siteShortName??>
|
||||||
|
"siteShortName" : "${siteShortName}"
|
||||||
|
<#else>
|
||||||
|
"siteShortName" : undefined
|
||||||
|
</#if>
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
<shortname>Invite Response</shortname>
|
<shortname>Invite Response</shortname>
|
||||||
<description>Processes invite response from Invitee</description>
|
<description>Processes invite response from Invitee</description>
|
||||||
<url>/api/inviteresponse/{response}?workflowId={workflowId}&inviteeUserName={inviteeUserName}&siteShortName={siteShortName}</url>
|
<url>/api/inviteresponse/{response}?workflowId={workflowId}&inviteeUserName={inviteeUserName}&siteShortName={siteShortName}</url>
|
||||||
<format default="html">extension</format>
|
<format default="json"/>
|
||||||
<authentication>guest</authentication>
|
<authentication>guest</authentication>
|
||||||
<transaction>required</transaction>
|
<transaction>required</transaction>
|
||||||
</webscript>
|
</webscript>
|
@@ -1,4 +1,6 @@
|
|||||||
var SITE_ROLE_COLLABORATOR = "collaborator";
|
var SITE_ROLE_COLLABORATOR = "SiteCollaborator";
|
||||||
|
var TRANSITION_ACCEPT = "accept";
|
||||||
|
var TRANSITION_REJECT = "reject";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes 'accept' response from invitee
|
* Processes 'accept' response from invitee
|
||||||
@@ -12,8 +14,22 @@ var SITE_ROLE_COLLABORATOR = "collaborator";
|
|||||||
function accept(workflowId, inviteeUserName, siteShortName)
|
function accept(workflowId, inviteeUserName, siteShortName)
|
||||||
{
|
{
|
||||||
var wfInstance = workflow.getInstance(workflowId);
|
var wfInstance = workflow.getInstance(workflowId);
|
||||||
var wfPath = wfInstance.getPaths()[0];
|
var wfPaths = wfInstance.getPaths();
|
||||||
wfPath.signal("accept");
|
|
||||||
|
// return error message if no workflow paths found for
|
||||||
|
// supplied workflow id
|
||||||
|
if ((wfPaths === null) || (wfPaths.length == 0))
|
||||||
|
{
|
||||||
|
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR,
|
||||||
|
"No workflow paths associated with workflow ID: "
|
||||||
|
+ workflowId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the first workflow path off the workflow paths array
|
||||||
|
// (there should only be one) and signal a transition to "accept"
|
||||||
|
var wfPath = wfPaths[0];
|
||||||
|
wfPath.signal(TRANSITION_ACCEPT);
|
||||||
|
|
||||||
people.enablePerson(inviteeUserName);
|
people.enablePerson(inviteeUserName);
|
||||||
|
|
||||||
@@ -21,8 +37,8 @@ function accept(workflowId, inviteeUserName, siteShortName)
|
|||||||
* Find out role string that Invitee should be added to Site as
|
* Find out role string that Invitee should be added to Site as
|
||||||
*/
|
*/
|
||||||
// Add Invitee to Site
|
// Add Invitee to Site
|
||||||
var site = sites.getSite(siteShortName);
|
var site = siteService.getSite(siteShortName);
|
||||||
site.setMembership(username, SITE_ROLE_COLLABORATOR);
|
site.setMembership(inviteeUserName, SITE_ROLE_COLLABORATOR);
|
||||||
|
|
||||||
// add data to appear in rendition
|
// add data to appear in rendition
|
||||||
model.response = "accept";
|
model.response = "accept";
|
||||||
@@ -40,9 +56,12 @@ function accept(workflowId, inviteeUserName, siteShortName)
|
|||||||
*/
|
*/
|
||||||
function reject(workflowId, inviteeUserName, siteShortName)
|
function reject(workflowId, inviteeUserName, siteShortName)
|
||||||
{
|
{
|
||||||
var wfInstance = workflow.getInstance(wfid);
|
var wfInstance = workflow.getInstance(workflowId);
|
||||||
var wfPath = wfInstance.getPaths()[0];
|
var wfPath = wfInstance.getPaths()[0];
|
||||||
wfPath.signal("reject");
|
wfPath.signal(TRANSITION_REJECT);
|
||||||
|
|
||||||
|
// delete the person created for invitee
|
||||||
|
people.deletePerson(inviteeUserName);
|
||||||
|
|
||||||
// add data to appear in rendition
|
// add data to appear in rendition
|
||||||
model.response = "reject";
|
model.response = "reject";
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"response" : "${response}",
|
||||||
|
"siteShortName" : "${siteShortName}"
|
||||||
|
}
|
@@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<model name="wf:workflowmodel"
|
<model name="wf:invite-workflow-model"
|
||||||
xmlns="http://www.alfresco.org/model/dictionary/1.0">
|
xmlns="http://www.alfresco.org/model/dictionary/1.0">
|
||||||
|
|
||||||
<imports>
|
<imports>
|
||||||
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
|
||||||
<import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm" />
|
<import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm" />
|
||||||
|
<import uri="http://www.alfresco.org/model/workflow/1.0" prefix="wf"/>
|
||||||
</imports>
|
</imports>
|
||||||
|
|
||||||
<types>
|
<types>
|
||||||
@@ -13,6 +14,24 @@
|
|||||||
|
|
||||||
<type name="wf:inviteToSiteTask">
|
<type name="wf:inviteToSiteTask">
|
||||||
<parent>bpm:startTask</parent>
|
<parent>bpm:startTask</parent>
|
||||||
|
<properties>
|
||||||
|
<property name="wf:inviterUserName">
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
|
<property name="wf:inviteeUserName">
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
|
<property name="wf:inviteeGenPassword">
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
|
<property name="wf:siteShortName">
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
</type>
|
||||||
|
|
||||||
|
<type name="wf:invitePendingTask">
|
||||||
|
<parent>bpm:workflowTask</parent>
|
||||||
</type>
|
</type>
|
||||||
|
|
||||||
<type name="wf:acceptInviteTask">
|
<type name="wf:acceptInviteTask">
|
||||||
|
@@ -2,76 +2,80 @@
|
|||||||
|
|
||||||
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:invite">
|
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:invite">
|
||||||
|
|
||||||
<swimlane name="inviter"/>
|
<swimlane name="initiator">
|
||||||
|
<assignment actor-id="#{wf_inviterUserName}"/>
|
||||||
|
</swimlane>
|
||||||
|
|
||||||
<swimlane name="invitee"/>
|
<swimlane name="assignee"/>
|
||||||
|
<!-- <assignment actor-id="#{wf_inviteeUserName}"/> -->
|
||||||
|
|
||||||
<start-state name="start">
|
<start-state name="start">
|
||||||
<task name="wf:inviteToSiteTask" swimlane="inviter" />
|
<task name="wf:inviteToSiteTask" swimlane="initiator" />
|
||||||
<transition name="" to="invitePending">
|
<transition name="sendInvite" to="invitePending">
|
||||||
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
|
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
|
||||||
<script>
|
<script>
|
||||||
/* TODO glen.johnson@alfresco.com generate username and password
|
// TODO glen johnson at alfresco dot com - get hold of the host
|
||||||
* and create person with inactive account
|
// and port for where the caller web script is located
|
||||||
*/
|
var hostname = "localhost";
|
||||||
var username = "jackblac12345";
|
var port = 8080;
|
||||||
var password = "password";
|
|
||||||
var person = people.createPerson("jackblac12345", "password");
|
|
||||||
|
|
||||||
/** TODO glen.johnson@alfresco.com - need to include Site name on subject line"
|
// get workflow instance ID
|
||||||
* need to pass this in from Invite Web Script as property into workflow
|
var workflowId = executionContext.processInstance.id;
|
||||||
*/
|
|
||||||
var sitename = null;
|
// get the invitee person
|
||||||
|
var inviteePerson = people.getPerson(wf_inviteeUserName);
|
||||||
|
|
||||||
var mail = actions.create("mail");
|
var mail = actions.create("mail");
|
||||||
mail.parameters.to = invitee.properties["cm:email"];
|
mail.parameters.to = inviteePerson.properties["cm:email"];
|
||||||
mail.parameters.subject = "Invitation to Alfresco Site";
|
mail.parameters.subject = "Invitation to Site " + wf_siteShortName;
|
||||||
mail.parameters.from = initiator.properties["cm:email"];
|
mail.parameters.from = initiator.properties["cm:email"];
|
||||||
|
|
||||||
/** TODO glen.johnson@alfresco.com - need to store id of current workflow instance
|
|
||||||
* into wfid action script variable
|
|
||||||
*/
|
|
||||||
var wfid = null;
|
|
||||||
|
|
||||||
mail.parameters.text = "Hello,\n"
|
mail.parameters.text = "Hello,\n"
|
||||||
+ "You have been invited to join the " + sitename + " Site.\n"
|
+ "You have been invited to join the site: "
|
||||||
+ "Your role in the site will be Collaborator.\n\n"
|
+ wf_siteShortName + "\n"
|
||||||
+ "Please click here http://{host}:{port}/alfresco/service/api/inviteresponse/accept?wfid={wfid}"
|
|
||||||
+ to accept the invitation\n"
|
|
||||||
+ "An account has been created for you with user"
|
|
||||||
+ username + "\n"
|
|
||||||
+ "An initial password has been generated for you"
|
|
||||||
+ password
|
|
||||||
+ ", please change it to a password of your choice once you have logged into the Site\n\n"
|
|
||||||
+ "Please click here "
|
+ "Please click here "
|
||||||
+ "http://{host}:{port}/alfresco/service/api/inviteresponse/reject?wfid={wfid}"
|
+ "http://" + hostname + ":" + port
|
||||||
+ "to reject the invitation\n";
|
+ "/alfresco/service/api/inviteresponse/accept?"
|
||||||
|
+ "workflowId=" + workflowId
|
||||||
|
+ "&inviteeUserName=" + wf_inviteeUserName
|
||||||
|
+ "&siteShortName=" + wf_siteShortName
|
||||||
|
+ " to accept the invitation\n\n"
|
||||||
|
+ "An account has been created for you with user name: "
|
||||||
|
+ wf_inviteeUserName + ".\n"
|
||||||
|
+ "An initial password has been generated for you: "
|
||||||
|
+ wf_inviteeGenPassword + ".\n"
|
||||||
|
+ "Please change it to a password of your choice once you "
|
||||||
|
+ "have logged into the site.\n\n"
|
||||||
|
+ "To reject the invitation to join the site: "
|
||||||
|
+ wf_siteShortName + ", "
|
||||||
|
+ "please click here "
|
||||||
|
+ "http://" + hostname + ":" + port
|
||||||
|
+ "/alfresco/service/api/inviteresponse/reject?"
|
||||||
|
+ "workflowId=" + workflowId
|
||||||
|
+ "&inviteeUserName=" + wf_inviteeUserName
|
||||||
|
+ "&siteShortName=" + wf_siteShortName;
|
||||||
|
|
||||||
mail.execute();
|
mail.execute(bpm_package);
|
||||||
</script>
|
</script>
|
||||||
</action>
|
</action>
|
||||||
</transition>
|
</transition>
|
||||||
</start-state>
|
</start-state>
|
||||||
|
|
||||||
<fork name="invitePending">
|
<task-node name="invitePending">
|
||||||
|
<task name="wf:invitePendingTask" swimlane="assignee" />
|
||||||
<transition name="accept" to="inviteAccepted" />
|
<transition name="accept" to="inviteAccepted" />
|
||||||
<transition name="reject" to="inviteRejected" />
|
<transition name="reject" to="inviteRejected" />
|
||||||
<transition name="cancel" to="acceptedOrRejectedOrCancelled" />
|
</task-node>
|
||||||
</fork>
|
|
||||||
|
|
||||||
<task-node name="inviteAccepted">
|
<task-node name="inviteAccepted">
|
||||||
<task name="wf:acceptInviteTask" swimlane="invitee" />
|
<task name="wf:acceptInviteTask" swimlane="assignee" />
|
||||||
<transition name="" to="acceptedOrRejectedOrCancelled" />
|
<transition name="" to="end" />
|
||||||
</task-node>
|
</task-node>
|
||||||
|
|
||||||
<task-node name="inviteRejected">
|
<task-node name="inviteRejected">
|
||||||
<task name="wf:rejectInviteTask" swimlane="invitee" />
|
<task name="wf:rejectInviteTask" swimlane="assignee" />
|
||||||
<transition name="" to="acceptedOrRejectedOrCancelled" />
|
|
||||||
</task-node>
|
|
||||||
|
|
||||||
<join name="acceptedOrRejectedOrCancelled">
|
|
||||||
<transition name="" to="end" />
|
<transition name="" to="end" />
|
||||||
</join>
|
</task-node>
|
||||||
|
|
||||||
<end-state name="end" />
|
<end-state name="end" />
|
||||||
|
|
||||||
|
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* 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.model.ContentModel;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
|
import org.alfresco.repo.site.SiteInfo;
|
||||||
|
import org.alfresco.repo.site.SiteService;
|
||||||
|
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||||
|
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.JSONObject;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit Test to test Invite Web Script API
|
||||||
|
*
|
||||||
|
* @author Glen Johnson at Alfresco dot com
|
||||||
|
*/
|
||||||
|
public class InviteServiceTest extends BaseWebScriptTest
|
||||||
|
{
|
||||||
|
private AuthenticationService authenticationService;
|
||||||
|
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 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");
|
||||||
|
|
||||||
|
// Create inviter user
|
||||||
|
createUser(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createUser(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());
|
||||||
|
|
||||||
|
// 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_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
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
JSONObject result = new JSONObject(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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user