- added webscript to get invite information for a given id and ticket

- invite response webscript now uses correct api and put/delete method and only requires invite id and ticket
- improved invite accept/reject pages ui, correct handling in case the invite has already been canceled
- fixed buggy digit-only usernames handling in memberships webscript
- slightly changed comment activities wording

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10506 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Michael Ru
2008-08-22 19:58:31 +00:00
parent ad30bbbbbe
commit 03a08a20f9
23 changed files with 440 additions and 284 deletions

View File

@@ -3,12 +3,12 @@
<#assign username = firstName + " " + lastName> <#assign username = firstName + " " + lastName>
</#if> </#if>
<entry xmlns='http://www.w3.org/2005/Atom'> <entry xmlns='http://www.w3.org/2005/Atom'>
<title>New comment for ${(itemTitle!'')?html?xml}</title> <title>${username?html?xml} commented on ${(itemTitle!'')?html?xml}</title>
<link rel="alternate" type="text/html" href="${(browsePostUrl!'')?xml}" /> <link rel="alternate" type="text/html" href="${(browsePostUrl!'')?xml}" />
<id>${id}</id> <id>${id}</id>
<updated>${xmldate(date)}</updated> <updated>${xmldate(date)}</updated>
<summary type="html"> <summary type="html">
<![CDATA[${username} added a comment to <a href="${(browseItemUrl!'')}">${(itemTitle!'unknown')?html}</a>]]> <![CDATA[${username} commented on <a href="${(browseItemUrl!'')}">${(itemTitle!'unknown')?html}</a>]]>
</summary> </summary>
<author> <author>
<name>${userId!""}</name> <name>${userId!""}</name>

View File

@@ -3,12 +3,12 @@
<#assign username = firstName + " " + lastName> <#assign username = firstName + " " + lastName>
</#if> </#if>
<entry xmlns='http://www.w3.org/2005/Atom'> <entry xmlns='http://www.w3.org/2005/Atom'>
<title>Comment deleted</title> <title>${username} deleted comment</title>
<link rel="alternate" type="text/html" href="${(browsePostListUrl!'')?xml}" /> <link rel="alternate" type="text/html" href="${(browsePostListUrl!'')?xml}" />
<id>${id}</id> <id>${id}</id>
<updated>${xmldate(date)}</updated> <updated>${xmldate(date)}</updated>
<summary type="html"> <summary type="html">
<![CDATA[${username} deleted comment on <a href="${(browseItemUrl!'')}">${(itemTitle!'unknown')?html}</a>]]> <![CDATA[${username?html} deleted comment on <a href="${(browseItemUrl!'')}">${(itemTitle!'unknown')?html}</a>]]>
</summary> </summary>
<author> <author>
<name>${userId!""}</name> <name>${userId!""}</name>

View File

@@ -3,12 +3,12 @@
<#assign username = firstName + " " + lastName> <#assign username = firstName + " " + lastName>
</#if> </#if>
<entry xmlns='http://www.w3.org/2005/Atom'> <entry xmlns='http://www.w3.org/2005/Atom'>
<title>Comment updated</title> <title>${username?html?xml} updated comment</title>
<link rel="alternate" type="text/html" href="${(browsePostUrl!'')?xml}" /> <link rel="alternate" type="text/html" href="${(browsePostUrl!'')?xml}" />
<id>${id}</id> <id>${id}</id>
<updated>${xmldate(date)}</updated> <updated>${xmldate(date)}</updated>
<summary type="html"> <summary type="html">
<![CDATA[${username} updated comment on <a href="${(browseItemUrl!'')}">${(itemTitle!'unknown')?html}</a>]]> <![CDATA[${username?html} updated comment on <a href="${(browseItemUrl!'')}">${(itemTitle!'unknown')?html}</a>]]>
</summary> </summary>
<author> <author>
<name>${userId!""}</name> <name>${userId!""}</name>

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Invite by ticket</shortname>
<description>Returns invite information for a given inviteId and inviteTicket. No authentication is required</description>
<url>/api/invite/{inviteId}/{inviteTicket}</url>
<format default="json"/>
<authentication>none</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,4 @@
<#import "invite.lib.ftl" as inviteLib/>
{
"invite" : <@inviteLib.inviteJSON invite=invite/>
}

View File

@@ -3,6 +3,9 @@
<#if inviteId??> <#if inviteId??>
"inviteId" : "${inviteId}", "inviteId" : "${inviteId}",
</#if> </#if>
<#if inviteTicket??>
"inviteTicket" : "${inviteTicket}",
</#if>
<#if inviteeUserName??> <#if inviteeUserName??>
"inviteeUserName" : "${inviteeUserName}", "inviteeUserName" : "${inviteeUserName}",
</#if> </#if>

View File

@@ -32,7 +32,12 @@
}, },
</#if> </#if>
"role" : "${invite.role}", "role" : "${invite.role}",
"siteShortName" : "${invite.siteShortName!''}", "site" : {
"shortName" : "${invite.siteShortName!''}"
<#if invite.siteInfo??>
, "title" : "${invite.siteInfo.title}"
</#if>
},
"invitationStatus" : "${invite.invitationStatus}", "invitationStatus" : "${invite.invitationStatus}",
"sentInviteDate" : "${invite.sentInviteDate?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}" "sentInviteDate" : "${invite.sentInviteDate?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}"
} }

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Invite reject</shortname>
<description>Rejects an invite</description>
<url>/api/invite/{inviteId}/{inviteTicket}</url>
<format default="json"/>
<authentication>none</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -1,8 +0,0 @@
<webscript>
<shortname>Invite Response</shortname>
<description>Processes invite response from Invitee ({response} is either 'accept' or 'reject' )</description>
<url>/api/inviteresponse/{response}?inviteId={inviteId}&amp;inviteeUserName={inviteeUserName}&amp;siteShortName={siteShortName}</url>
<format default="json"/>
<authentication>none</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -1,7 +0,0 @@
<#if response == "accept">
<p>Your acceptance to join site ${siteShortName} has been processed</p>
<#elseif response == "reject">
<p>Your rejection to join site ${siteShortName} has been processed</p>
<#else>
<p>Error: unknown invite response ${response}</p>
</#if>

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Invite accept</shortname>
<description>Accepts an invite</description>
<url>/api/invite/{inviteId}/{inviteTicket}</url>
<format default="json"/>
<authentication>none</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -0,0 +1,4 @@
{
"response" : "${response}",
"siteShortName" : "${siteShortName}"
}

View File

@@ -16,11 +16,13 @@ for (userName in memberships)
} }
// also copy over the memberships. // also copy over the memberships.
var mems = []; var mems = {};
var pos = 0; // memberships[userName] won't return the correct value if userName is a digit-only value
for (userName in memberships) for (userName in memberships)
{ {
var membershipType = memberships[userName]; var membershipType = memberships[pos];
mems["_" + userName] = membershipType; // make sure the keys are strings mems["_" + userName] = membershipType; // make sure the keys are strings
pos++;
} }
// Pass the information to the template // Pass the information to the template

View File

@@ -294,7 +294,6 @@
<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="namespaceService" ref="NamespaceService"/>
<property name="siteService" ref="SiteService"/> <property name="siteService" ref="SiteService"/>
<property name="nodeService" ref="NodeService"/> <property name="nodeService" ref="NodeService"/>
<property name="userNameGenerator" ref="userNameGenerator"/> <property name="userNameGenerator" ref="userNameGenerator"/>
@@ -302,18 +301,29 @@
</bean> </bean>
<!-- --> <!-- -->
<!-- Invite Response Web Script - invoked by Invitee to either 'accept' an invitation from a --> <!-- Invite Accept Web Script - accepts a pending invite -->
<!-- Site Manager (Inviter), or to reject an invitation that has already been sent out -->
<!-- --> <!-- -->
<bean id="webscript.org.alfresco.repository.invite.inviteresponse.get" <bean id="webscript.org.alfresco.repository.invite.inviteresponse.put"
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>
<!-- -->
<!-- Invite Reject Web Script - rejects a pending invite -->
<!-- -->
<bean id="webscript.org.alfresco.repository.invite.inviteresponse.delete"
class="org.alfresco.repo.web.scripts.invite.InviteResponse" class="org.alfresco.repo.web.scripts.invite.InviteResponse"
parent="webscript"> parent="webscript">
<property name="workflowService" ref="workflowServiceImpl"/> <property name="workflowService" ref="workflowServiceImpl"/>
<property name="mutableAuthenticationDao" ref="authenticationDao"/> <property name="mutableAuthenticationDao" ref="authenticationDao"/>
<property name="siteService" ref="siteService"/> <property name="siteService" ref="siteService"/>
<property name="personService" ref="personService"/> <property name="personService" ref="personService"/>
<property name="namespaceService" ref="namespaceService"/>
</bean> </bean>
<!-- --> <!-- -->
@@ -326,11 +336,22 @@
class="org.alfresco.repo.web.scripts.invite.Invites" class="org.alfresco.repo.web.scripts.invite.Invites"
parent="webscript"> parent="webscript">
<property name="workflowService" ref="WorkflowService"/> <property name="workflowService" ref="WorkflowService"/>
<property name="namespaceService" ref="NamespaceService"/>
<property name="personService" ref="PersonService"/>
<property name="serviceRegistry" ref="ServiceRegistry"/> <property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="siteService" ref="SiteService"/>
</bean> </bean>
<!-- -->
<!-- Returns invite information when for a given inviteId and inviteTicket -->
<!-- This webscript is accessible without authentication -->
<!-- -->
<bean id="webscript.org.alfresco.repository.invite.invite-by-ticket.get"
class="org.alfresco.repo.web.scripts.invite.InviteByTicket"
parent="webscript">
<property name="workflowService" ref="WorkflowService"/>
<property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="siteService" ref="SiteService"/>
</bean>
<!-- --> <!-- -->

View File

@@ -45,9 +45,6 @@ import org.alfresco.service.cmr.workflow.WorkflowDefinition;
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.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.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.alfresco.web.scripts.DeclarativeWebScript; import org.alfresco.web.scripts.DeclarativeWebScript;
@@ -67,10 +64,10 @@ public class Invite extends DeclarativeWebScript
{ {
private static final String ACTION_START = "start"; private static final String ACTION_START = "start";
private static final String ACTION_CANCEL = "cancel"; private static final String ACTION_CANCEL = "cancel";
private static final String TRANSITION_SEND_INVITE = "sendInvite";
private static final String MODEL_PROP_KEY_ACTION = "action"; private static final String MODEL_PROP_KEY_ACTION = "action";
private static final String MODEL_PROP_KEY_INVITE_ID = "inviteId"; private static final String MODEL_PROP_KEY_INVITE_ID = "inviteId";
private static final String MODEL_PROP_KEY_INVITE_TICKET = "inviteTicket";
private static final String MODEL_PROP_KEY_INVITEE_USER_NAME = "inviteeUserName"; private static final String MODEL_PROP_KEY_INVITEE_USER_NAME = "inviteeUserName";
private static final String MODEL_PROP_KEY_INVITEE_FIRSTNAME = "inviteeFirstName"; private static final String MODEL_PROP_KEY_INVITEE_FIRSTNAME = "inviteeFirstName";
private static final String MODEL_PROP_KEY_INVITEE_LASTNAME = "inviteeLastName"; private static final String MODEL_PROP_KEY_INVITEE_LASTNAME = "inviteeLastName";
@@ -93,7 +90,6 @@ public class Invite extends DeclarativeWebScript
private PersonService personService; private PersonService personService;
private AuthenticationService authenticationService; private AuthenticationService authenticationService;
private MutableAuthenticationDao mutableAuthenticationDao; private MutableAuthenticationDao mutableAuthenticationDao;
private NamespaceService namespaceService;
private SiteService siteService; private SiteService siteService;
private NodeService nodeService; private NodeService nodeService;
@@ -101,23 +97,6 @@ public class Invite extends DeclarativeWebScript
private UserNameGenerator usernameGenerator; private UserNameGenerator usernameGenerator;
private PasswordGenerator passwordGenerator; private PasswordGenerator passwordGenerator;
// workflow properties
public static final String WF_PROP_SERVER_PATH = "wf:serverPath";
public static final String WF_PROP_ACCEPT_URL = "wf:acceptUrl";
public static final String WF_PROP_REJECT_URL = "wf:rejectUrl";
public static final String WF_PROP_INVITE_TICKET = "wf:inviteTicket";
public static final String WF_PROP_INVITER_USER_NAME = "wf:inviterUserName";
public static final String WF_PROP_INVITEE_USER_NAME = "wf:inviteeUserName";
public static final String WF_PROP_INVITEE_FIRSTNAME = "wf:inviteeFirstName";
public static final String WF_PROP_INVITEE_LASTNAME = "wf:inviteeLastName";
public static final String WF_PROP_SITE_SHORT_NAME = "wf:siteShortName";
public static final String WF_PROP_INVITEE_SITE_ROLE = "wf:inviteeSiteRole";
public static final String WF_PROP_SENT_INVITE_DATE = "wf:sentInviteDate";
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";
// maximum number of tries to generate a invitee user name which // maximum number of tries to generate a invitee user name which
// does not already belong to an existing person // does not already belong to an existing person
public static final int MAX_NUM_INVITEE_USER_NAME_GEN_TRIES = 10; public static final int MAX_NUM_INVITEE_USER_NAME_GEN_TRIES = 10;
@@ -168,17 +147,6 @@ public class Invite extends DeclarativeWebScript
this.mutableAuthenticationDao = mutableAuthenticationDao; this.mutableAuthenticationDao = mutableAuthenticationDao;
} }
/**
* Set the namespace service
*
* @param namespaceService the namespace service to set
*/
public void setNamespaceService(
NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/** /**
* Set the user name generator service * Set the user name generator service
* *
@@ -454,7 +422,7 @@ public class Invite extends DeclarativeWebScript
* @param siteShortName * @param siteShortName
* @return whether there is an invite in progress * @return whether there is an invite in progress
*/ */
private boolean isInviteAlreadyInProgress(String inviteeUserName, String siteShortName) /*private boolean isInviteAlreadyInProgress(String inviteeUserName, String siteShortName)
{ {
// create workflow task query // create workflow task query
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery(); WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
@@ -462,16 +430,15 @@ public class Invite extends DeclarativeWebScript
// set query properties to look up task instances of inviteToSite task // set query properties to look up task instances of inviteToSite task
// in active invite workflow instances // in active invite workflow instances
wfTaskQuery.setActive(Boolean.TRUE); wfTaskQuery.setActive(Boolean.TRUE);
wfTaskQuery.setProcessName(QName.createQName("wf:invite", this.namespaceService)); wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED); wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED);
wfTaskQuery.setTaskName(QName.createQName(Invite.WF_INVITE_TASK_INVITE_TO_SITE, wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_TO_SITE);
this.namespaceService));
// set query process custom properties // set query process custom properties
HashMap<QName, Object> wfQueryProps = new HashMap<QName, Object>(2, 1.0f); HashMap<QName, Object> wfQueryProps = new HashMap<QName, Object>(2, 1.0f);
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITEE_USER_NAME, this.namespaceService), wfQueryProps.put(InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME,
inviteeUserName); inviteeUserName);
wfQueryProps.put(QName.createQName(Invite.WF_PROP_SITE_SHORT_NAME, this.namespaceService), wfQueryProps.put(InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME,
siteShortName); siteShortName);
wfTaskQuery.setTaskCustomProps(wfQueryProps); wfTaskQuery.setTaskCustomProps(wfQueryProps);
@@ -483,7 +450,7 @@ public class Invite extends DeclarativeWebScript
// throw web script exception if person (having the given invitee email address) already // throw web script exception if person (having the given invitee email address) already
// has an invitation in progress for the given site short name // has an invitation in progress for the given site short name
return (inviteTasksInProgress.size() > 0); return (inviteTasksInProgress.size() > 0);
} }*/
/** /**
* Starts the Invite workflow * Starts the Invite workflow
@@ -585,40 +552,40 @@ public class Invite extends DeclarativeWebScript
// //
WorkflowDefinition wfDefinition = this.workflowService WorkflowDefinition wfDefinition = this.workflowService
.getDefinitionByName(WORKFLOW_DEFINITION_NAME); .getDefinitionByName(InviteWorkflowModel.WORKFLOW_DEFINITION_NAME);
// handle workflow definition does not exist // handle workflow definition does not exist
if (wfDefinition == null) if (wfDefinition == null)
{ {
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"Workflow definition " + "for name " "Workflow definition " + "for name "
+ WORKFLOW_DEFINITION_NAME + " does not exist"); + InviteWorkflowModel.WORKFLOW_DEFINITION_NAME + " does not exist");
} }
// create workflow properties // create workflow properties
Map<QName, Serializable> workflowProps = new HashMap<QName, Serializable>( Map<QName, Serializable> workflowProps = new HashMap<QName, Serializable>(
7); 7);
workflowProps.put(QName.createQName(WF_PROP_INVITER_USER_NAME, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITER_USER_NAME,
inviterUserName); inviterUserName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_USER_NAME, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME,
inviteeUserName); inviteeUserName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_FIRSTNAME, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_FIRSTNAME,
inviteeFirstName); inviteeFirstName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_LASTNAME, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_LASTNAME,
inviteeLastName); inviteeLastName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_GEN_PASSWORD, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_GEN_PASSWORD,
inviteePassword); inviteePassword);
workflowProps.put(QName.createQName(WF_PROP_SITE_SHORT_NAME, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME,
siteShortName); siteShortName);
workflowProps.put(QName.createQName(WF_PROP_INVITEE_SITE_ROLE, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_SITE_ROLE,
inviteeSiteRole); inviteeSiteRole);
workflowProps.put(QName.createQName(WF_PROP_SERVER_PATH, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_SERVER_PATH,
serverPath); serverPath);
workflowProps.put(QName.createQName(WF_PROP_ACCEPT_URL, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_ACCEPT_URL,
acceptUrl); acceptUrl);
workflowProps.put(QName.createQName(WF_PROP_REJECT_URL, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_REJECT_URL,
rejectUrl); rejectUrl);
workflowProps.put(QName.createQName(WF_PROP_INVITE_TICKET, this.namespaceService), workflowProps.put(InviteWorkflowModel.WF_PROP_INVITE_TICKET,
inviteTicket); inviteTicket);
// start the workflow // start the workflow
@@ -644,11 +611,11 @@ public class Invite extends DeclarativeWebScript
// first task in workflow task list associated with the workflow path id above // first task in workflow task list associated with the workflow path id above
// should be "wf:inviteToSiteTask", otherwise throw web script exception // should be "wf:inviteToSiteTask", otherwise throw web script exception
String wfTaskTitle = wfTasks.get(0).title; String wfTaskTitle = wfTasks.get(0).title;
if (!wfTaskTitle.equals(WF_INVITE_TASK_INVITE_TO_SITE)) if (!wfTaskTitle.equals("wf:inviteToSiteTask"))
{ {
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"First workflow task found on workflow path ID: " + wfPathId "First workflow task found on workflow path ID: " + wfPathId
+ " should be " + WF_INVITE_TASK_INVITE_TO_SITE); + " should be " + "wf:inviteToSiteTask");
} }
// get "inviteToSite" task // get "inviteToSite" task
@@ -660,11 +627,12 @@ public class Invite extends DeclarativeWebScript
Map<QName, Serializable> wfTaskProps = new HashMap<QName, Serializable>(1, 1.0f); Map<QName, Serializable> wfTaskProps = new HashMap<QName, Serializable>(1, 1.0f);
wfTaskProps.put(WorkflowModel.ASSOC_PACKAGE, wfPackage); wfTaskProps.put(WorkflowModel.ASSOC_PACKAGE, wfPackage);
this.workflowService.updateTask(wfStartTask.id, wfTaskProps, null, null); this.workflowService.updateTask(wfStartTask.id, wfTaskProps, null, null);
this.workflowService.endTask(wfStartTask.id, TRANSITION_SEND_INVITE); this.workflowService.endTask(wfStartTask.id, InviteWorkflowModel.WF_TRANSITION_SEND_INVITE);
// add model properties for template to render // add model properties for template to render
model.put(MODEL_PROP_KEY_ACTION, ACTION_START); model.put(MODEL_PROP_KEY_ACTION, ACTION_START);
model.put(MODEL_PROP_KEY_INVITE_ID, workflowId); model.put(MODEL_PROP_KEY_INVITE_ID, workflowId);
model.put(MODEL_PROP_KEY_INVITE_TICKET, inviteTicket);
model.put(MODEL_PROP_KEY_INVITEE_USER_NAME, inviteeUserName); model.put(MODEL_PROP_KEY_INVITEE_USER_NAME, inviteeUserName);
model.put(MODEL_PROP_KEY_INVITEE_FIRSTNAME, inviteeFirstName); model.put(MODEL_PROP_KEY_INVITEE_FIRSTNAME, inviteeFirstName);
model.put(MODEL_PROP_KEY_INVITEE_LASTNAME, inviteeLastName); model.put(MODEL_PROP_KEY_INVITEE_LASTNAME, inviteeLastName);

View File

@@ -0,0 +1,126 @@
/*
* 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 java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.Status;
import org.alfresco.web.scripts.WebScriptException;
import org.alfresco.web.scripts.WebScriptRequest;
/**
* Web Script which returns invite information given an inviteId and inviteTicket.
*
* Note: This Web Script is accessible without authentication.
*
* @author glen dot johnson at alfresco dot com
*/
public class InviteByTicket extends DeclarativeWebScript
{
// service instances
private WorkflowService workflowService;
private ServiceRegistry serviceRegistry;
private SiteService siteService;
/**
* Set the workflow service property
*
* @param workflowService
* the workflow service to set
*/
public void setWorkflowService(WorkflowService workflowService)
{
this.workflowService = workflowService;
}
public void setServiceRegistry(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
public void setSiteService(SiteService siteService) {
this.siteService = siteService;
}
/*
* (non-Javadoc)
*
* @see
* org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco
* .web.scripts.WebScriptRequest,
* org.alfresco.web.scripts.WebScriptResponse)
*/
@Override
protected Map<String, Object> executeImpl(WebScriptRequest req,
Status status)
{
// initialise model to pass on for template to render
Map<String, Object> model = new HashMap<String, Object>();
// Extract inviteId and inviteTicket
String extPath = req.getExtensionPath();
int separatorIndex = extPath.indexOf('/');
if (separatorIndex < 0)
{
// should not happen as descriptor would not match
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"Parameters missing");
}
String inviteId = extPath.substring(0, separatorIndex);
String inviteTicket = extPath.substring(separatorIndex + 1);
// authenticate as system for the rest of the webscript
AuthenticationUtil.setSystemUserAsCurrentUser();
// find the workflow for the given id
WorkflowTask workflowTask = InviteHelper.findInviteStartTask(inviteId, workflowService);
if (workflowTask == null)
{
throw new WebScriptException(Status.STATUS_NOT_FOUND,
"No invite found for given id");
}
// check whether tickets match, throw error otherwise
String ticket = (String) workflowTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITE_TICKET);
if (ticket == null || (! ticket.equals(inviteTicket)))
{
throw new WebScriptException(Status.STATUS_NOT_FOUND,
"Ticket mismatch");
}
// return the invite info
InviteInfo inviteInfo = InviteHelper.getPendingInviteInfo(workflowTask, serviceRegistry, siteService);
model.put("invite", inviteInfo);
return model;
}
}

View File

@@ -24,8 +24,15 @@
*/ */
package org.alfresco.repo.web.scripts.invite; package org.alfresco.repo.web.scripts.invite;
import java.util.Date;
import java.util.List; import java.util.List;
import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
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.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery; import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
@@ -40,21 +47,11 @@ import org.alfresco.service.namespace.QName;
public class InviteHelper public class InviteHelper
{ {
/** /**
* Gets the invitee site role from the invite * Find an invite start task given the task id.
* workflow instance associated with the given invite ID.
* i.e. if the inviter 'starts' an invite (which is allocated some invite ID
* '12345' when it is processed), and that invite is requesting an invitee to
* to join some site under a given site role, then that site role is returned
* by this method when invite ID '12345' is passed in.
* *
* @param inviteId the ID of the invitation (invite workflow instance) * @return a WorkflowTask or null if not found.
* from which to retrieve the invitee site role
* @return the site role under which the invitee was invited to
* join the site. Returns <pre>null</pre> if no invite
* workflow instance was found matching the given invite ID
*/ */
static String getInviteeSiteRoleFromInvite(String inviteId, WorkflowService workflowService, public static WorkflowTask findInviteStartTask(String inviteId, WorkflowService workflowService)
NamespaceService namespaceService)
{ {
// create workflow task query // create workflow task query
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery(); WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
@@ -63,33 +60,83 @@ 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("wf:invite", namespaceService)); wfTaskQuery.setProcessName(QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invite"));
// pick up the start task because it has the "wf:inviteeSiteRole" property set with the // pick up the start task because it has the "wf:inviteeSiteRole" property set with the
// site role value that we want to retrieve // site role value that we want to retrieve
wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED); wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED);
wfTaskQuery.setTaskName(QName.createQName(Invite.WF_INVITE_TASK_INVITE_TO_SITE, namespaceService)); wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_TO_SITE);
// query for invite workflow task associate // query for invite workflow task associate
List<WorkflowTask> inviteStartTasks = workflowService List<WorkflowTask> inviteStartTasks = workflowService
.queryTasks(wfTaskQuery); .queryTasks(wfTaskQuery);
// if no results were returned for given inviteID, then return // should also be 0 or 1
// site role as null if (inviteStartTasks.size() < 1)
if (inviteStartTasks.size() == 0)
{ {
return null; return null;
} }
else else
{ {
// there should be only one start task returned for the given invite ID return inviteStartTasks.get(0);
// so just take the first one in the list
WorkflowTask inviteStartTask = inviteStartTasks.get(0);
String inviteeSiteRole = (String) inviteStartTask.properties.get(
QName.createQName(Invite.WF_PROP_INVITEE_SITE_ROLE, namespaceService));
return inviteeSiteRole;
} }
} }
/**
* Returns an InviteInfo object usable for rendering the response.
*
* @return object containing invite information
*/
public static InviteInfo getPendingInviteInfo(WorkflowTask workflowTask,
ServiceRegistry serviceRegistry, SiteService siteService)
{
PersonService personService = serviceRegistry.getPersonService();
// get the inviter, invitee, role and site short name
String inviterUserNameProp = (String) workflowTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITER_USER_NAME);
String inviteeUserNameProp = (String) workflowTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME);
String role = (String) workflowTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_SITE_ROLE);
String siteShortNameProp = (String) workflowTask.properties.get(
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
// fetch the site object
SiteInfo siteInfo = siteService.getSite(siteShortNameProp);
// get workflow instance id (associated with workflow task) to place
// as "inviteId" onto model
String workflowId = workflowTask.path.instance.id;
// set the invite start date to the time the workflow instance
// (associated with the task) was started
Date sentInviteDate = workflowTask.path.instance.startDate;
// TODO: glen johnson at alfresco com - as this web script only returns
// pending invites, this is hard coded to "pending" for now
String invitationStatus = InviteInfo.INVITATION_STATUS_PENDING;
// fetch the person node for the inviter
NodeRef inviterRef = personService.getPerson(inviterUserNameProp);
ScriptNode inviterPerson = null;
if (inviterRef != null)
{
inviterPerson = new ScriptNode(inviterRef, serviceRegistry);
}
// fetch the person node for the invitee
NodeRef inviteeRef = personService.getPerson(inviteeUserNameProp);
ScriptNode inviteePerson = null;
if (inviteeRef != null)
{
inviteePerson = new ScriptNode(inviteeRef, serviceRegistry);
}
// create and add InviteInfo to inviteInfoList
InviteInfo inviteInfo = new InviteInfo(invitationStatus, inviterUserNameProp, inviterPerson,
inviteeUserNameProp, inviteePerson, role, siteShortNameProp, siteInfo, sentInviteDate, workflowId);
return inviteInfo;
}
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.web.scripts.invite;
import java.util.Date; import java.util.Date;
import org.alfresco.repo.jscript.ScriptNode; import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.repo.site.SiteInfo;
/** /**
* Holds properties pertaining to an invitation that has been sent out by a Site Manager (Inviter) * Holds properties pertaining to an invitation that has been sent out by a Site Manager (Inviter)
@@ -36,6 +37,11 @@ import org.alfresco.repo.jscript.ScriptNode;
*/ */
public class InviteInfo public class InviteInfo
{ {
// invitation statuses
public static final String INVITATION_STATUS_PENDING = "pending";
public static final String INVITATION_STATUS_ACCEPTED = "accepted";
public static final String INVITATION_STATUS_REJECTED = "rejected";
// private instances to hold property values // private instances to hold property values
private String invitationStatus; private String invitationStatus;
private String inviterUserName; private String inviterUserName;
@@ -44,12 +50,13 @@ public class InviteInfo
private ScriptNode inviteePerson; private ScriptNode inviteePerson;
private String role; private String role;
private String siteShortName; private String siteShortName;
private SiteInfo siteInfo;
private Date sentInviteDate; private Date sentInviteDate;
private String inviteId; private String inviteId;
public InviteInfo(String invitationStatus, String inviterUserName, ScriptNode inviterPerson, public InviteInfo(String invitationStatus, String inviterUserName, ScriptNode inviterPerson,
String inviteeUserName, ScriptNode inviteePerson, String role, String inviteeUserName, ScriptNode inviteePerson, String role,
String siteShortName, Date sentInviteDate, String inviteId) String siteShortName, SiteInfo siteInfo, Date sentInviteDate, String inviteId)
{ {
this.invitationStatus = invitationStatus; this.invitationStatus = invitationStatus;
this.inviterUserName = inviterUserName; this.inviterUserName = inviterUserName;
@@ -58,6 +65,7 @@ public class InviteInfo
this.inviteePerson = inviteePerson; this.inviteePerson = inviteePerson;
this.role = role; this.role = role;
this.siteShortName = siteShortName; this.siteShortName = siteShortName;
this.siteInfo = siteInfo;
this.sentInviteDate = sentInviteDate; this.sentInviteDate = sentInviteDate;
this.inviteId = inviteId; this.inviteId = inviteId;
} }
@@ -151,4 +159,9 @@ public class InviteInfo
{ {
return role; return role;
} }
public SiteInfo getSiteInfo() {
return siteInfo;
}
} }

View File

@@ -37,7 +37,6 @@ 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.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; 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;
@@ -88,13 +87,6 @@ public class InviteResponse extends DeclarativeWebScript
private static final String RESPONSE_ACCEPT = "accept"; private static final String RESPONSE_ACCEPT = "accept";
private static final String RESPONSE_REJECT = "reject"; private static final String RESPONSE_REJECT = "reject";
private static final String WF_TASK_ACCEPT_INVITE = "wf:acceptInviteTask";
private static final String WF_TASK_REJECT_INVITE = "wf:rejectInviteTask";
private static final String WF_TASK_INVITE_PENDING = "wf:invitePendingTask";
private static final String WF_TRANSITION_ACCEPT = "accept";
private static final String WF_TRANSITION_REJECT = "reject";
private static final String WF_TRANSITION_ACCEPT_INVITE_END = "end";
private static final String WF_TRANSITION_REJECT_INVITE_END = "end";
private static final String MODEL_PROP_KEY_RESPONSE = "response"; private static final String MODEL_PROP_KEY_RESPONSE = "response";
private static final String MODEL_PROP_KEY_SITE_SHORT_NAME = "siteShortName"; private static final String MODEL_PROP_KEY_SITE_SHORT_NAME = "siteShortName";
private static final String USER_ADMIN = "admin"; private static final String USER_ADMIN = "admin";
@@ -104,7 +96,6 @@ public class InviteResponse extends DeclarativeWebScript
private MutableAuthenticationDao mutableAuthenticationDao; private MutableAuthenticationDao mutableAuthenticationDao;
private SiteService siteService; private SiteService siteService;
private PersonService personService; private PersonService personService;
private NamespaceService namespaceService;
/** /**
* Sets the workflow service property * Sets the workflow service property
@@ -151,17 +142,6 @@ public class InviteResponse extends DeclarativeWebScript
this.personService = personService; this.personService = personService;
} }
/**
* Sets the namespaceService property
*
* @param namespaceService
* the namespace service to set
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
@@ -177,57 +157,52 @@ public class InviteResponse extends DeclarativeWebScript
// initialise model to pass on for template to render // initialise model to pass on for template to render
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();
// get the URL parameter values // Extract inviteId and inviteTicket
String inviteId = req.getParameter("inviteId"); /*String extPath = req.getExtensionPath();
String inviteeUserName = req.getParameter("inviteeUserName"); int separatorIndex = extPath.indexOf('/');
String siteShortName = req.getParameter("siteShortName"); if (separatorIndex < 0)
{
// should not happen as descriptor would not match
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"Parameters missing");
}
String inviteId = extPath.substring(0, separatorIndex);
String inviteTicket = extPath.substring(separatorIndex + 1);*/
// get the invite response value String inviteId = req.getServiceMatch().getTemplateVars().get("inviteId");
String response = req.getExtensionPath(); String inviteTicket = req.getServiceMatch().getTemplateVars().get("inviteTicket");
// check that response has been provided // fetch the start task - it might not exist if the workflow has been finished/canceled already
if ((response == null) || (response.length() == 0)) WorkflowTask inviteStartTask = InviteHelper.findInviteStartTask(inviteId, workflowService);
if (inviteStartTask == null)
{ {
// handle response not provided throw new WebScriptException(Status.STATUS_NOT_FOUND,
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "No invite workflow for given id found");
"response has not been provided as part of URL.");
} }
// check that invite id URL parameter has been provided
else if ((inviteId == null) || (inviteId.length() == 0)) // check the ticket for a match
String ticket = (String) inviteStartTask.properties.get(InviteWorkflowModel.WF_PROP_INVITE_TICKET);
if (ticket == null || (! ticket.equals(inviteTicket)))
{ {
// handle invite id not provided throw new WebScriptException(Status.STATUS_NOT_FOUND,
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Invalid ticket");
"invite id parameter has not been provided in the URL.");
} }
// check that inviteeUserName URL parameter has been provided
else if ((inviteeUserName == null) || (inviteeUserName.length() == 0))
{
// handle inviteeUserName not provided
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"inviteeUserName parameter has not been provided in the URL.");
}
// check that siteShortName URL parameter has been provided
else if ((siteShortName == null) || (siteShortName.length() == 0))
{
// handle siteShortName not provided
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"siteShortName parameter has not been provided in the URL.");
} else
{
// process response // process response
if (response.equals(RESPONSE_ACCEPT)) String method = req.getServiceMatch().getWebScript().getDescription().getMethod();
if (method.equals("PUT"))
{ {
acceptInvite(model, inviteId, inviteeUserName, siteShortName); acceptInvite(model, inviteId, inviteStartTask);
} else if (response.equals(RESPONSE_REJECT))
{
rejectInvite(model, inviteId, inviteeUserName, siteShortName);
} else
{
/* handle unrecognised response */
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"response, " + response
+ ", provided in URL has not been recognised.");
} }
else if (method.equals("DELETE"))
{
rejectInvite(model, inviteId, inviteStartTask);
}
else
{
/* handle unrecognised method */
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"method " + method + " is not supported by this webscript.");
} }
return model; return model;
@@ -241,17 +216,19 @@ public class InviteResponse extends DeclarativeWebScript
* for rendering * for rendering
* @param inviteId * @param inviteId
* ID of invite * ID of invite
* @param inviteeUserName * @param inviteStartTask
* user name of invitee
* @param siteShortName
* short name of site for which invitee is accepting
* invitation to join
*/ */
private void acceptInvite(Map<String, Object> model, String inviteId, private void acceptInvite(Map<String, Object> model, String inviteId, WorkflowTask inviteStartTask)
String inviteeUserName, String siteShortName)
{ {
String inviteeUserName = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME);
String siteShortName = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
String inviteeSiteRole = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_SITE_ROLE);
// complete the wf:invitePendingTask task because the invitation has been accepted // complete the wf:invitePendingTask task because the invitation has been accepted
completeInviteTask(inviteId, QName.createQName(WF_TASK_INVITE_PENDING, this.namespaceService), WF_TRANSITION_ACCEPT); completeInviteTask(inviteId, InviteWorkflowModel.WF_TASK_INVITE_PENDING, InviteWorkflowModel.WF_TRANSITION_ACCEPT);
// TODO glen dot johnson at alfresco dot com - farm the code that follows (up until adding properties onto // TODO glen dot johnson at alfresco dot com - farm the code that follows (up until adding properties onto
// the model) out into workflow action class that gets run when task wf:acceptInviteTask // the model) out into workflow action class that gets run when task wf:acceptInviteTask
@@ -266,10 +243,6 @@ public class InviteResponse extends DeclarativeWebScript
this.mutableAuthenticationDao.setEnabled(inviteeUserName, true); this.mutableAuthenticationDao.setEnabled(inviteeUserName, true);
} }
// retrieve the site role with which the invitee was invited to the site
String inviteeSiteRole = InviteHelper.getInviteeSiteRoleFromInvite(inviteId, this.workflowService,
this.namespaceService);
// add Invitee to Site with the site role that the inviter "started" the invite process with // add Invitee to Site with the site role that the inviter "started" the invite process with
RunAsWork<Boolean> setSiteMembershipWorker = new InviteResponse.SetSiteMembershipWorker( RunAsWork<Boolean> setSiteMembershipWorker = new InviteResponse.SetSiteMembershipWorker(
siteShortName, inviteeUserName, inviteeSiteRole); siteShortName, inviteeUserName, inviteeSiteRole);
@@ -280,7 +253,7 @@ public class InviteResponse extends DeclarativeWebScript
// starting from above where wf:invitePendingTask is completed, up to here). This code // starting from above where wf:invitePendingTask is completed, up to here). This code
// block will soon be farmed out into a workflow action which gets executed when // block will soon be farmed out into a workflow action which gets executed when
// wf:acceptInviteTask gets completed // wf:acceptInviteTask gets completed
completeInviteTask(inviteId, QName.createQName(WF_TASK_ACCEPT_INVITE, this.namespaceService), WF_TRANSITION_ACCEPT_INVITE_END); completeInviteTask(inviteId, InviteWorkflowModel.WF_TASK_ACCEPT_INVITE, InviteWorkflowModel.WF_TRANSITION_ACCEPT_INVITE_END);
// 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);
@@ -301,11 +274,15 @@ public class InviteResponse extends DeclarativeWebScript
* short name of site for which invitee is rejecting * short name of site for which invitee is rejecting
* invitation to join * invitation to join
*/ */
private void rejectInvite(Map<String, Object> model, String inviteId, private void rejectInvite(Map<String, Object> model, String inviteId, WorkflowTask inviteStartTask)
String inviteeUserName, String siteShortName)
{ {
String inviteeUserName = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME);
String siteShortName = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
// complete the wf:invitePendingTask task because the invitation has been accepted // complete the wf:invitePendingTask task because the invitation has been accepted
completeInviteTask(inviteId, QName.createQName(WF_TASK_INVITE_PENDING, this.namespaceService), WF_TRANSITION_REJECT); completeInviteTask(inviteId, InviteWorkflowModel.WF_TASK_INVITE_PENDING, InviteWorkflowModel.WF_TRANSITION_REJECT);
// TODO glen dot johnson at alfresco dot com - farm the code that follows (up until adding properties onto // TODO glen dot johnson at alfresco dot com - farm the code that follows (up until adding properties onto
// the model) out into workflow action class that gets run when task wf:rejectInviteTask // the model) out into workflow action class that gets run when task wf:rejectInviteTask
@@ -331,7 +308,7 @@ public class InviteResponse extends DeclarativeWebScript
// starting from above where wf:invitePendingTask is completed, up to here). This code // starting from above where wf:invitePendingTask is completed, up to here). This code
// block will soon be farmed out into a workflow action which gets executed when // block will soon be farmed out into a workflow action which gets executed when
// wf:rejectInviteTask gets completed // wf:rejectInviteTask gets completed
completeInviteTask(inviteId, QName.createQName(WF_TASK_REJECT_INVITE, this.namespaceService), WF_TRANSITION_REJECT_INVITE_END); completeInviteTask(inviteId, InviteWorkflowModel.WF_TASK_REJECT_INVITE, InviteWorkflowModel.WF_TRANSITION_REJECT_INVITE_END);
// 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);
@@ -364,7 +341,7 @@ public class InviteResponse extends DeclarativeWebScript
// set process name to "wf:invite" so that only // set process name to "wf:invite" so that only
// invite workflow instances are considered by this query // invite workflow instances are considered by this query
wfTaskQuery.setProcessName(QName.createQName("wf:invite", this.namespaceService)); wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
// query for invite workflow tasks with the constructed query // query for invite workflow tasks with the constructed query
List<WorkflowTask> wf_invite_tasks = this.workflowService List<WorkflowTask> wf_invite_tasks = this.workflowService

View File

@@ -494,18 +494,16 @@ public class InviteServiceTest extends BaseWebScriptTest
// get hold of invite ID of started invite // get hold of invite ID of started invite
String inviteId = result.getString("inviteId"); String inviteId = result.getString("inviteId");
String inviteTicket = result.getString("inviteTicket");
// get hold of invitee user name that was generated as part of starting // get hold of invitee user name that was generated as part of starting
// the invite // the invite
String inviteeUserName = result.getString("inviteeUserName"); String inviteeUserName = result.getString("inviteeUserName");
// Invitee accepts invitation to a Site from Inviter // Invitee accepts invitation to a Site from Inviter
String acceptInviteUrl = URL_INVITERSP_SERVICE + "/" String acceptInviteUrl = URL_INVITE_SERVICE + "/" + inviteId + "/" + inviteTicket;
+ INVITE_RSP_ACCEPT + "?inviteId=" + inviteId MockHttpServletResponse response = putRequest(acceptInviteUrl,
+ "&inviteeUserName=" + inviteeUserName + "&siteShortName=" Status.STATUS_OK, null, null);
+ SITE_SHORT_NAME_INVITE_1;
MockHttpServletResponse response = getRequest(acceptInviteUrl,
Status.STATUS_OK);
// //
// test that invitation represented by invite ID (of invitation started // test that invitation represented by invite ID (of invitation started
@@ -530,17 +528,15 @@ public class InviteServiceTest extends BaseWebScriptTest
// get hold of invite ID of started invite // get hold of invite ID of started invite
String inviteId = result.getString("inviteId"); String inviteId = result.getString("inviteId");
String inviteTicket = result.getString("inviteTicket");
// get hold of invitee user name that was generated as part of starting // get hold of invitee user name that was generated as part of starting
// the invite // the invite
String inviteeUserName = result.getString("inviteeUserName"); String inviteeUserName = result.getString("inviteeUserName");
// Invitee rejects invitation to a Site from Inviter // Invitee rejects invitation to a Site from Inviter
String rejectInviteUrl = URL_INVITERSP_SERVICE + "/" String rejectInviteUrl = URL_INVITE_SERVICE + "/" + inviteId + "/" + inviteTicket;
+ INVITE_RSP_REJECT + "?inviteId=" + inviteId MockHttpServletResponse response = deleteRequest(rejectInviteUrl,
+ "&inviteeUserName=" + inviteeUserName + "&siteShortName="
+ SITE_SHORT_NAME_INVITE_1;
MockHttpServletResponse response = getRequest(rejectInviteUrl,
Status.STATUS_OK); Status.STATUS_OK);
// //
@@ -646,6 +642,6 @@ public class InviteServiceTest extends BaseWebScriptTest
JSONObject inviteJSONObj = getInvitesResult.getJSONArray("invites").getJSONObject(0); JSONObject inviteJSONObj = getInvitesResult.getJSONArray("invites").getJSONObject(0);
assertEquals(siteShortName, inviteJSONObj.get("siteShortName")); assertEquals(siteShortName, inviteJSONObj.getJSONObject("site").get("shortName"));
} }
} }

View File

@@ -0,0 +1,42 @@
package org.alfresco.repo.web.scripts.invite;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
public interface InviteWorkflowModel {
// process name
public static final QName WF_PROCESS_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invite");
// workflow definition name
public static final String WORKFLOW_DEFINITION_NAME = "jbpm$wf:invite";
// tasks
public static final QName WF_INVITE_TASK_INVITE_TO_SITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteToSiteTask");
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_INVITE_PENDING = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invitePendingTask");
// transition names
public static final String WF_TRANSITION_SEND_INVITE = "sendInvite";
public static final String WF_TRANSITION_ACCEPT = "accept";
public static final String WF_TRANSITION_REJECT = "reject";
public static final String WF_TRANSITION_ACCEPT_INVITE_END = "end";
public static final String WF_TRANSITION_REJECT_INVITE_END = "end";
// workflow properties
public static final QName WF_PROP_SERVER_PATH = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "serverPath");
public static final QName WF_PROP_ACCEPT_URL = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "acceptUrl");
public static final QName WF_PROP_REJECT_URL = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "rejectUrl");
public static final QName WF_PROP_INVITE_TICKET = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteTicket");
public static final QName WF_PROP_INVITER_USER_NAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviterUserName");
public static final QName WF_PROP_INVITEE_USER_NAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeUserName");
public static final QName WF_PROP_INVITEE_FIRSTNAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeFirstName");
public static final QName WF_PROP_INVITEE_LASTNAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeLastName");
public static final QName WF_PROP_SITE_SHORT_NAME = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "siteShortName");
public static final QName WF_PROP_INVITEE_SITE_ROLE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "inviteeSiteRole");
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");
}

View File

@@ -25,20 +25,16 @@
package org.alfresco.repo.web.scripts.invite; package org.alfresco.repo.web.scripts.invite;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.jscript.ScriptNode; import org.alfresco.repo.site.SiteService;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
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.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery; import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; 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;
@@ -77,16 +73,10 @@ public class Invites extends DeclarativeWebScript
// model key names // model key names
private static final String MODEL_KEY_NAME_INVITES = "invites"; private static final String MODEL_KEY_NAME_INVITES = "invites";
// invitation statuses
private static final String INVITATION_STATUS_PENDING = "pending";
private static final String INVITATION_STATUS_ACCEPTED = "accepted";
private static final String INVITATION_STATUS_REJECTED = "rejected";
// service instances // service instances
private WorkflowService workflowService; private WorkflowService workflowService;
private NamespaceService namespaceService;
private PersonService personService;
private ServiceRegistry serviceRegistry; private ServiceRegistry serviceRegistry;
private SiteService siteService;
/** /**
* Set the workflow service property * Set the workflow service property
@@ -99,25 +89,14 @@ public class Invites extends DeclarativeWebScript
this.workflowService = workflowService; this.workflowService = workflowService;
} }
/**
* Set the namespace service
*
* @param namespaceService the namespace service to set
*/
public void setNamespaceService(
NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
public void setServiceRegistry(ServiceRegistry serviceRegistry) { public void setServiceRegistry(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry; this.serviceRegistry = serviceRegistry;
} }
public void setSiteService(SiteService siteService) {
this.siteService = siteService;
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
@@ -204,17 +183,17 @@ public class Invites extends DeclarativeWebScript
1.0f); 1.0f);
if (inviterUserName != null) if (inviterUserName != null)
{ {
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITER_USER_NAME, this.namespaceService), wfQueryProps.put(InviteWorkflowModel.WF_PROP_INVITER_USER_NAME,
inviterUserName); inviterUserName);
} }
if (inviteeUserName != null) if (inviteeUserName != null)
{ {
wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITEE_USER_NAME, this.namespaceService), wfQueryProps.put(InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME,
inviteeUserName); inviteeUserName);
} }
if (siteShortName != null) if (siteShortName != null)
{ {
wfQueryProps.put(QName.createQName(Invite.WF_PROP_SITE_SHORT_NAME, this.namespaceService), wfQueryProps.put(InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME,
siteShortName); siteShortName);
} }
@@ -227,12 +206,12 @@ public class Invites extends DeclarativeWebScript
// pick up the start task // pick up the start task
wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED); wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED);
wfTaskQuery.setTaskName(QName.createQName(Invite.WF_INVITE_TASK_INVITE_TO_SITE, this.namespaceService)); wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_TO_SITE);
// 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 // invite workflow instances
// are returned by query // are returned by query
wfTaskQuery.setProcessName(QName.createQName("wf:invite", this.namespaceService)); wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
// query for invite workflow tasks // query for invite workflow tasks
List<WorkflowTask> wf_invite_tasks = this.workflowService List<WorkflowTask> wf_invite_tasks = this.workflowService
@@ -247,48 +226,7 @@ public class Invites extends DeclarativeWebScript
// onto model for each invite workflow task returned by the query // onto model for each invite workflow task returned by the query
for (WorkflowTask workflowTask : wf_invite_tasks) for (WorkflowTask workflowTask : wf_invite_tasks)
{ {
// get wf:inviterUserName, wf:inviteeUserName, wf:siteShortName InviteInfo inviteInfo = InviteHelper.getPendingInviteInfo(workflowTask, serviceRegistry, siteService);
// properties from workflow path associated with workflow task
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;
// set the invite start date to the time the workflow instance
// (associated with the task) was started
Date sentInviteDate = workflowTask.path.instance.startDate;
// get role that invitee was invited to the site as
String role = InviteHelper.getInviteeSiteRoleFromInvite(inviteId, workflowService, namespaceService);
// TODO: glen johnson at alfresco com - as this web script only returns
// pending invites, this is hard coded to "pending" for now
String invitationStatus = INVITATION_STATUS_PENDING;
// check whether we can find a person node for inviter/invitee
NodeRef inviterRef = personService.getPerson(inviterUserNameProp);
ScriptNode inviterPerson = null;
if (inviterRef != null)
{
inviterPerson = new ScriptNode(inviterRef, serviceRegistry);
}
NodeRef inviteeRef = personService.getPerson(inviteeUserNameProp);
ScriptNode inviteePerson = null;
if (inviteeRef != null)
{
inviteePerson = new ScriptNode(inviteeRef, serviceRegistry);
}
// create and add InviteInfo to inviteInfoList
InviteInfo inviteInfo = new InviteInfo(invitationStatus, inviterUserNameProp, inviterPerson,
inviteeUserNameProp, inviteePerson, role, siteShortNameProp, sentInviteDate, workflowId);
inviteInfoList.add(inviteInfo); inviteInfoList.add(inviteInfo);
} }
@@ -298,4 +236,5 @@ public class Invites extends DeclarativeWebScript
return model; return model;
} }
} }