From 1a3013e3f384913dd857f5c29e546a25a6858e9c Mon Sep 17 00:00:00 2001 From: Mark Rogers Date: Wed, 30 Apr 2014 16:10:58 +0000 Subject: [PATCH] Merged HEAD-BUG-FIX (4.3/Cloud) to HEAD (4.3/Cloud) 68126: Merged V4.2-BUG-FIX (4.2.3) to HEAD-BUG-FIX (4.3/Cloud) 67461: Merged V4.1-BUG-FIX (4.1.9) to V4.2-BUG-FIX (4.2.3) 66886: Merged DEV to V4.1-BUG-FIX 66841 : MNT-9905 : Pending Invites created by one site manager aren't visible to other site managers Execute some operation: "Invite/Search", "Pending Invites/Search" and "Pending Invites/Search/Cancel" using 'system' user. Corrected code. Added test. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@68411 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repository/invite/invite.get.desc.xml | 2 +- .../web-scripts-application-context.xml | 1 + .../repo/web/scripts/invite/Invite.java | 38 +++++- .../repo/web/scripts/invite/Invites.java | 27 +++- .../web/scripts/invite/InviteServiceTest.java | 119 ++++++++++++++++-- 5 files changed, 173 insertions(+), 14 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 e9852333e8..8a4b54ef33 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 @@ -2,7 +2,7 @@ Process invite Processes Inviter actions ('start' or 'cancel' invite) /api/invite/start?inviteeFirstName={inviteeFirstName}&inviteeLastName={inviteeLastName}&inviteeEmail={inviteeEmailAddress}&inviteeUserName={inviteeUserName?}&siteShortName={siteShortName}&inviteeSiteRole={inviteeSiteRole}&serverPath={serverPath}&acceptUrl={acceptUrl}&rejectUrl={rejectUrl} - /api/invite/cancel?inviteId={inviteId} + /api/invite/cancel?inviteId={inviteId}&siteShortName={siteShortName} user required diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 53fa81bfb0..312b86c632 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -713,6 +713,7 @@ class="org.alfresco.repo.web.scripts.invite.Invite" parent="webscript"> + 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 9928aea854..c93196137f 100644 --- a/source/java/org/alfresco/repo/web/scripts/invite/Invite.java +++ b/source/java/org/alfresco/repo/web/scripts/invite/Invite.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -21,13 +21,16 @@ package org.alfresco.repo.web.scripts.invite; import java.util.HashMap; import java.util.Map; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.permissions.AccessDeniedException; +import org.alfresco.repo.site.SiteModel; import org.alfresco.service.cmr.invitation.Invitation; import org.alfresco.service.cmr.invitation.InvitationExceptionForbidden; import org.alfresco.service.cmr.invitation.InvitationExceptionUserError; import org.alfresco.service.cmr.invitation.InvitationService; import org.alfresco.service.cmr.invitation.NominatedInvitation; -import org.alfresco.util.UrlUtil; +import org.alfresco.service.cmr.site.SiteService; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.DeclarativeWebScript; import org.springframework.extensions.webscripts.Status; @@ -70,12 +73,17 @@ public class Invite extends DeclarativeWebScript // services private InvitationService invitationService; + private SiteService siteService; public void setInvitationService(InvitationService invitationService) { this.invitationService = invitationService; } + public void setSiteService(SiteService siteService) + { + this.siteService = siteService; + } /* * (non-Javadoc) @@ -260,7 +268,31 @@ public class Invite extends DeclarativeWebScript // process action 'cancel' with provided parameters try { - invitationService.cancel(inviteId); + //MNT-9905 Pending Invites created by one site manager aren't visible to other site managers + String currentUser = AuthenticationUtil.getRunAsUser(); + String siteShortName = req.getParameter(PARAM_SITE_SHORT_NAME); + + if (siteShortName != null && (SiteModel.SITE_MANAGER).equals(siteService.getMembersRole(siteShortName, currentUser))) + { + final String invId = inviteId; + + RunAsWork runAsSystem = new RunAsWork() + { + @Override + public Void doWork() throws Exception + { + invitationService.cancel(invId); + return null; + } + }; + + AuthenticationUtil.runAs(runAsSystem, AuthenticationUtil.getSystemUserName()); + } + else + { + invitationService.cancel(inviteId); + } + // add model properties for template to render model.put(MODEL_PROP_KEY_ACTION, ACTION_CANCEL); model.put(MODEL_PROP_KEY_INVITE_ID, inviteId); diff --git a/source/java/org/alfresco/repo/web/scripts/invite/Invites.java b/source/java/org/alfresco/repo/web/scripts/invite/Invites.java index 78a8cd7493..efb46c71c7 100644 --- a/source/java/org/alfresco/repo/web/scripts/invite/Invites.java +++ b/source/java/org/alfresco/repo/web/scripts/invite/Invites.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -27,6 +27,7 @@ import org.alfresco.repo.invitation.InvitationSearchCriteriaImpl; import org.alfresco.repo.invitation.site.InviteInfo; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.site.SiteModel; import org.alfresco.repo.template.TemplateNode; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.invitation.Invitation; @@ -214,7 +215,29 @@ public class Invites extends DeclarativeWebScript criteria.setResourceName(siteShortName); } - List invitations = invitationService.searchInvitation(criteria); + //MNT-9905 Pending Invites created by one site manager aren't visible to other site managers + String currentUser = AuthenticationUtil.getRunAsUser(); + List invitations; + + if (siteShortNameProvided == true && (SiteModel.SITE_MANAGER).equals(siteService.getMembersRole(siteShortName, currentUser)) && inviterUserNameProvided == false && inviteeUserNameProvided == false) + { + final InvitationSearchCriteriaImpl crit = criteria; + + RunAsWork> runAsSystem = new RunAsWork>() + { + @Override + public List doWork() throws Exception + { + return invitationService.searchInvitation(crit); + } + }; + + invitations = AuthenticationUtil.runAs(runAsSystem, AuthenticationUtil.getSystemUserName()); + } + else + { + invitations = invitationService.searchInvitation(criteria); + } // Put InviteInfo objects (containing workflow path properties // wf:inviterUserName, wf:inviteeUserName, wf:siteShortName, diff --git a/source/test-java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java b/source/test-java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java index 286706f958..bd8234ba31 100644 --- a/source/test-java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java +++ b/source/test-java/org/alfresco/repo/web/scripts/invite/InviteServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -26,6 +26,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.action.executer.MailActionExecuter; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation; +import org.alfresco.repo.invitation.script.ScriptInvitationService; import org.alfresco.repo.invitation.site.InviteInfo; import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory; import org.alfresco.repo.node.archive.NodeArchiveService; @@ -55,6 +56,7 @@ import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.GUID; import org.alfresco.util.PropertyMap; import org.apache.commons.lang.RandomStringUtils; +import org.json.JSONArray; import org.json.JSONObject; import org.springframework.context.ApplicationContext; import org.springframework.core.io.ClassPathResource; @@ -138,6 +140,10 @@ public class InviteServiceTest extends BaseWebScriptTest this.transactionService = (TransactionService) getServer().getApplicationContext() .getBean("TransactionService"); this.nodeArchiveService = (NodeArchiveService)getServer().getApplicationContext().getBean("nodeArchiveService"); + ScriptInvitationService scriptInvitationService = (ScriptInvitationService) getServer().getApplicationContext().getBean("invitationServiceScript"); + scriptInvitationService.setSiteService(this.siteService); + Invite invite = (Invite) getServer().getApplicationContext().getBean("webscript.org.alfresco.repository.invite.invite.get"); + invite.setSiteService(this.siteService); configureMailExecutorForTestMode(this.getServer()); @@ -443,12 +449,15 @@ public class InviteServiceTest extends BaseWebScriptTest expectedStatus); } - private JSONObject cancelInvite(String inviteId, int expectedStatus) throws Exception + private JSONObject cancelInvite(String inviteId, String siteShortName, int expectedStatus) throws Exception { - String cancelInviteUrl = URL_INVITE + "/" - + INVITE_ACTION_CANCEL + "?inviteId=" + inviteId; - - Response response = sendRequest(new GetRequest(cancelInviteUrl), expectedStatus);; + String cancelInviteUrl = URL_INVITE + "/" + INVITE_ACTION_CANCEL + "?inviteId=" + inviteId; + if (siteShortName != null && !siteShortName.isEmpty()) + { + cancelInviteUrl = cancelInviteUrl + "&siteShortName=" + siteShortName; + } + Response response = sendRequest(new GetRequest(cancelInviteUrl), expectedStatus); + ; JSONObject result = new JSONObject(response.getContentAsString()); return result; @@ -522,6 +531,19 @@ public class InviteServiceTest extends BaseWebScriptTest return result; } + private JSONObject listInvitations(String siteShortName, String userNameSearch, int expectedStatus) throws Exception + { + // construct get invites URL + String getInvitesUrl = "/api/sites/" + siteShortName + "/potentialmembers?authorityType=USER&sortBy=fullName&dir=asc&filter=" + userNameSearch + "&maxResults=250"; + + // invoke get invites web script + Response response = sendRequest(new GetRequest(getInvitesUrl), expectedStatus); + + JSONObject result = new JSONObject(response.getContentAsString()); + + return result; + } + private JSONObject getInviteInfo(String inviteId, String inviteTicket, String inviteeUid) throws Exception { String url = "/api/invite/" + inviteId + "/" + inviteTicket + "?inviteeUserName=" + inviteeUid; @@ -633,7 +655,7 @@ public class InviteServiceTest extends BaseWebScriptTest String inviteId = result.getString("inviteId"); // Inviter cancels pending invitation - cancelInvite(inviteId, Status.STATUS_OK); + cancelInvite(inviteId, null, Status.STATUS_OK); } public void testAcceptInvite() throws Exception @@ -855,7 +877,7 @@ public class InviteServiceTest extends BaseWebScriptTest // when inviter 2 (who is not Site Manager of the given site) tries to cancel invite // http status FORBIDDEN must be returned AuthenticationUtil.setFullyAuthenticatedUser(USER_INVITER_2); - cancelInvite(inviteId, Status.STATUS_FORBIDDEN); + cancelInvite(inviteId, null, Status.STATUS_FORBIDDEN); } public void testInviteeResourcesDeletedUponRejectWhenNoInvitePending() throws Exception @@ -967,4 +989,85 @@ public class InviteServiceTest extends BaseWebScriptTest // Should return bad request since the email address has not been provided startInvite(PERSON_FIRSTNAME, PERSON_LASTNAME, emailAddress, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_1, 400); } + + public void testMNT9905() throws Exception + { + String[] managerUsersArr = { "user1", "user2" }; + String[] allUsersArr = { "user1", "user2", "user3", "user4" }; + String collaborator = "user3"; + + try + { + // create users + for (String user : allUsersArr) + { + final String userName = user; + ; + + // Create a person with a blank email address and + AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() throws Exception + { + createPerson(userName, userName, userName, " "); + return null; + } + + }, AuthenticationUtil.getSystemUserName()); + } + + // add manager to site + for (String manager : managerUsersArr) + { + String manag = manager; + + startInvite(manag, manag, SiteModel.SITE_MANAGER, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + siteService.setMembership(SITE_SHORT_NAME_INVITE_1, manag, SiteModel.SITE_MANAGER); + } + + InviteServiceTest.this.authenticationComponent.setCurrentUser(managerUsersArr[0]); + JSONObject collInv = startInvite(collaborator, collaborator, SiteModel.SITE_COLLABORATOR, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + siteService.setMembership(SITE_SHORT_NAME_INVITE_1, collaborator, SiteModel.SITE_COLLABORATOR); + + // get pending invites matching inviter user name used in invite started + InviteServiceTest.this.authenticationComponent.setCurrentUser(managerUsersArr[1]); + JSONObject getInvitesResult = getInvitesBySiteShortName(SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + assertEquals(true, getInvitesResult.length() == 1); + + // get site member + JSONObject userList = listInvitations(SITE_SHORT_NAME_INVITE_1, "user", Status.STATUS_OK); + JSONArray inviteJSONArr = userList.getJSONArray("people"); + List siteUsers = new ArrayList(); + for (int i = 0; i < inviteJSONArr.length(); i++) + { + String userName = (String) inviteJSONArr.getJSONObject(i).get("userName"); + + if (userName != null) + { + String role = siteService.getMembersRole(SITE_SHORT_NAME_INVITE_1, userName); + if (role != null) + { + siteUsers.add(userName); + } + } + } + assertEquals(3, siteUsers.size()); + + // cancel invite different manager + String inviteId = (String) collInv.get("inviteId"); + cancelInvite(inviteId, SITE_SHORT_NAME_INVITE_1, Status.STATUS_OK); + } + finally + { + AuthenticationUtil.setRunAsUserSystem(); + + // delete users + for (String user : allUsersArr) + { + deletePersonByUserName(user); + } + + deletePersonByUserName(collaborator); + } + } }