From f4da392bc340015bdc30f8fde72d1f5634d747c8 Mon Sep 17 00:00:00 2001 From: Glen Johnson Date: Wed, 20 Aug 2008 09:06:13 +0000 Subject: [PATCH] Change to Invite Service so that 'start invite' operation receives a given invitee site role and 'accept invite' picks it off the workflow and sets the invitee's site membership with that role git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10435 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repository/invite/invite.get.desc.xml | 2 +- .../workflow/invite-workflow-model.xml | 3 + .../repo/web/scripts/invite/Invite.java | 20 +++- .../web/scripts/invite/InviteResponse.java | 98 ++++++++++++++++--- .../web/scripts/invite/InviteServiceTest.java | 41 ++++---- 5 files changed, 128 insertions(+), 36 deletions(-) diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invite.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invite.get.desc.xml index 2c790c244f..98f539a388 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invite.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/invite/invite.get.desc.xml @@ -1,7 +1,7 @@ Invite Processes Inviter actions ('start' or 'cancel' invite) - /api/invite/start?inviteeFirstName={inviteeFirstName}&inviteeLastName={inviteeLastName}&inviteeEmail={inviteeEmailAddress}&siteShortName={siteShortName} + /api/invite/start?inviteeFirstName={inviteeFirstName}&inviteeLastName={inviteeLastName}&inviteeEmail={inviteeEmailAddress}&siteShortName={siteShortName}&inviteeSiteRole={inviteeSiteRole} /api/invite/cancel?inviteId={inviteId} user diff --git a/config/alfresco/workflow/invite-workflow-model.xml b/config/alfresco/workflow/invite-workflow-model.xml index f2fc762333..9158ea79b0 100644 --- a/config/alfresco/workflow/invite-workflow-model.xml +++ b/config/alfresco/workflow/invite-workflow-model.xml @@ -36,6 +36,9 @@ d:text + + d:text + diff --git a/source/java/org/alfresco/repo/web/scripts/invite/Invite.java b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java index 5e2a438a4e..8ba74c730f 100644 --- a/source/java/org/alfresco/repo/web/scripts/invite/Invite.java +++ b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java @@ -82,6 +82,7 @@ public class Invite extends DeclarativeWebScript private static final String PARAM_INVITEE_EMAIL = "inviteeEmail"; private static final String PARAM_SITE_SHORT_NAME = "siteShortName"; private static final String PARAM_INVITE_ID = "inviteId"; + private static final String PARAM_INVITEE_SITE_ROLE = "inviteeSiteRole"; // services private WorkflowService workflowService; @@ -103,6 +104,7 @@ public class Invite extends DeclarativeWebScript public static final String WF_PROP_INVITEE_FIRSTNAME = "wf:inviteeFirstName"; public static final String WF_PROP_INVITEE_LASTNAME = "wf:inviteeLastName"; public static final String WF_PROP_SITE_SHORT_NAME = "wf:siteShortName"; + public static final String WF_PROP_INVITEE_SITE_ROLE = "wf:inviteeSiteRole"; private static final String WF_PROP_INVITEE_GEN_PASSWORD = "wf:inviteeGenPassword"; public static final String WF_INVITE_TASK_INVITE_TO_SITE = "wf:inviteToSiteTask"; @@ -301,11 +303,21 @@ public class Invite extends DeclarativeWebScript + ACTION_START + "'"); } + // check for 'inviteeSiteRole' parameter not provided + String inviteeSiteRole = req.getParameter(PARAM_INVITEE_SITE_ROLE); + if ((inviteeSiteRole == null) || (inviteeSiteRole.length() == 0)) + { + // handle inviteeSiteRole URL parameter not provided + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "'inviteeSiteRole' parameter has not been provided in URL for action '" + + ACTION_START + "'"); + } + // get externally reachable address of server hosting invite web scripts String serverPath = req.getServerPath(); // process action 'start' with provided parameters - startInvite(model, inviteeFirstName, inviteeLastName, inviteeEmail, siteShortName, serverPath); + startInvite(model, inviteeFirstName, inviteeLastName, inviteeEmail, siteShortName, inviteeSiteRole, serverPath); } // else handle if provided 'action' is 'cancel' else if (action.equals(ACTION_CANCEL)) @@ -453,11 +465,13 @@ public class Invite extends DeclarativeWebScript * @param siteShortName * short name of site that the invitee is being invited to by the * inviter + * @param inviteeSiteRole + * role under which invitee is being invited to the site by the inviter * @param serverPath * externally accessible server address of server hosting invite web scripts */ private void startInvite(Map model, String inviteeFirstName, String inviteeLastName, - String inviteeEmail, String siteShortName, String serverPath) + String inviteeEmail, String siteShortName, String inviteeSiteRole, String serverPath) { // get the inviter user name (the name of user web script is executed under) // - needs to be assigned here because various system calls further on @@ -558,6 +572,8 @@ public class Invite extends DeclarativeWebScript inviteePassword); workflowProps.put(QName.createQName(WF_PROP_SITE_SHORT_NAME, this.namespaceService), siteShortName); + workflowProps.put(QName.createQName(WF_PROP_INVITEE_SITE_ROLE, this.namespaceService), + inviteeSiteRole); workflowProps.put(QName.createQName(WF_PROP_SERVER_PATH, this.namespaceService), serverPath); diff --git a/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java b/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java index 1c9daad8fd..0f9e1c9a19 100644 --- a/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java +++ b/source/java/org/alfresco/repo/web/scripts/invite/InviteResponse.java @@ -31,7 +31,6 @@ import java.util.Map; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.MutableAuthenticationDao; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.site.SiteModel; import org.alfresco.repo.site.SiteService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.workflow.WorkflowService; @@ -258,20 +257,28 @@ public class InviteResponse extends DeclarativeWebScript // the model) out into workflow action class that gets run when task wf:acceptInviteTask // is completed by this web script - // enable invitee person's user account because he/she has accepted the + // 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 - this.mutableAuthenticationDao.setEnabled(inviteeUserName, true); + if ((this.mutableAuthenticationDao.userExists(inviteeUserName)) + && (this.mutableAuthenticationDao.getEnabled(inviteeUserName) == false)) + { + this.mutableAuthenticationDao.setEnabled(inviteeUserName, true); + } - // Add Invitee to Site as "Site Collaborator" role + // retrieve the site role with which the invitee was invited to the site + String inviteeSiteRole = getInviteeSiteRoleFromInvite(inviteId); + + // add Invitee to Site with the site role that the inviter "started" the invite process with RunAsWork setSiteMembershipWorker = new InviteResponse.SetSiteMembershipWorker( - siteShortName, inviteeUserName, SiteModel.SITE_COLLABORATOR); + siteShortName, inviteeUserName, inviteeSiteRole); AuthenticationUtil.runAs(setSiteMembershipWorker, USER_ADMIN); // complete the wf:acceptInviteTask because the operations that need to be performed // when the invitee has accepted the invitation have now been performed (code block - // above up to where wf:invitePendingTask is completed). This code block will soon - // be farmed out into a workflow action which gets executed when wf:acceptInviteTask - // gets completed + // starting from above where wf:invitePendingTask is completed, up to here). This code + // block will soon be farmed out into a workflow action which gets executed when + // wf:acceptInviteTask gets completed completeInviteTask(QName.createQName(WF_TASK_ACCEPT_INVITE, this.namespaceService), WF_TRANSITION_ACCEPT_INVITE_END); // add model properties for template to render @@ -303,14 +310,26 @@ public class InviteResponse extends DeclarativeWebScript // the model) out into workflow action class that gets run when task wf:rejectInviteTask // is completed by this web script - // delete the person created for invitee - this.personService.deletePerson(inviteeUserName); + // if invitee's user account is still disabled then remove the account and + // delete the invitee's person node + if ((this.mutableAuthenticationDao.userExists(inviteeUserName)) + && (this.mutableAuthenticationDao.getEnabled(inviteeUserName) == false)) + { + // delete the invitee's user account + this.mutableAuthenticationDao.deleteUser(inviteeUserName); + + // delete the invitee's person node if one exists + if (this.personService.personExists(inviteeUserName)) + { + this.personService.deletePerson(inviteeUserName); + } + } // complete the wf:rejectInviteTask because the operations that need to be performed // when the invitee has rejected the invitation have now been performed (code block - // above up to where wf:invitePendingTask is completed). This code block will soon - // be farmed out into a workflow action which gets executed when wf:rejectInviteTask - // gets completed + // starting from above where wf:invitePendingTask is completed, up to here). This code + // block will soon be farmed out into a workflow action which gets executed when + // wf:rejectInviteTask gets completed completeInviteTask(QName.createQName(WF_TASK_REJECT_INVITE, this.namespaceService), WF_TRANSITION_REJECT_INVITE_END); // add model properties for template to render @@ -350,4 +369,57 @@ public class InviteResponse extends DeclarativeWebScript this.workflowService.endTask(workflowTask.id, transitionId); } } + + /** + * Gets the invitee site role from the invite + * workflow instance associated with the given invite ID. + * i.e. if the inviter 'starts' an invite (which is allocated some invite ID + * '12345' when it is processed), and that invite is requesting an invitee to + * to join some site under a given site role, then that site role is returned + * by this method when invite ID '12345' is passed in. + * + * @param inviteId the ID of the invitation (invite workflow instance) + * from which to retrieve the invitee site role + * @return the site role under which the invitee was invited to + * join the site. Returns
null
if no invite + * workflow instance was found matching the given invite ID + */ + private String getInviteeSiteRoleFromInvite(String inviteId) + { + // 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("wf:invite", this.namespaceService)); + + // pick up the start task because it has the "wf:inviteeSiteRole" property set with the + // site role value that we want to retrieve + wfTaskQuery.setTaskState(WorkflowTaskState.COMPLETED); + wfTaskQuery.setTaskName(QName.createQName(Invite.WF_INVITE_TASK_INVITE_TO_SITE, this.namespaceService)); + + // query for invite workflow task associate + List inviteStartTasks = this.workflowService + .queryTasks(wfTaskQuery); + + // if no results were returned for given inviteID, then return + // site role as null + if (inviteStartTasks.size() == 0) + { + return null; + } + else + { + // there should be only one start task returned for the given invite ID + // so just take the first one in the list + WorkflowTask inviteStartTask = inviteStartTasks.get(0); + + String inviteeSiteRole = (String) inviteStartTask.properties.get( + QName.createQName(Invite.WF_PROP_INVITEE_SITE_ROLE, this.namespaceService)); + + return inviteeSiteRole; + } + } } diff --git a/source/java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java b/source/java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java index 3cbe95f570..3b7ba0d36a 100644 --- a/source/java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java +++ b/source/java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java @@ -51,7 +51,6 @@ import org.alfresco.util.PropertyMap; import org.alfresco.util.URLEncoder; import org.alfresco.web.scripts.Status; import org.apache.commons.lang.RandomStringUtils; -import org.json.JSONArray; import org.json.JSONObject; import org.springframework.mock.web.MockHttpServletResponse; @@ -86,6 +85,7 @@ public class InviteServiceTest extends BaseWebScriptTest private static final String INVITER_EMAIL = "FirstName123.LastName123@email.com"; private static final String INVITEE_EMAIL_DOMAIN = "alfrescotesting.com"; private static final String INVITEE_EMAIL_PREFIX = "invitee"; + private static final String INVITEE_SITE_ROLE = SiteModel.SITE_COLLABORATOR; private static final String SITE_SHORT_NAME_INVITE_1 = "BananaMilkshakeSite"; private static final String SITE_SHORT_NAME_INVITE_2 = "DoubleScoopSite"; @@ -144,6 +144,7 @@ public class InviteServiceTest extends BaseWebScriptTest "InviteSitePreset", SITE_SHORT_NAME_INVITE_1, "InviteSiteTitle", "InviteSiteDescription", true); } + SiteInfo siteInfo2 = InviteServiceTest.this.siteService .getSite(SITE_SHORT_NAME_INVITE_2); if (siteInfo2 == null) @@ -298,8 +299,8 @@ public class InviteServiceTest extends BaseWebScriptTest } } - private JSONObject startInvite(String inviteeFirstName, - String inviteeLastName, String inviteeEmail, String siteShortName, int expectedStatus) + private JSONObject startInvite(String inviteeFirstName, String inviteeLastName, String inviteeEmail, String inviteeSiteRole, + String siteShortName, int expectedStatus) throws Exception { this.inviteeEmailAddrs.add(inviteeEmail); @@ -309,7 +310,7 @@ public class InviteServiceTest extends BaseWebScriptTest + "?inviteeFirstName=" + inviteeFirstName + "&inviteeLastName=" + inviteeLastName + "&inviteeEmail=" + URLEncoder.encode(inviteeEmail) + "&siteShortName=" - + siteShortName; + + siteShortName + "&inviteeSiteRole=" + inviteeSiteRole; MockHttpServletResponse response = getRequest(startInviteUrl, expectedStatus); @@ -320,7 +321,7 @@ public class InviteServiceTest extends BaseWebScriptTest } private JSONObject startInvite(String inviteeFirstName, - String inviteeLastName, String siteShortName, int expectedStatus) + String inviteeLastName, String inviteeSiteRole, String siteShortName, int expectedStatus) throws Exception { // String inviteeEmail = INVITEE_EMAIL_PREFIX + @@ -328,7 +329,7 @@ public class InviteServiceTest extends BaseWebScriptTest // + "@" + INVITEE_EMAIL_DOMAIN; String inviteeEmail = "glen.johnson@alfresco.com"; - return startInvite(inviteeFirstName, inviteeLastName, inviteeEmail, siteShortName, + return startInvite(inviteeFirstName, inviteeLastName, inviteeEmail, inviteeSiteRole, siteShortName, expectedStatus); } @@ -397,7 +398,7 @@ public class InviteServiceTest extends BaseWebScriptTest public void testStartInvite() throws Exception { - JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, + JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); assertEquals(INVITE_ACTION_START, result.get("action")); @@ -431,45 +432,45 @@ public class InviteServiceTest extends BaseWebScriptTest // add invitee person to site: SITE_SHORT_NAME_INVITE InviteServiceTest.this.siteService.setMembership( SITE_SHORT_NAME_INVITE_1, inviteeUserName, - SiteModel.SITE_COLLABORATOR); + INVITEE_SITE_ROLE); return null; } }, USER_ADMIN); - JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmailAddr, + JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmailAddr, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_CONFLICT); } // public void testStartInviteWhenAlreadyInProgress() // throws Exception // { -// JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, +// JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, INVITEE_SITE_ROLE, // SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // // String inviteeEmail = (String) result.get("inviteeEmail"); // -// startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmail, +// startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmail, INVITEE_SITE_ROLE, // SITE_SHORT_NAME_INVITE_1, Status.STATUS_CONFLICT); // } // public void testStartInviteForSameInviteeButTwoDifferentSites() throws Exception { - JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, + JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); String inviteeEmail = (String) result.get("inviteeEmail"); - startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmail, + startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, inviteeEmail, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_2, Status.STATUS_OK); } public void testCancelInvite() throws Exception { // inviter starts invite workflow - JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, + JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get hold of invite ID of started invite @@ -485,7 +486,7 @@ public class InviteServiceTest extends BaseWebScriptTest public void testAcceptInvite() throws Exception { // inviter starts invite (sends out invitation) - JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, + JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get hold of invite ID of started invite @@ -521,7 +522,7 @@ public class InviteServiceTest extends BaseWebScriptTest public void testRejectInvite() throws Exception { // inviter starts invite (sends out invitation) - JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, + JSONObject result = startInvite(INVITEE_FIRSTNAME, INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get hold of invite ID of started invite @@ -558,7 +559,7 @@ public class InviteServiceTest extends BaseWebScriptTest { // inviter starts invite workflow JSONObject startInviteResult = startInvite(INVITEE_FIRSTNAME, - INVITEE_LASTNAME, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get hold of workflow ID of started invite workflow instance @@ -581,7 +582,7 @@ public class InviteServiceTest extends BaseWebScriptTest { // inviter starts invite workflow JSONObject startInviteResult = startInvite(INVITEE_FIRSTNAME, - INVITEE_LASTNAME, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get pending invites matching inviter user name used in invite started // above @@ -599,7 +600,7 @@ public class InviteServiceTest extends BaseWebScriptTest { // inviter starts invite workflow JSONObject startInviteResult = startInvite(INVITEE_FIRSTNAME, - INVITEE_LASTNAME, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get hold of invitee user name property of started invite workflow // instance @@ -624,7 +625,7 @@ public class InviteServiceTest extends BaseWebScriptTest { // inviter starts invite workflow JSONObject startInviteResult = startInvite(INVITEE_FIRSTNAME, - INVITEE_LASTNAME, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); // get hold of site short name property of started invite workflow // instance