MERGE DEV/3.2_INVITATION to HEAD

MOB-124 First cut of invitation service
  First cut group site membership

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13378 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2009-02-26 15:53:23 +00:00
parent d96f48fee9
commit b3ec745f99
22 changed files with 169 additions and 1062 deletions

View File

@@ -6,29 +6,5 @@
startup for beans in the Remote API project.
-->
<beans>
<bean id="remote-api.workflowBootstrap" parent="workflowDeployer">
<property name="workflowDefinitions">
<list>
<!-- Remote API invite workflow definition -->
<props>
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/workflow/invite_processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">false</prop>
</props>
</list>
</property>
<property name="models">
<list>
<!-- Remote API invite workflow Model -->
<value>alfresco/workflow/invite-workflow-model.xml</value>
</list>
</property>
<property name="labels">
<list>
<!-- Remote API invite workflow Model -->
<value>alfresco/workflow/invite-workflow-messages</value>
</list>
</property>
</bean>
</beans>

View File

@@ -11,6 +11,7 @@
"tagScope" : "${url.serviceContext + "/api/tagscopes/" + site.node.storeType + "/" + site.node.storeId + "/" + site.node.id}",
</#if>
"isPublic" : ${site.isPublic?string("true", "false")},
"visibility" : "${site.visibility}",
<#if site.customProperties?size != 0>
"customProperties" :
{

View File

@@ -6,10 +6,36 @@ function main()
if (site != null)
{
// Update the sites details
site.title = json.get("title");
site.description = json.get("description");
site.isPublic = json.getBoolean("isPublic");
// Updafte the sites details
if (json.has("title") == true)
{
site.title = json.get("title");
}
if (json.has("description") == true)
{
site.description = json.get("description");
}
// Use the visibility flag before the isPublic flag
if (json.has("visibility") == true)
{
site.visibility = json.get("visibility");
}
else if (json.has("isPublic") == true)
{
// Deal with deprecated isPublic flag accordingly
var isPublic = json.getBoolean("isPublic");
if (isPublic == true)
{
site.visibility = siteService.PUBLIC_SITE;
}
else
{
site.visibility = siteService.PRIVATE_SITE;
}
}
// Save the site
site.save();
// Pass the model to the template

View File

@@ -8,15 +8,15 @@ function main()
return;
}
// See if the shortName is available
var site = siteService.getSite(shortName);
if (site != null)
{
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "error.duplicateShortName");
return;
}
// See if the shortName is available
var site = siteService.getSite(shortName);
if (site != null)
{
status.setCode(status.STATUS_INTERNAL_SERVER_ERROR, "error.duplicateShortName");
return;
}
var sitePreset = json.get("sitePreset");
var sitePreset = json.get("sitePreset");
if (shortName == null || shortName.length == 0)
{
status.setCode(status.STATUS_BAD_REQUEST, "Site preset missing when creating site");
@@ -25,10 +25,28 @@ function main()
var title = json.get("title");
var description = json.get("description");
var isPublic = json.getBoolean("isPublic");
// Use the visibility flag before the isPublic flag
var visibility = siteService.PUBLIC_SITE;
if (json.has("visibility") == true)
{
visibility = json.get("visibility");
}
else if (json.has("isPublic") == true)
{
var isPublic = json.getBoolean("isPublic");
if (isPublic == true)
{
visibility = siteService.PUBLIC_SITE;
}
else
{
visibility = siteService.PRIVATE_SITE;
}
}
// Create the site
var site = siteService.createSite(sitePreset, shortName, title, description, isPublic);
var site = siteService.createSite(sitePreset, shortName, title, description, visibility);
// Put the created site into the model
model.site = site;

View File

@@ -1,40 +0,0 @@
# Display labels for out-of-the-box Site-oriented Workflows
#
# Invite Workflow
#
wf_invite.workflow.title=Site Invite
wf_invite.workflow.description=Invite to a Share Site
# Invite Task Definitions
wf_invite-workflow-model.type.wf_inviteToSiteTask.title=Start Invite
wf_invite-workflow-model.type.wf_inviteToSiteTask.description=Start an invite to a Site
wf_invite-workflow-model.type.wf_invitePendingTask.title=Site Invite
wf_invite-workflow-model.type.wf_invitePendingTask.description=Invite to a Site
wf_invite-workflow-model.type.wf_rejectInviteTask.title=Rejected
wf_invite-workflow-model.type.wf_rejectInviteTask.description=Rejected
wf_invite-workflow-model.type.wf_acceptInviteTask.title=Accepted
wf_invite-workflow-model.type.wf_acceptInviteTask.description=Accepted
# Invite Process Definitions
wf_invite.node.start.title=Start
wf_invite.node.start.description=Start
wf_invite.node.invitePending.title=Invite Pending
wf_invite.node.invitePending.description=Invite Pending
wf_invite.node.invitePending.transition.reject.title=Reject
wf_invite.node.invitePending.transition.reject.description=Reject
wf_invite.node.invitePending.transition.accept.title=Accept
wf_invite.node.invitePending.transition.accept.description=Accept
wf_invite.node.inviteRejected.title=Rejected
wf_invite.node.inviteRejected.description=Rejected
wf_invite.task.wf_rejectInviteTask.title=Rejected
wf_invite.task.wf_rejectInviteTask.description=Rejected
wf_invite.node.inviteAccepted.title=Accepted
wf_invite.node.inviteAccepted.description=Accepted
wf_invite.task.wf_acceptInviteTask.title=Accepted
wf_invite.task.wf_acceptInviteTask.description=Accepted
wf_invite.node.end.title=End
wf_invite.node.end.description=End

View File

@@ -1,69 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<model name="wf:invite-workflow-model" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<imports>
<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/workflow/1.0" prefix="wf" />
</imports>
<types>
<!-- Custom Tasks -->
<type name="wf:inviteToSiteTask">
<parent>bpm:startTask</parent>
<properties>
<property name="wf:serverPath">
<type>d:text</type>
</property>
<property name="wf:acceptUrl">
<type>d:text</type>
</property>
<property name="wf:rejectUrl">
<type>d:text</type>
</property>
<property name="wf:inviteTicket">
<type>d:text</type>
</property>
<property name="wf:inviterUserName">
<type>d:text</type>
</property>
<property name="wf:inviteeUserName">
<type>d:text</type>
</property>
<property name="wf:inviteeFirstName">
<type>d:text</type>
</property>
<property name="wf:inviteeLastName">
<type>d:text</type>
</property>
<property name="wf:inviteeGenPassword">
<type>d:text</type>
</property>
<property name="wf:siteShortName">
<type>d:text</type>
</property>
<property name="wf:inviteeSiteRole">
<type>d:text</type>
</property>
</properties>
<mandatory-aspects>
<aspect>bpm:assignee</aspect>
</mandatory-aspects>
</type>
<type name="wf:invitePendingTask">
<parent>bpm:workflowTask</parent>
</type>
<type name="wf:acceptInviteTask">
<parent>bpm:workflowTask</parent>
</type>
<type name="wf:rejectInviteTask">
<parent>bpm:workflowTask</parent>
</type>
</types>
</model>

View File

@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:invite">
<swimlane name="initiator"/>
<start-state name="start">
<task name="wf:inviteToSiteTask" swimlane="initiator" />
<transition name="sendInvite" to="invitePending">
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script>
var workflowId = workflowinstanceid;
var inviterPerson = people.getPerson(wf_inviterUserName);
var inviteePerson = people.getPerson(wf_inviteeUserName);
var site = siteService.getSite(wf_siteShortName);
var siteName = site.shortName;
if (site.title.length() > 0)
{
siteName = site.title;
}
var params = "?inviteId=" + workflowId +
"&amp;inviteeUserName=" + wf_inviteeUserName +
"&amp;siteShortName=" + wf_siteShortName +
"&amp;inviteTicket=" + wf_inviteTicket;
var acceptLink = wf_serverPath + wf_acceptUrl + params;
var rejectLink = wf_serverPath + wf_rejectUrl + params;
var mail = actions.create("mail");
mail.parameters.from = inviterPerson.properties["cm:email"];
mail.parameters.to = inviteePerson.properties["cm:email"];
mail.parameters.subject = "Invitation to join '" + siteName + "' site";
var results = search.luceneSearch(" PATH:\"app:company_home/app:dictionary/app:email_templates/cm:invite/cm:invite-email.ftl\"");
var template = results[0];
var args = [];
args["inviteePersonRef"] = inviteePerson.nodeRef.toString();
args["inviterPersonRef"] = inviterPerson.nodeRef.toString();
args["siteName"] = siteName;
args["inviteeSiteRole"] = wf_inviteeSiteRole;
args["inviteeUserName"] = wf_inviteeUserName;
args["inviteeGenPassword"] = wf_inviteeGenPassword;
args["acceptLink"] = acceptLink;
args["rejectLink"] = rejectLink;
var mail_text = inviteePerson.processTemplate(template, args);
mail.parameters.text = mail_text;
mail.execute(bpm_package);
</script>
</action>
</transition>
</start-state>
<swimlane name="assignee">
<assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
<actor>#{bpm_assignee.properties['cm:userName']}</actor>
</assignment>
</swimlane>
<task-node name="invitePending">
<task name="wf:invitePendingTask" swimlane="assignee" />
<transition name="accept" to="inviteAccepted">
<action class="org.alfresco.repo.web.scripts.invite.AcceptInviteAction"/>
</transition>
<transition name="reject" to="inviteRejected">
<action class="org.alfresco.repo.web.scripts.invite.RejectInviteAction"/>
</transition>
<transition name="cancel" to="end">
<action class="org.alfresco.repo.web.scripts.invite.CancelInviteAction"/>
</transition>
</task-node>
<task-node name="inviteAccepted">
<task name="wf:acceptInviteTask" swimlane="initiator" />
<transition name="end" to="end"/>
</task-node>
<task-node name="inviteRejected">
<task name="wf:rejectInviteTask" swimlane="initiator" />
<transition name="end" to="end"/>
</task-node>
<end-state name="end" />
</process-definition>

View File

@@ -31,9 +31,9 @@ import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteService;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.JSONtoFmModel;
import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.Status;

View File

@@ -30,12 +30,12 @@ import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteModel;
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.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.PropertyMap;
import org.alfresco.web.scripts.TestWebScriptServer.DeleteRequest;
import org.alfresco.web.scripts.TestWebScriptServer.GetRequest;

View File

@@ -29,12 +29,12 @@ import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteModel;
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.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.util.PropertyMap;
import org.alfresco.web.scripts.TestWebScriptServer.DeleteRequest;
import org.alfresco.web.scripts.TestWebScriptServer.GetRequest;

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.web.scripts.invite;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
import org.alfresco.service.ServiceRegistry;
import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.beans.factory.BeanFactory;
/**
* This class contains logic that gets executed when
* the wf:invitePendingTask in the invite workflow gets completed
* along the "accept" transition
*
* @author glen johnson at alfresco com
*/
public class AcceptInviteAction extends JBPMSpringActionHandler
{
private static final long serialVersionUID = 8133039174866049136L;
private SiteService siteService;
private MutableAuthenticationDao mutableAuthenticationDao;
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
*/
@Override
protected void initialiseHandler(BeanFactory factory)
{
ServiceRegistry services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
mutableAuthenticationDao = (MutableAuthenticationDao) factory.getBean("authenticationDao");
siteService = services.getSiteService();
}
/* (non-Javadoc)
* @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
*/
@SuppressWarnings("unchecked")
public void execute(final ExecutionContext executionContext) throws Exception
{
final String inviteeUserName = (String) executionContext.getVariable("wf_inviteeUserName");
final String siteShortName = (String) executionContext.getVariable("wf_siteShortName");
final String inviterUserName = (String) executionContext.getVariable("wf_inviterUserName");
final String inviteeSiteRole = (String) executionContext.getVariable("wf_inviteeSiteRole");
// if there is already a user account for the invitee and that account
// is disabled, then enable the account because he/she has accepted the
// site invitation
if ((this.mutableAuthenticationDao.userExists(inviteeUserName))
&& (this.mutableAuthenticationDao.getEnabled(inviteeUserName) == false))
{
this.mutableAuthenticationDao.setEnabled(inviteeUserName, true);
}
// add Invitee to Site with the site role that the inviter "started" the invite process with
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
AcceptInviteAction.this.siteService.setMembership(siteShortName,
inviteeUserName, inviteeSiteRole);
return null;
}
}, inviterUserName);
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.web.scripts.invite;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.web.scripts.Status;
import org.alfresco.web.scripts.WebScriptException;
import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.beans.factory.BeanFactory;
/**
* This class contains logic that gets executed when
* the wf:invitePendingTask in the invite workflow gets cancelled
* along the "cancel" transition
*
* @author glen johnson at alfresco com
*/
public class CancelInviteAction extends JBPMSpringActionHandler
{
private static final long serialVersionUID = 776961141883350908L;
private MutableAuthenticationDao mutableAuthenticationDao;
private PersonService personService;
private WorkflowService workflowService;
private SiteService siteService;
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
*/
@Override
protected void initialiseHandler(BeanFactory factory)
{
ServiceRegistry services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
mutableAuthenticationDao = (MutableAuthenticationDao) factory.getBean("authenticationDao");
personService = (PersonService) services.getPersonService();
workflowService = (WorkflowService) services.getWorkflowService();
siteService = (SiteService) services.getSiteService();
}
/* (non-Javadoc)
* @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
*/
@SuppressWarnings("unchecked")
public void execute(final ExecutionContext executionContext) throws Exception
{
// get the invitee user name and site short name variables off the execution context
final String inviteeUserName = (String) executionContext.getVariable(
InviteWorkflowModel.wfVarInviteeUserName);
final String siteShortName = (String) executionContext.getVariable(
InviteWorkflowModel.wfVarSiteShortName);
final String inviteId = (String) executionContext.getVariable(
InviteWorkflowModel.wfVarWorkflowInstanceId);
// throw http status 'forbidden' Web Script Exception if current user is not a Site Manager of the site
// associated with the invite (identified by inviteID)
String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
String currentUserSiteRole = this.siteService.getMembersRole(siteShortName, currentUserName);
if ((currentUserSiteRole == null) || (currentUserSiteRole.equals(SiteModel.SITE_MANAGER) == false))
{
throw new WebScriptException(Status.STATUS_FORBIDDEN,
"Current user '" + currentUserName + "' cannot cancel invite having ID '" + inviteId
+ "' because he\\she is not a Site Manager of the site with short name:'" + siteShortName
+ "'");
}
// clean up invitee's user account and person node if they are not in use i.e.
// account is still disabled and there are no pending invites outstanding for the
// invitee
InviteHelper.cleanUpStaleInviteeResources(inviteeUserName, mutableAuthenticationDao, personService,
workflowService);
}
}

View File

@@ -31,20 +31,24 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.invitation.site.InviteHelper;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.authentication.PasswordGenerator;
import org.alfresco.repo.security.authentication.UserNameGenerator;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.InvitationExceptionForbidden;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.service.cmr.workflow.WorkflowPath;
@@ -374,7 +378,14 @@ public class Invite extends DeclarativeWebScript
}
// process action 'cancel' with provided parameters
cancelInvite(model, inviteId);
try
{
cancelInvite(model, inviteId);
}
catch(InvitationExceptionForbidden fe)
{
throw new WebScriptException(Status.STATUS_FORBIDDEN, "Unable to cancel workflow" , fe);
}
}
// handle action not recognised
else
@@ -589,16 +600,16 @@ public class Invite extends DeclarativeWebScript
//
WorkflowDefinition wfDefinition = this.workflowService
.getDefinitionByName(InviteWorkflowModel.WORKFLOW_DEFINITION_NAME);
.getDefinitionByName(WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME);
// handle workflow definition does not exist
if (wfDefinition == null)
{
if (logger.isInfoEnabled())
logger.info("Workflow definition for name " + InviteWorkflowModel.WORKFLOW_DEFINITION_NAME + " does not exist.");
logger.info("Workflow definition for name " + WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME + " does not exist.");
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
"Workflow definition for name " + InviteWorkflowModel.WORKFLOW_DEFINITION_NAME + " does not exist.");
"Workflow definition for name " + WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME + " does not exist.");
}
// Get invitee person NodeRef to add as assignee
@@ -606,18 +617,19 @@ public class Invite extends DeclarativeWebScript
// create workflow properties
Map<QName, Serializable> workflowProps = new HashMap<QName, Serializable>(16);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITER_USER_NAME, inviterUserName);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME, inviteeUserName);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITER_USER_NAME, inviterUserName);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_USER_NAME, inviteeUserName);
workflowProps.put(WorkflowModel.ASSOC_ASSIGNEE, inviteeNodeRef);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_FIRSTNAME, inviteeFirstName);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_LASTNAME, inviteeLastName);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_GEN_PASSWORD, inviteePassword);
workflowProps.put(InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME, siteShortName);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITEE_SITE_ROLE, inviteeSiteRole);
workflowProps.put(InviteWorkflowModel.WF_PROP_SERVER_PATH, serverPath);
workflowProps.put(InviteWorkflowModel.WF_PROP_ACCEPT_URL, acceptUrl);
workflowProps.put(InviteWorkflowModel.WF_PROP_REJECT_URL, rejectUrl);
workflowProps.put(InviteWorkflowModel.WF_PROP_INVITE_TICKET, inviteTicket);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_FIRSTNAME, inviteeFirstName);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_LASTNAME, inviteeLastName);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_GEN_PASSWORD, inviteePassword);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_TYPE, Invitation.ResourceType.WEB_SITE);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME, siteShortName);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_SITE_ROLE, inviteeSiteRole);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_SERVER_PATH, serverPath);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_ACCEPT_URL, acceptUrl);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_REJECT_URL, rejectUrl);
workflowProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITE_TICKET, inviteTicket);
// start the workflow
WorkflowPath wfPath = this.workflowService.startWorkflow(wfDefinition.getId(), workflowProps);
@@ -649,7 +661,7 @@ public class Invite extends DeclarativeWebScript
String wfTaskName = wfTasks.get(0).name;
QName wfTaskNameQName = QName.createQName(wfTaskName, this.namespaceService);
QName inviteToSiteTaskQName = InviteWorkflowModel.WF_INVITE_TASK_INVITE_TO_SITE;
QName inviteToSiteTaskQName = WorkflowModelNominatedInvitation.WF_INVITE_TASK_INVITE_TO_SITE;
if (!wfTaskNameQName.equals(inviteToSiteTaskQName))
{
if (logger.isInfoEnabled())
@@ -679,7 +691,7 @@ public class Invite extends DeclarativeWebScript
logger.debug("Transitioning Invite workflow task...");
try
{
this.workflowService.endTask(wfStartTask.id, InviteWorkflowModel.WF_TRANSITION_SEND_INVITE);
this.workflowService.endTask(wfStartTask.id, WorkflowModelNominatedInvitation.WF_TRANSITION_SEND_INVITE);
}
catch (RuntimeException err)
{
@@ -723,9 +735,14 @@ public class Invite extends DeclarativeWebScript
try
{
// complete the wf:invitePendingTask along the 'cancel' transition because the invitation has been cancelled
InviteHelper.completeInviteTask(inviteId, InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING,
InviteWorkflowModel.WF_TRANSITION_CANCEL, this.workflowService);
InviteHelper.completeInviteTask(inviteId, WorkflowModelNominatedInvitation.WF_INVITE_TASK_INVITE_PENDING,
WorkflowModelNominatedInvitation.WF_TRANSITION_CANCEL, this.workflowService);
}
catch(InvitationExceptionForbidden fe)
{
throw new WebScriptException(Status.STATUS_FORBIDDEN, "Unable to cancel workflow" , fe);
}
catch (WorkflowException wfe)
{
//
@@ -734,7 +751,12 @@ public class Invite extends DeclarativeWebScript
//
Throwable indirectCause = wfe.getCause().getCause();
if (indirectCause instanceof WebScriptException)
if(indirectCause instanceof InvitationExceptionForbidden)
{
throw new WebScriptException(Status.STATUS_FORBIDDEN, "Unable to cancel workflow" , indirectCause);
}
else if (indirectCause instanceof WebScriptException)
{
WebScriptException wse = (WebScriptException) indirectCause;
throw wse;

View File

@@ -27,9 +27,12 @@ package org.alfresco.repo.web.scripts.invite;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.invitation.site.InviteHelper;
import org.alfresco.repo.invitation.site.InviteInfo;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.web.scripts.DeclarativeWebScript;
@@ -103,7 +106,7 @@ public class InviteByTicket extends DeclarativeWebScript
// check whether tickets match, throw error otherwise
String ticket = (String) workflowTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITE_TICKET);
WorkflowModelNominatedInvitation.WF_PROP_INVITE_TICKET);
if (ticket == null || (! ticket.equals(inviteTicket)))
{
throw new WebScriptException(Status.STATUS_NOT_FOUND,

View File

@@ -1,268 +0,0 @@
/*
* 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.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.template.TemplateNode;
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.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;
/**
* Helper class to house utility methods common to
* more than one Invite Service Web Script
*/
public class InviteHelper
{
/**
* Find an invite start task by the given task id.
*
* @return a WorkflowTask or null if not found.
*/
public static WorkflowTask findInviteStartTask(String inviteId, WorkflowService workflowService)
{
// create workflow task query
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
wfTaskQuery.setProcessId(inviteId);
// set process name to "wf:invite" so that only tasks associated with
// invite workflow instances are returned by query
wfTaskQuery.setProcessName(QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invite"));
// filter to find only the invite start task
wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED);
wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_TO_SITE);
// query for invite workflow task associate
List<WorkflowTask> inviteStartTasks = workflowService
.queryTasks(wfTaskQuery);
// should also be 0 or 1
if (inviteStartTasks.size() < 1)
{
return null;
}
else
{
return inviteStartTasks.get(0);
}
}
/**
* Find invitePending tasks (in-progress) by the given invitee user name
*
* @return a list of workflow tasks
*/
public static List<WorkflowTask> findInvitePendingTasks(String inviteeUserName, WorkflowService workflowService)
{
// create workflow task query
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
// set process name to "wf:invite" so that only tasks associated with
// invite workflow instances are returned by query
wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
// set query to only pick up invite workflow instances
// associated with the given invitee user name
Map<QName, Object> processCustomProps = new HashMap<QName, Object>(1, 1.0f);
processCustomProps.put(InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME, inviteeUserName);
wfTaskQuery.setProcessCustomProps(processCustomProps);
// set query to only pick up in-progress invite pending tasks
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING);
// query for invite workflow task associate
List<WorkflowTask> inviteStartTasks = workflowService
.queryTasks(wfTaskQuery);
return inviteStartTasks;
}
/**
* Returns an InviteInfo instance for the given startInvite task
* (used for rendering the response).
*
* @param startInviteTask startInvite task to get invite info properties from
* @param serviceRegistry service registry instance
* @param siteService site service instance
*
* @return InviteInfo instance containing invite information
*/
public static InviteInfo getPendingInviteInfo(final WorkflowTask startInviteTask,
final ServiceRegistry serviceRegistry, final SiteService siteService)
{
final PersonService personService = serviceRegistry.getPersonService();
// get the inviter, invitee, role and site short name
final String inviterUserNameProp = (String) startInviteTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITER_USER_NAME);
final String inviteeUserNameProp = (String) startInviteTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME);
final String role = (String) startInviteTask.properties.get(
InviteWorkflowModel.WF_PROP_INVITEE_SITE_ROLE);
final String siteShortNameProp = (String) startInviteTask.properties.get(
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
// get the site info
SiteInfo siteInfo = siteService.getSite(siteShortNameProp);
// get workflow instance id (associated with workflow task) to place
// as "inviteId" onto model
String workflowId = startInviteTask.path.instance.id;
// set the invite start date to the time the workflow instance
// (associated with the task) was started
Date sentInviteDate = startInviteTask.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);
TemplateNode inviterPerson = null;
if (inviterRef != null)
{
inviterPerson = new TemplateNode(inviterRef, serviceRegistry, null);
//inviterPerson = new ScriptNode(inviterRef, serviceRegistry);
}
// fetch the person node for the invitee
NodeRef inviteeRef = personService.getPerson(inviteeUserNameProp);
TemplateNode inviteePerson = null;
if (inviteeRef != null)
{
inviteePerson = new TemplateNode(inviteeRef, serviceRegistry, null);
//inviteePerson = new ScriptNode(inviteeRef, serviceRegistry);
}
// create and return a invite info
InviteInfo inviteInfo = new InviteInfo(invitationStatus, inviterUserNameProp, inviterPerson,
inviteeUserNameProp, inviteePerson, role, siteShortNameProp, siteInfo, sentInviteDate, workflowId);
return inviteInfo;
}
/**
* Clean up invitee user account and person node when no longer in use.
* They are deemed to no longer be in use when the invitee user account
* is still disabled and there are no outstanding pending invites for that invitee.
*
* @param inviteeUserName
* @param authenticationDao
* @param personService
* @param workflowService
*/
public static void cleanUpStaleInviteeResources(final String inviteeUserName,
final MutableAuthenticationDao authenticationDao, final PersonService personService,
final WorkflowService workflowService)
{
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
// see if there are any pending invites (invite workflow instances with invitePending task in-progress)
// outstanding for given invitee user name
List<WorkflowTask> pendingTasks = InviteHelper.findInvitePendingTasks(inviteeUserName, workflowService);
boolean invitesPending = (pendingTasks != null) && (pendingTasks.size() > 0);
// if invitee's user account is still disabled and there are no pending invites outstanding
// for the invitee, then remove the account and delete the invitee's person node
if ((authenticationDao.userExists(inviteeUserName))
&& (authenticationDao.getEnabled(inviteeUserName) == false)
&& (invitesPending == false))
{
// delete the invitee's user account
authenticationDao.deleteUser(inviteeUserName);
// delete the invitee's person node if one exists
if (personService.personExists(inviteeUserName))
{
personService.deletePerson(inviteeUserName);
}
}
return null;
}
}, AuthenticationUtil.getSystemUserName());
}
/**
* Complete the specified Invite Workflow Task for the invite workflow
* instance associated with the given invite ID, and follow the given
* transition upon completing the task
*
* @param inviteId the invite ID of the invite workflow instance for which
* we want to complete the given task
* @param fullTaskName qualified name of invite workflow task to complete
* @param transitionId the task transition to take on completion of
* the task (or null, for the default transition)
*/
public static void completeInviteTask(String inviteId, QName fullTaskName, String transitionId,
final WorkflowService workflowService)
{
// create workflow task query
WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
// set the given invite ID as the workflow process ID in the workflow query
wfTaskQuery.setProcessId(inviteId);
// find incomplete invite workflow tasks with given task name
wfTaskQuery.setActive(Boolean.TRUE);
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
wfTaskQuery.setTaskName(fullTaskName);
// set process name to "wf:invite" so that only
// invite workflow instances are considered by this query
wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
// query for invite workflow tasks with the constructed query
List<WorkflowTask> wf_invite_tasks = workflowService
.queryTasks(wfTaskQuery);
// end all tasks found with this name
for (WorkflowTask workflowTask : wf_invite_tasks)
{
workflowService.endTask(workflowTask.id, transitionId);
}
}
}

View File

@@ -1,171 +0,0 @@
/*
* 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.io.Serializable;
import java.util.Date;
import org.alfresco.repo.template.TemplateNode;
import org.alfresco.repo.site.SiteInfo;
/**
* Holds properties pertaining to an invitation that has been sent out by a Site Manager (Inviter)
* to another person (Invitee) to join his/her Site
*
* @author glen dot johnson at alfresco dot com
*/
public class InviteInfo implements Serializable
{
private static final long serialVersionUID = -4514253998906200208L;
// 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 String invitationStatus;
private String inviterUserName;
private TemplateNode inviterPerson;
private String inviteeUserName;
private TemplateNode inviteePerson;
private String role;
private String siteShortName;
private SiteInfo siteInfo;
private Date sentInviteDate;
private String inviteId;
public InviteInfo(String invitationStatus, String inviterUserName, TemplateNode inviterPerson,
String inviteeUserName, TemplateNode inviteePerson, String role,
String siteShortName, SiteInfo siteInfo, Date sentInviteDate, String inviteId)
{
this.invitationStatus = invitationStatus;
this.inviterUserName = inviterUserName;
this.inviterPerson = inviterPerson;
this.inviteeUserName = inviteeUserName;
this.inviteePerson = inviteePerson;
this.role = role;
this.siteShortName = siteShortName;
this.siteInfo = siteInfo;
this.sentInviteDate = sentInviteDate;
this.inviteId = inviteId;
}
/**
* Gets the inviter user name
*
* @return the inviterUserName
*/
public String getInviterUserName()
{
return inviterUserName;
}
/**
* Gets the invitee user name
*
* @return the inviteeUserName
*/
public String getInviteeUserName()
{
return inviteeUserName;
}
/**
* Gets the site short name
*
* @return the siteShortName
*/
public String getSiteShortName()
{
return siteShortName;
}
/**
* Gets the invite ID
*
* @return the inviteId
*/
public String getInviteId()
{
return inviteId;
}
/**
* Gets the invitee person
*
* @return the invitee person
*/
public TemplateNode getInviteePerson()
{
return inviteePerson;
}
/**
* Gets the inviter person
*
* @return the inviter person
*/
public TemplateNode getInviterPerson()
{
return inviterPerson;
}
/**
* Gets the sent invite date
*
* @return the sent invite date
*/
public Date getSentInviteDate()
{
return sentInviteDate;
}
/**
* Gets the invitation status
*
* @return the invitation status
*/
public String getInvitationStatus()
{
return invitationStatus;
}
/**
* Gets the role that invitee has been invited to the site as
*
* @return the role that the invitee has been invited to the site as
*/
public String getRole()
{
return role;
}
public SiteInfo getSiteInfo()
{
return siteInfo;
}
}

View File

@@ -27,6 +27,8 @@ package org.alfresco.repo.web.scripts.invite;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.invitation.site.InviteHelper;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.web.scripts.DeclarativeWebScript;
@@ -90,7 +92,7 @@ public class InviteResponse extends DeclarativeWebScript
}
// check the ticket for a match
String ticket = (String) inviteStartTask.properties.get(InviteWorkflowModel.WF_PROP_INVITE_TICKET);
String ticket = (String) inviteStartTask.properties.get(WorkflowModelNominatedInvitation.WF_PROP_INVITE_TICKET);
if (ticket == null || (! ticket.equals(inviteTicket)))
{
throw new WebScriptException(Status.STATUS_NOT_FOUND,
@@ -133,11 +135,11 @@ public class InviteResponse extends DeclarativeWebScript
private void acceptInvite(Map<String, Object> model, String inviteId, WorkflowTask inviteStartTask)
{
String siteShortName = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME);
// complete the wf:invitePendingTask along the 'accept' transition because the invitation has been accepted
InviteHelper.completeInviteTask(inviteId, InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING,
InviteWorkflowModel.WF_TRANSITION_ACCEPT, this.workflowService);
InviteHelper.completeInviteTask(inviteId, WorkflowModelNominatedInvitation.WF_INVITE_TASK_INVITE_PENDING,
WorkflowModelNominatedInvitation.WF_TRANSITION_ACCEPT, this.workflowService);
// add model properties for template to render
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_ACCEPT);
@@ -161,11 +163,11 @@ public class InviteResponse extends DeclarativeWebScript
private void rejectInvite(Map<String, Object> model, String inviteId, WorkflowTask inviteStartTask)
{
String siteShortName = (String) inviteStartTask.properties.get(
InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME);
WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME);
// complete the wf:invitePendingTask task along the 'reject' transition because the invitation has been rejected
InviteHelper.completeInviteTask(inviteId, InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING,
InviteWorkflowModel.WF_TRANSITION_REJECT, this.workflowService);
InviteHelper.completeInviteTask(inviteId, WorkflowModelNominatedInvitation.WF_INVITE_TASK_INVITE_PENDING,
WorkflowModelNominatedInvitation.WF_TRANSITION_REJECT, this.workflowService);
// add model properties for template to render
model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_REJECT);

View File

@@ -30,13 +30,12 @@ import java.util.Set;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
@@ -47,6 +46,8 @@ import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.alfresco.service.cmr.workflow.WorkflowService;
@@ -137,10 +138,10 @@ public class InviteServiceTest extends BaseWebScriptTest
// redeploy invite process definition in case it has been modified
WorkflowDefinition inviteWfDefinition = this.workflowService.getDefinitionByName(
"jbpm$" + InviteWorkflowModel.WF_PROCESS_INVITE.toPrefixString(this.namespaceService));
"jbpm$" + WorkflowModelNominatedInvitation.WF_PROCESS_INVITE.toPrefixString(this.namespaceService));
this.workflowService.undeployDefinition(inviteWfDefinition.id);
ClassPathResource inviteWfResource = new ClassPathResource(
"alfresco/workflow/invite_processdefinition.xml");
"alfresco/workflow/invitation-nominated_processdefinition.xml");
workflowService.deployDefinition(
"jbpm", inviteWfResource.getInputStream(), MimetypeMap.MIMETYPE_XML);

View File

@@ -1,46 +0,0 @@
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_INVITE_TASK_INVITE_PENDING = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "invitePendingTask");
public static final QName WF_TASK_ACCEPT_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "acceptInviteTask");
public static final QName WF_TASK_REJECT_INVITE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "rejectInviteTask");
// 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_CANCEL = "cancel";
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");
// workflow execution context variable names
public static final String wfVarInviteeUserName = "wf_inviteeUserName";
public static final String wfVarSiteShortName = "wf_siteShortName";
public static final String wfVarWorkflowInstanceId = "workflowinstanceid";
}

View File

@@ -29,8 +29,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.invitation.site.InviteHelper;
import org.alfresco.repo.invitation.site.InviteInfo;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
@@ -183,17 +186,17 @@ public class Invites extends DeclarativeWebScript
1.0f);
if (inviterUserNameProvided)
{
wfQueryProps.put(InviteWorkflowModel.WF_PROP_INVITER_USER_NAME,
wfQueryProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITER_USER_NAME,
inviterUserName);
}
if (inviteeUserNameProvided)
{
wfQueryProps.put(InviteWorkflowModel.WF_PROP_INVITEE_USER_NAME,
wfQueryProps.put(WorkflowModelNominatedInvitation.WF_PROP_INVITEE_USER_NAME,
inviteeUserName);
}
if (siteShortNameProvided)
{
wfQueryProps.put(InviteWorkflowModel.WF_PROP_SITE_SHORT_NAME,
wfQueryProps.put(WorkflowModelNominatedInvitation.WF_PROP_RESOURCE_NAME,
siteShortName);
}
@@ -206,12 +209,12 @@ public class Invites extends DeclarativeWebScript
// pick up the start task
wfTaskQuery.setTaskState(WorkflowTaskState.IN_PROGRESS);
wfTaskQuery.setTaskName(InviteWorkflowModel.WF_INVITE_TASK_INVITE_PENDING);
wfTaskQuery.setTaskName(WorkflowModelNominatedInvitation.WF_INVITE_TASK_INVITE_PENDING);
// set process name to "wf:invite" so that only tasks associated with
// invite workflow instances
// are returned by query
wfTaskQuery.setProcessName(InviteWorkflowModel.WF_PROCESS_INVITE);
wfTaskQuery.setProcessName(WorkflowModelNominatedInvitation.WF_PROCESS_INVITE);
// query for invite workflow tasks
List<WorkflowTask> wf_invite_tasks = this.workflowService

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.web.scripts.invite;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.beans.factory.BeanFactory;
/**
* This class contains logic that gets executed when
* the wf:invitePendingTask in the invite workflow gets completed
* along the "reject" transition
*
* @author glen johnson at alfresco com
*/
public class RejectInviteAction extends JBPMSpringActionHandler
{
private static final long serialVersionUID = 4377660284993206875L;
private MutableAuthenticationDao mutableAuthenticationDao;
private PersonService personService;
private WorkflowService workflowService;
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
*/
@Override
protected void initialiseHandler(BeanFactory factory)
{
ServiceRegistry services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
mutableAuthenticationDao = (MutableAuthenticationDao) factory.getBean("authenticationDao");
personService = (PersonService) services.getPersonService();
workflowService = (WorkflowService) services.getWorkflowService();
}
/* (non-Javadoc)
* @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
*/
@SuppressWarnings("unchecked")
public void execute(final ExecutionContext executionContext) throws Exception
{
// get the invitee user name
final String inviteeUserName = (String) executionContext.getVariable(InviteWorkflowModel.wfVarInviteeUserName);
// clean up invitee's user account and person node if they are not in use i.e.
// account is still disabled and there are no pending invites outstanding for the
// invitee
InviteHelper.cleanUpStaleInviteeResources(inviteeUserName, mutableAuthenticationDao, personService,
workflowService);
}
}

View File

@@ -32,14 +32,15 @@ import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.site.SiteInfo;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.site.SiteService;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.alfresco.util.PropertyMap;
@@ -48,6 +49,7 @@ import org.alfresco.web.scripts.TestWebScriptServer.GetRequest;
import org.alfresco.web.scripts.TestWebScriptServer.PostRequest;
import org.alfresco.web.scripts.TestWebScriptServer.PutRequest;
import org.alfresco.web.scripts.TestWebScriptServer.Response;
import org.htmlparser.parserapplications.SiteCapturer;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -133,20 +135,21 @@ public class SiteServiceTest extends BaseWebScriptTest
String shortName = GUID.generate();
// Create a new site
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
assertEquals("myPreset", result.get("sitePreset"));
assertEquals(shortName, result.get("shortName"));
assertEquals("myTitle", result.get("title"));
assertEquals("myDescription", result.get("description"));
assertNotNull(result.get("node"));
assertNotNull(result.get("tagScope"));
assertEquals(SiteVisibility.PUBLIC.toString(), result.get("visibility"));
assertTrue(result.getBoolean("isPublic"));
// Check for duplicate names
createSite("myPreset", shortName, "myTitle", "myDescription", true, 500);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 500);
}
private JSONObject createSite(String sitePreset, String shortName, String title, String description, boolean isPublic, int expectedStatus)
private JSONObject createSite(String sitePreset, String shortName, String title, String description, SiteVisibility visibility, int expectedStatus)
throws Exception
{
JSONObject site = new JSONObject();
@@ -154,7 +157,7 @@ public class SiteServiceTest extends BaseWebScriptTest
site.put("shortName", shortName);
site.put("title", title);
site.put("description", description);
site.put("isPublic", isPublic);
site.put("visibility", visibility.toString());
Response response = sendRequest(new PostRequest(URL_SITES, site.toString(), "application/json"), expectedStatus);
this.createdSites.add(shortName);
return new JSONObject(response.getContentAsString());
@@ -167,11 +170,11 @@ public class SiteServiceTest extends BaseWebScriptTest
assertNotNull(result);
assertEquals(0, result.length());
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", true, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", true, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", true, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", true, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", true, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
createSite("myPreset", GUID.generate(), "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
response = sendRequest(new GetRequest(URL_SITES), 200);
result = new JSONArray(response.getContentAsString());
@@ -196,7 +199,7 @@ public class SiteServiceTest extends BaseWebScriptTest
// Create a site and get it
String shortName = GUID.generate();
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
response = sendRequest(new GetRequest(URL_SITES + "/" + shortName), 200);
}
@@ -205,17 +208,18 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Update the site
result.put("title", "abs123abc");
result.put("description", "123abc123");
result.put("isPublic", false);
result.put("visibility", SiteVisibility.PRIVATE.toString());
Response response = sendRequest(new PutRequest(URL_SITES + "/" + shortName, result.toString(), "application/json"), 200);
result = new JSONObject(response.getContentAsString());
assertEquals("abs123abc", result.get("title"));
assertEquals("123abc123", result.get("description"));
assertFalse(result.getBoolean("isPublic"));
assertEquals(SiteVisibility.PRIVATE.toString(), result.get("visibility"));
// Try and get the site and double check it's changed
response = sendRequest(new GetRequest(URL_SITES + "/" + shortName), 200);
@@ -223,16 +227,17 @@ public class SiteServiceTest extends BaseWebScriptTest
assertEquals("abs123abc", result.get("title"));
assertEquals("123abc123", result.get("description"));
assertFalse(result.getBoolean("isPublic"));
assertEquals(SiteVisibility.PRIVATE.toString(), result.get("visibility"));
}
public void testDeleteSite() throws Exception
{
// Delete non-existant site
// Delete non-existent site
Response response = sendRequest(new DeleteRequest(URL_SITES + "/" + "somerandomshortname"), 404);
// Create a site
String shortName = GUID.generate();
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
JSONObject result = createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Get the site
response = sendRequest(new GetRequest(URL_SITES + "/" + shortName), 200);
@@ -248,7 +253,7 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Check the memberships
Response response = sendRequest(new GetRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS), 200);
@@ -264,7 +269,7 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Build the JSON membership object
JSONObject membership = new JSONObject();
@@ -273,7 +278,7 @@ public class SiteServiceTest extends BaseWebScriptTest
person.put("userName", USER_TWO);
membership.put("person", person);
// Post the memebership
// Post the membership
Response response = sendRequest(new PostRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS, membership.toString(), "application/json"), 200);
JSONObject result = new JSONObject(response.getContentAsString());
@@ -292,7 +297,7 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Test error conditions
sendRequest(new GetRequest(URL_SITES + "/badsite" + URL_MEMBERSHIPS + "/" + USER_ONE), 404);
@@ -311,7 +316,7 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Test error conditions
// TODO
@@ -323,7 +328,7 @@ public class SiteServiceTest extends BaseWebScriptTest
person.put("userName", USER_TWO);
membership.put("person", person);
// Post the memebership
// Post the membership
Response response = sendRequest(new PostRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS, membership.toString(), "application/json"), 200);
JSONObject newMember = new JSONObject(response.getContentAsString());
@@ -347,7 +352,7 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// Build the JSON membership object
JSONObject membership = new JSONObject();
@@ -371,9 +376,9 @@ public class SiteServiceTest extends BaseWebScriptTest
{
// Create a site
String shortName = GUID.generate();
createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
String shortName2 = GUID.generate();
createSite("myPreset", shortName2, "myTitle", "myDescription", true, 200);
createSite("myPreset", shortName2, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
Response response = sendRequest(new GetRequest("/api/people/" + USER_TWO + "/sites"), 200);
JSONArray result = new JSONArray(response.getContentAsString());
@@ -381,7 +386,7 @@ public class SiteServiceTest extends BaseWebScriptTest
assertNotNull(result);
assertEquals(0, result.length());
// Add some memeberships
// Add some memberships
JSONObject membership = new JSONObject();
membership.put("role", SiteModel.SITE_CONSUMER);
JSONObject person = new JSONObject();
@@ -430,7 +435,7 @@ public class SiteServiceTest extends BaseWebScriptTest
throws Exception
{
// Create a site with a custom property
SiteInfo siteInfo = this.siteService.createSite("testPreset", "mySiteWithCustomProperty2", "testTitle", "testDescription", true);
SiteInfo siteInfo = this.siteService.createSite("testPreset", "mySiteWithCustomProperty2", "testTitle", "testDescription", SiteVisibility.PUBLIC);
NodeRef siteNodeRef = siteInfo.getNodeRef();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(1);
properties.put(QName.createQName(SiteModel.SITE_CUSTOM_PROPERTY_URL, "additionalInformation"), "information");