Merged 5.2.N (5.2.2) to HEAD (5.2)

135255 arebegea: MNT-17427 : api/invite/cancel deletes records in the database with a GET: CSRF/XSS attack
      - delete the script/org/alfresco/repository/invite/invite.get
      - use the alternatives: script/org/alfresco/repository/site/invitation/invitation.post and script/org/alfresco/repository/site/invitation/invitation.delete
      - updating the tests
      - updating the controller for the invitation.delete to a java controller
      - fix test fallout (SiteServiceTest testInviteDisabledUser - expected error status code)
      - improve security by allowing only invitationIDs that belong the the site passed as parameter to be canceled
      - be consistent and return 404 when an invitationID can not be found


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137384 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrei Rebegea
2017-06-14 17:02:29 +00:00
parent 99e41785ad
commit c1270defd1
12 changed files with 665 additions and 780 deletions

View File

@@ -25,37 +25,39 @@
*/
package org.alfresco.repo.web.scripts.invitation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.invitation.InvitationServiceImpl;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.repo.web.scripts.invite.InviteServiceTest;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.GUID;
import org.alfresco.util.PropertyMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.invitation.InvitationServiceImpl;
import org.alfresco.repo.invitation.WorkflowModelNominatedInvitation;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.repo.web.scripts.invite.InviteServiceTest;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.GUID;
import org.alfresco.util.PropertyMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest;
import org.springframework.extensions.webscripts.TestWebScriptServer.Response;
/**
@@ -498,25 +500,25 @@ public class InvitationWebScriptTest extends BaseWebScriptTest
// Reset back to default
this.invitationServiceImpl.setNominatedInvitationWorkflowId(
WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI_ADD_DIRECT);
}
private void checkJSONInvitations(JSONArray data) throws JSONException
{
for (int i = 0; i < data.length(); i++)
{
JSONObject invitation = data.getJSONObject(i);
String userId = invitation.getString("inviteeUserName");
// Check invitee info for Nominated invitation.
Map<String, String> expectedProps = userProperties.get(userId);
JSONObject invitee = invitation.getJSONObject("invitee");
assertNotNull(invitee);
assertEquals("User name is wrong for user: " + i, userId, invitee.getString("userName"));
assertEquals("Avatar URI is wrong for user: " + i, expectedProps.get("avatar"), invitee.getString("avatar"));
assertEquals("First name is wrong!", expectedProps.get("firstName"), invitee.getString("firstName"));
assertEquals("Last name is wrong!", expectedProps.get("lastName"), invitee.getString("lastName"));
}
}
}
private void checkJSONInvitations(JSONArray data) throws JSONException
{
for (int i = 0; i < data.length(); i++)
{
JSONObject invitation = data.getJSONObject(i);
String userId = invitation.getString("inviteeUserName");
// Check invitee info for Nominated invitation.
Map<String, String> expectedProps = userProperties.get(userId);
JSONObject invitee = invitation.getJSONObject("invitee");
assertNotNull(invitee);
assertEquals("User name is wrong for user: " + i, userId, invitee.getString("userName"));
assertEquals("Avatar URI is wrong for user: " + i, expectedProps.get("avatar"), invitee.getString("avatar"));
assertEquals("First name is wrong!", expectedProps.get("firstName"), invitee.getString("firstName"));
assertEquals("Last name is wrong!", expectedProps.get("lastName"), invitee.getString("lastName"));
}
}
public static String makeAvatar(final NodeService nodeService, final NodeRef person)
{
@@ -563,7 +565,70 @@ public class InvitationWebScriptTest extends BaseWebScriptTest
createdInvitations.add(new Tracker(inviteId, siteName));
return inviteId;
}
}
public void testDeleteInvitation() throws Exception
{
String nominatedId = null;
String shortNameSiteA = GUID.generate();
// Create a site where the action will take place
createSite("myPreset", shortNameSiteA, "myTitle", "myDescription", SiteVisibility.PUBLIC, 200);
// create an invitation for an external user
{
String inviteeFirstName = "Buffy" + GUID.generate();
String inviteeLastName = "Summers";
String inviteeEmail = "inviteeVA3Rtu@alfrescotesting.com";
// set null in order to create an InvitationWorkflowType.NOMINATED_EXTERNAL invitation
String inviteeUserName = null;
String serverPath = "http://localhost:8081/share/";
String acceptURL = "page/accept-invite";
String rejectURL = "page/reject-invite";
// Create an external nominated invitation on SiteA
nominatedId = createNominatedInvitation(shortNameSiteA, inviteeFirstName, inviteeLastName, inviteeEmail, inviteeUserName,
SiteModel.SITE_COLLABORATOR, serverPath, acceptURL, rejectURL);
}
// search for all invitations to site A: one nominated should be found for user Buffy... Summers
{
JSONArray data = queryCurrentInvitationList(shortNameSiteA);
assertEquals("Wrong number of invitations!", 1, data.length());
JSONObject nominatedInv = getInvitation(nominatedId, data);
assertNotNull("Nominated invitation to Site A not present!", nominatedInv);
}
// now delete it
deleteInvitation(nominatedId, shortNameSiteA, 200);
// list the pending invitations and check that it is empty
{
JSONArray data = queryCurrentInvitationList(shortNameSiteA);
assertEquals("Wrong number of invitations!", 0, data.length());
JSONObject nominatedInv = getInvitation(nominatedId, data);
assertNull("Nominated invitation to Site A present!", nominatedInv);
}
// deleting the invitation was successful
}
private JSONArray queryCurrentInvitationList(String shortNameSiteA) throws IOException, JSONException, UnsupportedEncodingException
{
String allSiteAUrl = URL_SITES + "/" + shortNameSiteA + "/invitations";
Response response = sendRequest(new GetRequest(allSiteAUrl), 200);
JSONObject top = new JSONObject(response.getContentAsString());
return top.getJSONArray("data");
}
void deleteInvitation(String invitationID, String siteShortName, int expectedStatus) throws Exception
{
assertNotNull(invitationID);
assertNotNull(siteShortName);
assertFalse(invitationID.isEmpty());
assertFalse(siteShortName.isEmpty());
Response response = sendRequest(new DeleteRequest(URL_SITES + "/" + siteShortName + "/invitations/" + invitationID), expectedStatus);
assertNotNull(new JSONObject(response.getContentAsString()));
}
private String createModeratedInvitation(String siteName, String inviteeComments, String inviteeUserName,
String inviteeRoleName) throws Exception