diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invites.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invites.get.desc.xml
new file mode 100644
index 0000000000..9aee4d3286
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invites.get.desc.xml
@@ -0,0 +1,10 @@
+
+ Invites
+ Returns pending invites filtered by Inviter user name, Invitee user name & Site short name
+ /api/invites?inviterUserName={inviterUserName}&inviteeUserName={inviteeUserName?}&siteShortName={siteShortName?}
+ /api/invites?inviterUserName={inviterUserName?}&inviteeUserName={inviteeUserName}&siteShortName={siteShortName?}
+ /api/invites?inviterUserName={inviterUserName?}&inviteeUserName={inviteeUserName?}&siteShortName={siteShortName}
+
+ user
+ required
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/web/scripts/invite/Invite.java b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java
new file mode 100644
index 0000000000..3db87012f3
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java
@@ -0,0 +1,367 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
+import org.alfresco.repo.security.authentication.PasswordGenerator;
+import org.alfresco.repo.security.authentication.UserNameGenerator;
+import org.alfresco.service.cmr.security.AuthenticationService;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.cmr.workflow.WorkflowDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowPath;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.namespace.QName;
+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 invoked by a Site Manager (Inviter) to either send
+ * (action='start') an invitation to a another person (Invitee) to join a Site
+ * as a Site Collaborator, or to cancel (action='cancel') a pending invitation
+ * that has already been sent out
+ *
+ * @author glen dot johnson at alfresco dot com
+ */
+public class Invite extends DeclarativeWebScript
+{
+ private static final String WORKFLOW_DEFINITION_NAME = "jbpm$wf:invite";
+ private static final String ACTION_START = "start";
+ 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_WORKFLOW_ID = "workflowId";
+ private static final String MODEL_PROP_KEY_INVITEE_USER_NAME = "inviteeUserName";
+ private static final String MODEL_PROP_KEY_SITE_SHORT_NAME = "siteShortName";
+
+ // URL request parameter names
+ private static final String PARAM_INVITEE_EMAIL = "inviteeEmail";
+ private static final String PARAM_SITE_SHORT_NAME = "siteShortName";
+ private static final String PARAM_WORKFLOW_ID = "workflowId";
+
+ // workflow properties
+ 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_SITE_SHORT_NAME = "wf:siteShortName";
+ private static final String WF_PROP_INVITEE_GEN_PASSWORD = "wf:inviteeGenPassword";
+
+ // services
+ private WorkflowService workflowService;
+ private PersonService personService;
+ private AuthenticationService authenticationService;
+ private MutableAuthenticationDao mutableAuthenticationDao;
+
+ // user name and password generation beans
+ private UserNameGenerator usernameGenerator;
+ private PasswordGenerator passwordGenerator;
+
+ /**
+ * Sets the workflowService property
+ *
+ * @param workflowService
+ * the workflow service to set
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ /**
+ * Set the personService property
+ *
+ * @param personService
+ * the person service to set
+ */
+ public void setPersonService(PersonService personService)
+ {
+ this.personService = personService;
+ }
+
+ /**
+ * Set the authenticationService property
+ *
+ * @param authenticationService
+ * the authentication service to set
+ */
+ public void setAuthenticationService(
+ AuthenticationService authenticationService)
+ {
+ this.authenticationService = authenticationService;
+ }
+
+ /**
+ * Set the mutable authentication DAO
+ *
+ * @param mutableAuthenticationDao
+ * Mutable Authentication DAO
+ */
+ public void setMutableAuthenticationDao(
+ MutableAuthenticationDao mutableAuthenticationDao)
+ {
+ this.mutableAuthenticationDao = mutableAuthenticationDao;
+ }
+
+ /**
+ * Set the user name generator service
+ *
+ * @param userNameGenerator
+ * the user name generator
+ */
+ public void setUserNameGenerator(UserNameGenerator userNameGenerator)
+ {
+ this.usernameGenerator = userNameGenerator;
+ }
+
+ /**
+ * Set the password generator service
+ *
+ * @param passwordGenerator
+ * the password generator
+ */
+ public void setPasswordGenerator(PasswordGenerator passwordGenerator)
+ {
+ this.passwordGenerator = passwordGenerator;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco
+ * .web.scripts.WebScriptRequest,
+ * org.alfresco.web.scripts.WebScriptResponse)
+ */
+ @Override
+ protected Map executeImpl(WebScriptRequest req,
+ Status status)
+ {
+ // initialise model to pass on for template to render
+ Map model = new HashMap();
+
+ // extract action string from URL
+ String servicePath = req.getServicePath();
+ String action = null;
+ int actionStartIndex = servicePath.lastIndexOf("/") + 1;
+ if (actionStartIndex <= servicePath.length() - 1)
+ {
+ action = servicePath.substring(actionStartIndex, servicePath
+ .length());
+ }
+
+ // check that the action has been provided on the URL
+ // and that URL parameters have been provided
+ if ((action == null) || (action.length() == 0))
+ {
+ // handle action not provided on URL
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "Action has not been provided in URL");
+ }
+
+ // handle no parameters given on URL
+ if ((req.getParameterNames() == null) || (req.getParameterNames().length == 0))
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "No parameters have been provided on URL");
+ }
+
+ // handle action 'start'
+ if (action.equals(ACTION_START))
+ {
+ // check for 'inviteeEmail' parameter not provided
+ String inviteeEmail = req.getParameter(PARAM_INVITEE_EMAIL);
+ if ((inviteeEmail == null) || (inviteeEmail.length() == 0))
+ {
+ // handle inviteeEmail URL parameter not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "'inviteeEmail' parameter "
+ + "has not been provided in URL for action '"
+ + ACTION_START + "'");
+ }
+
+ // check for 'siteShortName' parameter not provided
+ String siteShortName = req.getParameter(PARAM_SITE_SHORT_NAME);
+ if ((siteShortName == null) || (siteShortName.length() == 0))
+ {
+ // handle siteShortName URL parameter not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "'siteShortName' parameter "
+ + "has not been provided in URL for action '"
+ + ACTION_START + "'");
+ }
+
+ // process action 'start' with provided parameters
+ startInvite(model, inviteeEmail, siteShortName);
+ }
+ // else handle if provided 'action' is 'cancel'
+ else if (action.equals(ACTION_CANCEL))
+ {
+ // check for 'workflowId' parameter not provided
+ String workflowId = req.getParameter(PARAM_WORKFLOW_ID);
+ if ((workflowId == null) || (workflowId.length() == 0))
+ {
+ // handle workflowId URL parameter not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "'workflowId' parameter has "
+ + "not been provided in URL for action '"
+ + ACTION_CANCEL + "'");
+ }
+
+ // process action 'cancel' with provided parameters
+ cancelInvite(model, workflowId);
+ }
+ // handle action not recognised
+ else
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Action, '"
+ + action + "', "
+ + "provided in URL has not been recognised.");
+ }
+
+ return model;
+ }
+
+ /**
+ * Starts the Invite workflow
+ *
+ * @param model
+ * model to add objects to, which will be passed to the template
+ * for rendering
+ * @param inviteeEmail
+ * email address of invitee
+ * @param siteShortName
+ * short name of site that the invitee is being invited to by the
+ * inviter
+ *
+ */
+ private void startInvite(Map model, String inviteeEmail,
+ String siteShortName)
+ {
+ WorkflowDefinition wfDefinition = this.workflowService
+ .getDefinitionByName(WORKFLOW_DEFINITION_NAME);
+
+ // handle workflow definition does not exist
+ if (wfDefinition == null)
+ {
+ throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
+ "Workflow definition " + "for name "
+ + WORKFLOW_DEFINITION_NAME + " does not exist");
+ }
+
+ char[] generatedPassword = null;
+
+ // generate user name
+ String inviteeUserName = usernameGenerator.generateUserName();
+
+ // create person if user name does not already exist
+ if (!this.personService.personExists(inviteeUserName))
+ {
+ Map properties = new HashMap();
+
+ properties.put(ContentModel.PROP_USERNAME, inviteeUserName);
+ properties.put(ContentModel.PROP_EMAIL, inviteeEmail);
+
+ this.personService.createPerson(properties);
+ } else
+ {
+ throw new WebScriptException(
+ Status.STATUS_INTERNAL_SERVER_ERROR,
+ "When trying to create a user account for Invitee with generated user name, "
+ + inviteeUserName
+ + ", a person was found who already has that user name");
+ }
+
+ // create invitee person with generated user name and password, and with
+ // a disabled user account (with a generated password)
+
+ // generate password
+ generatedPassword = passwordGenerator.generatePassword().toCharArray();
+
+ // create account for person with generated userName and
+ // password
+ mutableAuthenticationDao.createUser(inviteeUserName, generatedPassword);
+ mutableAuthenticationDao.setEnabled(inviteeUserName, false);
+
+ // create workflow properties
+ Map workflowProps = new HashMap(
+ 4);
+ workflowProps.put(QName.createQName(WF_PROP_INVITER_USER_NAME),
+ this.authenticationService.getCurrentUserName());
+ workflowProps.put(QName.createQName(WF_PROP_INVITEE_USER_NAME),
+ inviteeUserName);
+ workflowProps.put(QName.createQName(WF_PROP_INVITEE_GEN_PASSWORD),
+ generatedPassword);
+ workflowProps.put(QName.createQName(WF_PROP_SITE_SHORT_NAME), siteShortName);
+
+ // start the workflow
+ WorkflowPath wfPath = this.workflowService.startWorkflow(wfDefinition
+ .getId(), workflowProps);
+ String workflowId = wfPath.instance.id;
+
+ // send out the invite
+ this.workflowService.signal(wfPath.id, TRANSITION_SEND_INVITE);
+
+ // add model properties for template to render
+ model.put(MODEL_PROP_KEY_ACTION, ACTION_START);
+ model.put(MODEL_PROP_KEY_WORKFLOW_ID, workflowId);
+ model.put(MODEL_PROP_KEY_INVITEE_USER_NAME, inviteeUserName);
+ model.put(MODEL_PROP_KEY_SITE_SHORT_NAME, siteShortName);
+ }
+
+ /**
+ * Cancels pending invite. Note that only the Inviter should cancel the
+ * pending invite.
+ *
+ * @param model
+ * model to add objects to, which will be passed to the template
+ * for rendering
+ * @param workflowId
+ * workflow id of the invite process that inviter wishes to
+ * cancel
+ */
+ private void cancelInvite(Map model, String workflowId)
+ {
+ // handle workflow instance for given workflow ID does not exist
+ if ((workflowId == null) || (workflowId.length() == 0))
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "Workflow instance for given " + "workflow ID "
+ + workflowId + " does not exist");
+ }
+
+ // cancel the workflow
+ this.workflowService.cancelWorkflow(workflowId);
+
+ // add model properties for template to render
+ model.put(MODEL_PROP_KEY_ACTION, ACTION_CANCEL);
+ model.put(MODEL_PROP_KEY_WORKFLOW_ID, workflowId);
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/invite/InviteInfo.java b/source/java/org/alfresco/repo/web/scripts/invite/InviteInfo.java
new file mode 100644
index 0000000000..4d49047294
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/invite/InviteInfo.java
@@ -0,0 +1,88 @@
+/*
+ * 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;
+
+/**
+ * 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
+{
+ // private instances to hold property values
+ private String inviterUserName;
+ private String inviteeUserName;
+ private String siteShortName;
+ private String inviteId;
+
+ public InviteInfo(String inviterUserName, String inviteeUserName, String siteShortName, String inviteId)
+ {
+ this.inviterUserName = inviterUserName;
+ this.inviteeUserName = inviteeUserName;
+ this.siteShortName = siteShortName;
+ 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;
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java b/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java
new file mode 100644
index 0000000000..ad248888a9
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java
@@ -0,0 +1,237 @@
+/*
+ * 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.MutableAuthenticationDao;
+import org.alfresco.repo.site.SiteModel;
+import org.alfresco.repo.site.SiteService;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+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 invoked by Invitee to either accept (response='accept') an
+ * invitation from a Site Manager (Inviter) to join a Site as a Site
+ * Collaborator, or to reject (response='reject') an invitation that has
+ * already been sent out
+ *
+ * @author glen dot johnson at alfresco dot com
+ */
+public class InviteResponse extends DeclarativeWebScript
+{
+ private static final String RESPONSE_ACCEPT = "accept";
+ private static final String RESPONSE_REJECT = "reject";
+ private static final String TRANSITION_ACCEPT = "accept";
+ private static final String TRANSITION_REJECT = "reject";
+ private static final String MODEL_PROP_KEY_RESPONSE = "response";
+ private static final String MODEL_PROP_KEY_SITE_SHORT_NAME = "siteShortName";
+
+ // properties for services
+ private WorkflowService workflowService;
+ private MutableAuthenticationDao mutableAuthenticationDao;
+ private SiteService siteService;
+ private PersonService personService;
+
+ /**
+ * Sets the workflow service property
+ *
+ * @param workflowService
+ * the workflow service instance assign to the property
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ /**
+ * Sets the mutableAuthenticationDao service property
+ *
+ * @param mutableAuthenticationDao
+ * the MutableAuthenticationDao service to set
+ */
+ public void setMutableAuthenticationDao(
+ MutableAuthenticationDao mutableAuthenticationDao)
+ {
+ this.mutableAuthenticationDao = mutableAuthenticationDao;
+ }
+
+ /**
+ * Sets the siteService property
+ *
+ * @param siteService
+ * the siteService to set
+ */
+ public void setSiteService(SiteService siteService)
+ {
+ this.siteService = siteService;
+ }
+
+ /**
+ * Sets the personService property
+ *
+ * @param personService
+ * the person service to set
+ */
+ public void setPersonService(PersonService personService)
+ {
+ this.personService = personService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco
+ * .web.scripts.WebScriptRequest,
+ * org.alfresco.web.scripts.WebScriptResponse)
+ */
+ @Override
+ protected Map executeImpl(WebScriptRequest req,
+ Status status)
+ {
+ // initialise model to pass on for template to render
+ Map model = new HashMap();
+
+ // get the URL parameter values
+ String workflowId = req.getParameter("workflowId");
+ String inviteeUserName = req.getParameter("inviteeUserName");
+ String siteShortName = req.getParameter("siteShortName");
+
+ // get the invite response value
+ String response = req.getExtensionPath();
+
+ // check that response has been provided
+ if ((response == null) || (response.length() == 0))
+ {
+ // handle response not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "response has not been provided as part of URL.");
+ }
+ // check that workflow id URL parameter has been provided
+ else if ((workflowId == null) || (workflowId.length() == 0))
+ {
+ // handle workflow id not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "workflow 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
+ if (response.equals(RESPONSE_ACCEPT))
+ {
+ acceptInvite(model, workflowId, inviteeUserName, siteShortName);
+ } else if (response.equals(RESPONSE_REJECT))
+ {
+ rejectInvite(model, workflowId, inviteeUserName, siteShortName);
+ } else
+ {
+ /* handle unrecognised response */
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "response, " + response
+ + ", provided in URL has not been recognised.");
+ }
+ }
+
+ return model;
+ }
+
+ /**
+ * Processes 'accept' response from invitee
+ *
+ * @param model
+ * model to add objects to, which will be passed to the template
+ * for rendering
+ * @param workflowId
+ * string id of invite process workflow instance
+ * @param inviteeUserName
+ * string user name of invitee
+ * @param siteShortName
+ * string short name of site for which invitee is accepting
+ * invitation to join
+ */
+ private void acceptInvite(Map model, String workflowId,
+ String inviteeUserName, String siteShortName)
+ {
+ this.workflowService.signal(workflowId, TRANSITION_ACCEPT);
+
+ // enable invitee person's user account because he/she has accepted the
+ // site invitation
+ this.mutableAuthenticationDao.setEnabled(inviteeUserName, true);
+
+ // Add Invitee to Site as "Site Collaborator" role
+ this.siteService.setMembership(siteShortName, inviteeUserName,
+ SiteModel.SITE_COLLABORATOR);
+
+ // add model properties for template to render
+ model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_ACCEPT);
+ model.put(MODEL_PROP_KEY_SITE_SHORT_NAME, siteShortName);
+ }
+
+ /**
+ * Processes 'reject' invite response from invitee
+ *
+ * @param model
+ * model to add objects to, which will be passed to the template
+ * for rendering
+ * @param workflowId
+ * string id of invite process workflow instance
+ * @param inviteeUserName
+ * string user name of invitee
+ * @param siteShortName
+ * string short name of site for which invitee is rejecting
+ * invitation to join
+ */
+ private void rejectInvite(Map model, String workflowId,
+ String inviteeUserName, String siteShortName)
+ {
+ this.workflowService.signal(workflowId, TRANSITION_REJECT);
+
+ // delete the person created for invitee
+ this.personService.deletePerson(inviteeUserName);
+
+ // add model properties for template to render
+ model.put(MODEL_PROP_KEY_RESPONSE, RESPONSE_REJECT);
+ model.put(MODEL_PROP_KEY_SITE_SHORT_NAME, siteShortName);
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/invite/Invites.java b/source/java/org/alfresco/repo/web/scripts/invite/Invites.java
new file mode 100644
index 0000000000..e6aa489ece
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/invite/Invites.java
@@ -0,0 +1,200 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
+import org.alfresco.service.namespace.QName;
+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 either
+ * (1) Site invitations pending against a given
+ * person (user name). i.e. including both invitations which have been sent
+ * by that person (inviter) which have not been responded to (accepted or rejected)
+ * by the recipient (invitee), and also invitations which have been received by that
+ * person, but which he/she hasn't responded to yet.
+ * (2) Invitations pending against a given site (site short name)
+ * invoked by a Site Manager (Inviter) to either send
+ * (action='start') an invitation to a another person (Invitee) to join a Site
+ * as a Site Collaborator, or to cancel (action='cancel') a pending invitation
+ * that has already been sent out
+ *
+ * @author glen dot johnson at alfresco dot com
+ */
+public class Invites extends DeclarativeWebScript
+{
+ // request parameter names
+ private static final String PARAM_INVITER_USER_NAME = "inviterUserName";
+ private static final String PARAM_INVITEE_USER_NAME = "inviteeUserName";
+ private static final String PARAM_SITE_SHORT_NAME = "siteShortName";
+
+ // service instances
+ private WorkflowService workflowService;
+
+ // invite process definition name
+ private static final QName WF_INVITE_PROCESS_DEFINITION_QNAME = QName.createQName("wf:invite");
+
+ // model key names
+ private static final String MODEL_KEY_NAME_INVITES = "invites";
+
+ /**
+ * Set the workflow service property
+ *
+ * @param workflowService the workflow service to set
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco
+ * .web.scripts.WebScriptRequest,
+ * org.alfresco.web.scripts.WebScriptResponse)
+ */
+ @Override
+ protected Map executeImpl(WebScriptRequest req,
+ Status status)
+ {
+ // initialise model to pass on for template to render
+ Map model = new HashMap();
+ // Get parameter names
+ String[] paramNames = req.getParameterNames();
+
+ // handle no parameters given on URL
+ if ((paramNames == null) || (paramNames.length == 0))
+ {
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "No parameters have been provided on URL");
+ }
+
+ // get URL request parameters
+
+ String inviterUserName = req.getParameter(PARAM_INVITER_USER_NAME);
+ // check for 'inviterUserName' parameter not provided
+ if ((inviterUserName == null) || (inviterUserName.length() == 0))
+ {
+ // handle inviterUserName URL parameter not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "'inviterUserName' parameter has not been provided in URL");
+ }
+
+ String inviteeUserName = req.getParameter(PARAM_INVITEE_USER_NAME);
+ // check for 'inviteeUserName' parameter not provided
+ if ((inviteeUserName == null) || (inviteeUserName.length() == 0))
+ {
+ // handle inviteeUserName URL parameter not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "'inviteeUserName' parameter has not been provided in URL");
+ }
+
+ String siteShortName = req.getParameter(PARAM_SITE_SHORT_NAME);
+ // check for 'siteShortName' parameter not provided
+ if ((siteShortName == null) || (siteShortName.length() == 0))
+ {
+ // handle siteShortName URL parameter not provided
+ throw new WebScriptException(Status.STATUS_BAD_REQUEST,
+ "'siteShortName' parameter has not been provided in URL");
+ }
+
+ // query for workflow tasks by given parameters
+ // create workflow task query
+ WorkflowTaskQuery wfTaskQuery = new WorkflowTaskQuery();
+
+ // query only active workflows
+ wfTaskQuery.setActive(Boolean.TRUE);
+
+ // create the query properties from the invite URL request parameters
+ // - because this web script class will terminate if no invite URL request
+ // - parameters are set, at least one of these query properties will always be set
+ final HashMap wfQueryProps = new HashMap(3, 1.0f);
+ if (inviterUserName != null)
+ {
+ wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITER_USER_NAME), inviterUserName);
+ }
+ if (inviteeUserName != null)
+ {
+ wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITER_USER_NAME), inviteeUserName);
+ }
+ if (siteShortName != null)
+ {
+ wfQueryProps.put(QName.createQName(Invite.WF_PROP_INVITER_USER_NAME), siteShortName);
+ }
+
+ // set workflow task query parameters
+ wfTaskQuery.setProcessCustomProps(wfQueryProps);
+
+ // set process name to "wf:invite" so that only tasks associated with invite workflow instances
+ // are returned by query
+ wfTaskQuery.setProcessName(WF_INVITE_PROCESS_DEFINITION_QNAME);
+
+ // query for invite workflow tasks
+ List wf_invite_tasks = this.workflowService.queryTasks(wfTaskQuery);
+
+ // InviteInfo List to place onto model
+ List inviteInfoList = new ArrayList();
+
+ // Put InviteInfo object (containing workflow path properties
+ // wf:inviteUserName, wf:inviterUserName, wf:siteShortName,
+ // and invite id property (from workflow instance id))
+ // for each invite workflow task returned by the query
+ // onto model (that is passed onto the template for rendering)
+ for (WorkflowTask workflowTask : wf_invite_tasks)
+ {
+ // get wf:inviterUserName, wf:inviteeUserName, wf:siteShortName
+ // properties from workflow path associated with workflow task
+ Map pathProperties = this.workflowService.getPathProperties(workflowTask.path.id);
+ String inviterUserNameProp = (String)pathProperties.get(Invite.WF_PROP_INVITER_USER_NAME);
+ String inviteeUserNameProp = (String)pathProperties.get(Invite.WF_PROP_INVITEE_USER_NAME);
+ String siteShortNameProp = (String)pathProperties.get(Invite.WF_PROP_SITE_SHORT_NAME);
+
+ // get workflow instance id (associated with workflow task) to place as "inviteId" onto model
+ String workflowId = workflowTask.path.instance.id;
+
+ // create and add InviteInfo to inviteInfoList
+ InviteInfo inviteInfo = new InviteInfo(inviterUserNameProp, inviteeUserNameProp, siteShortNameProp, workflowId);
+ inviteInfoList.add(inviteInfo);
+ }
+
+ // put the list of invite infos onto model to be passed onto template for rendering
+ model.put(MODEL_KEY_NAME_INVITES, inviteInfoList);
+
+ return model;
+ }
+}