Package org.apache.sling.launchpad.webapp.integrationtest.servlets.post

Source Code of org.apache.sling.launchpad.webapp.integrationtest.servlets.post.PostServletPrivilegesUpdateTest$TestEventListener

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.launchpad.webapp.integrationtest.servlets.post;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.testing.integration.HttpTest;
import org.apache.sling.commons.testing.integration.NameValuePairList;
import org.apache.sling.commons.testing.junit.categories.JackrabbitOnly;
import org.apache.sling.launchpad.webapp.integrationtest.AuthenticatedTestUtil;
import org.apache.sling.servlets.post.SlingPostConstants;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TestName;

public class PostServletPrivilegesUpdateTest {
    public static final String TEST_BASE_PATH = "/sling-tests";
    private String postUrl;
  private String testUserId = null;
 
  private final AuthenticatedTestUtil H = new AuthenticatedTestUtil();
 
    @Rule
    public TestName testName = new TestName();

    @Before
    public void setup() throws Exception {
        H.setUp();
        postUrl = HttpTest.HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
    }

   /* (non-Javadoc)
   * @see org.apache.sling.commons.testing.integration.HttpTestBase#tearDown()
   */
  @After
  public void cleanup() throws Exception {
    if (testUserId != null) {
      //remove the test user if it exists.
      String postUrl = HttpTest.HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".delete.html";
      List<NameValuePair> postParams = new ArrayList<NameValuePair>();
      H.assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);
    }
    H.tearDown();
  }

    /**
     * Test for SLING-897 fix:
     * 1. Updating a property requires jcr:modifyProperties privilege on node.
     * 2. When changing an existing property observers should receive a PROPERTY_CHANGED event instead
     *     of a PROPERTY_REMOVED event and a PROPERTY_ADDED event
     */
    @Test
    @Category(JackrabbitOnly.class) // TODO: fails on Oak
    @Ignore // TODO fails on jackrabbit 2.6.5
    public void testUpdatePropertyPrivilegesAndEvents() throws IOException, JSONException, RepositoryException, InterruptedException {
      //1. Create user as admin (OK)
        // curl -F:name=myuser -Fpwd=password -FpwdConfirm=password http://admin:admin@localhost:8080/system/userManager/user.create.html
      testUserId = H.createTestUser();

      //2. Create node as admin (OK)
        // curl -F:nameHint=node -FpropOne=propOneValue1 -FpropOne=propOneValue2 -FpropTwo=propTwoValue http://admin:admin@localhost:8080/test/
        final String createTestNodeUrl = postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX;
        NameValuePairList clientNodeProperties = new NameValuePairList();
        clientNodeProperties.add(SlingPostConstants.RP_NODE_NAME_HINT, testName.getMethodName());
        clientNodeProperties.add("propOne", "propOneValue1");
        clientNodeProperties.add("propOne", "propOneValue2");
        clientNodeProperties.add("propTwo", "propTwoValue");
      String testNodeUrl = H.getTestClient().createNode(createTestNodeUrl, clientNodeProperties, null, false);

        String content = H.getContent(testNodeUrl + ".json", HttpTest.CONTENT_TYPE_JSON);
        JSONObject json = new JSONObject(content);
        Object propOneObj = json.opt("propOne");
        assertTrue(propOneObj instanceof JSONArray);
        assertEquals(2, ((JSONArray)propOneObj).length());
        assertEquals("propOneValue1", ((JSONArray)propOneObj).get(0));
        assertEquals("propOneValue2", ((JSONArray)propOneObj).get(1));
     
        Object propTwoObj = json.opt("propTwo");
        assertTrue(propTwoObj instanceof String);
        assertEquals("propTwoValue", propTwoObj);
     
     
        //3. Attempt to update property of node as testUser (500: javax.jcr.AccessDeniedException: /test/node/propOne: not allowed to add or modify item)
        // curl -FpropOne=propOneValueChanged -FpropTwo=propTwoValueChanged1 -FpropTwo=propTwoValueChanged2 http://myuser:password@localhost:8080/test/node
      List<NameValuePair> postParams = new ArrayList<NameValuePair>();
      postParams.add(new NameValuePair("propOne", "propOneValueChanged"));
      postParams.add(new NameValuePair("propTwo", "propTwoValueChanged1"));
      postParams.add(new NameValuePair("propTwo", "propTwoValueChanged2"));
    Credentials testUserCreds = new UsernamePasswordCredentials(testUserId, "testPwd");
    String expectedMessage = "Expected javax.jcr.AccessDeniedException";
      H.assertAuthenticatedPostStatus(testUserCreds, testNodeUrl, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, expectedMessage);
     
        //4. Grant jcr:modifyProperties rights to testUser as admin (OK)
        // curl -FprincipalId=myuser -Fprivilege@jcr:modifyProperties=granted http://admin:admin@localhost:8080/test/node.modifyAce.html
        Map<String, String> nodeAceProperties = new HashMap<String, String>();
        nodeAceProperties.put("principalId", testUserId);
        nodeAceProperties.put("privilege@jcr:modifyProperties", "granted");
      H.getTestClient().createNode(testNodeUrl + ".modifyAce.html", nodeAceProperties);
     
        //use a davex session to verify the correct JCR events are delivered
        Repository repository = JcrUtils.getRepository(HttpTest.HTTP_BASE_URL + "/server/");
        Session jcrSession = null;
        TestEventListener listener = new TestEventListener();
        ObservationManager observationManager = null;
        try {
            jcrSession = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
            observationManager = jcrSession.getWorkspace().getObservationManager();
          String testNodePath = testNodeUrl.substring(HttpTest.HTTP_BASE_URL.length());
            observationManager.addEventListener(listener,
          Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED, //event types
          testNodePath, //absPath
          true, //isDeep
          null, //uuid
          null, //nodeTypeName
          false); //noLocal
       
            //5. Attempt to update properties of node (OK)
            // curl -FpropOne=propOneValueChanged -FpropTwo=propTwoValueChanged1 -FpropTwo=propTwoValueChanged2 http://myuser:password@localhost:8080/test/node
          H.assertAuthenticatedPostStatus(testUserCreds, testNodeUrl, HttpServletResponse.SC_OK, postParams, expectedMessage);
         
          //verify the change happened
            String afterUpdateContent = H.getContent(testNodeUrl + ".json", HttpTest.CONTENT_TYPE_JSON);
            JSONObject afterUpdateJson = new JSONObject(afterUpdateContent);
            Object afterUpdatePropOneObj = afterUpdateJson.opt("propOne");
            assertTrue(afterUpdatePropOneObj instanceof JSONArray);
            assertEquals(1, ((JSONArray)afterUpdatePropOneObj).length());
            assertEquals("propOneValueChanged", ((JSONArray)afterUpdatePropOneObj).get(0));
         
            Object afterUpdatePropTwoObj = afterUpdateJson.opt("propTwo");
            assertTrue(afterUpdatePropTwoObj instanceof JSONArray);
            assertEquals(2, ((JSONArray)afterUpdatePropTwoObj).length());
            assertEquals("propTwoValueChanged1", ((JSONArray)afterUpdatePropTwoObj).get(0));
            assertEquals("propTwoValueChanged2", ((JSONArray)afterUpdatePropTwoObj).get(1));
           
          //wait for the expected JCR events to be delivered
      for (int second = 0; second < 15; second++) {
        if (listener.getEventBundlesProcessed() > 0) {
          break;
        }
        Thread.sleep(1000);
      }
     
      assertEquals("One property added event was expected: " + listener.toString(),
          1, listener.addedProperties.size());
      assertEquals(testNodePath + "/propTwo", listener.addedProperties.get(0));
      assertEquals("One property removed event was expected: " + listener.toString(),
          1, listener.removedProperties.size());
      assertEquals(testNodePath + "/propTwo", listener.removedProperties.get(0));
      assertEquals("One property changed event was expected: " + listener.toString(),
          1, listener.changedProperties.size());
      assertEquals(testNodePath + "/propOne", listener.changedProperties.get(0));
        } finally {
          //cleanup
          if (observationManager != null) {
              observationManager.removeEventListener(listener);
          }
            jcrSession.logout();
            repository = null;
        }
    }
   
  protected class TestEventListener implements EventListener {
    protected List<String> changedProperties = new ArrayList<String>();
    protected List<String> addedProperties = new ArrayList<String>();
    protected List<String> removedProperties = new ArrayList<String>();
   
    protected int eventBundlesProcessed = 0;
   
    public void onEvent(EventIterator eventIterator) {
      try {
        while (eventIterator.hasNext()) {
          Event event = eventIterator.nextEvent();
          int type = event.getType();
          switch (type) {
            case Event.PROPERTY_CHANGED:
              changedProperties.add(event.getPath());
              break;
            case Event.PROPERTY_ADDED:
              addedProperties.add(event.getPath());
              break;
            case Event.PROPERTY_REMOVED:
              removedProperties.add(event.getPath());
              break;
          }
        }
        eventBundlesProcessed++;
      } catch (RepositoryException e) {
        fail(e.getMessage());
      }
    }
   
    public int getEventBundlesProcessed() {
      return eventBundlesProcessed;
    }

    public void clear() {
      changedProperties.clear();
      addedProperties.clear();
      removedProperties.clear();
      eventBundlesProcessed = 0;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      return "TestEventListener [addedProperties=" + Arrays.toString(addedProperties.toArray())
          + ", changedProperties=" + Arrays.toString(changedProperties.toArray())
          + ", removedProperties=" + Arrays.toString(removedProperties.toArray()) + "]";
    }
  }  
}
TOP

Related Classes of org.apache.sling.launchpad.webapp.integrationtest.servlets.post.PostServletPrivilegesUpdateTest$TestEventListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.