You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2017/11/30 20:05:10 UTC

[sling-org-apache-sling-jcr-contentloader] branch master updated: SLING-7268 unable to create principals and use principals in ACLs on import

This is an automated email from the ASF dual-hosted git repository.

enorman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git


The following commit(s) were added to refs/heads/master by this push:
     new 646984b  SLING-7268 unable to create principals and use principals in ACLs on import
646984b is described below

commit 646984b82c72ccdac055bfaf7bd876adfc0a4664
Author: Eric Norman <en...@apache.org>
AuthorDate: Thu Nov 30 12:03:50 2017 -0800

    SLING-7268 unable to create principals and use principals in ACLs on
    import
    
    As pointed out in OAK-5496, we cannot successfully use
    PrincipalManager#getPrincipal in oak without the session that created
    the principal getting saved first (and a subsequent index update).
    Workaround by trying the UserManager#getAuthorizable API to locate the
    principal.
---
 .../internal/DefaultContentCreator.java            |  12 ++
 .../it/SLING7268InitialContentIT.java              | 161 +++++++++++++++++++++
 src/test/resources/initial-content/SLING-7268.json |  37 +++++
 3 files changed, 210 insertions(+)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
index 9659847..8ed0d74 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
@@ -831,9 +831,21 @@ public class DefaultContentCreator implements ContentCreator {
     public void createAce(String principalId, String[] grantedPrivilegeNames, String[] deniedPrivilegeNames, String order) throws RepositoryException {
         final Node parentNode = this.parentNodeStack.peek();
         Session session = parentNode.getSession();
+        
         PrincipalManager principalManager = AccessControlUtil.getPrincipalManager(session);
         Principal principal = principalManager.getPrincipal(principalId);
         if (principal == null) {
+            // SLING-7268 - as pointed out in OAK-5496, we cannot successfully use PrincipalManager#getPrincipal in oak 
+        	//  without the session that created the principal getting saved first (and a subsequent index update).  
+        	//  Workaround by trying the UserManager#getAuthorizable API to locate the principal. 
+            UserManager userManager = AccessControlUtil.getUserManager(session);
+            final Authorizable authorizable = userManager.getAuthorizable(principalId);
+            if (authorizable != null) {
+                principal = authorizable.getPrincipal();
+            }
+        }
+        		
+        if (principal == null) {
             throw new RepositoryException("No principal found for id: " + principalId);
         }
         String resourcePath = parentNode.getPath();
diff --git a/src/test/java/org/apache/sling/jcr/contentloader/it/SLING7268InitialContentIT.java b/src/test/java/org/apache/sling/jcr/contentloader/it/SLING7268InitialContentIT.java
new file mode 100644
index 0000000..b870854
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/contentloader/it/SLING7268InitialContentIT.java
@@ -0,0 +1,161 @@
+/*
+ * 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.jcr.contentloader.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.commons.testing.junit.Retry;
+import org.apache.sling.jcr.base.util.AccessControlUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.osgi.framework.Bundle;
+
+/** test of a bundle that provides initial content that creates a user/group and defines an ace 
+ *  for those principals within the same transaction 
+ */
+@RunWith(PaxExam.class)
+public class SLING7268InitialContentIT extends ContentBundleTestBase {
+    
+    protected TinyBundle setupTestBundle(TinyBundle b) throws IOException {
+        b.set(SLING_INITIAL_CONTENT_HEADER, DEFAULT_PATH_IN_BUNDLE + ";path:=" + contentRootPath);
+        addContent(b, DEFAULT_PATH_IN_BUNDLE, "SLING-7268.json");
+        return b;
+    }
+    
+    @Test
+    @Retry(intervalMsec=RETRY_INTERVAL, timeoutMsec=RETRY_TIMEOUT)
+    public void bundleStarted() {
+        final Bundle b = PaxExamUtilities.findBundle(bundleContext, bundleSymbolicName);
+        assertNotNull("Expecting bundle to be found:" + bundleSymbolicName, b);
+        assertEquals("Expecting bundle to be active:" + bundleSymbolicName, Bundle.ACTIVE, b.getState());
+    }
+    
+    @Test
+    @Retry(intervalMsec=RETRY_INTERVAL, timeoutMsec=RETRY_TIMEOUT)
+    public void initialContentInstalled() throws RepositoryException {
+        final String folderPath = contentRootPath + "/SLING-7268"; 
+        assertTrue("Expecting initial content to be installed", session.itemExists(folderPath)); 
+        assertEquals("folder has node type 'sling:Folder'", "sling:Folder", session.getNode(folderPath).getPrimaryNodeType().getName()); 
+    }
+
+    @Test
+    @Retry(intervalMsec=RETRY_INTERVAL, timeoutMsec=RETRY_TIMEOUT)
+    public void userCreated() throws RepositoryException {
+        UserManager userManager = AccessControlUtil.getUserManager(session);
+        Authorizable authorizable = userManager.getAuthorizable("sling7268_user");
+        assertNotNull("Expecting test user to exist", authorizable);
+    }
+
+    @Test
+    @Retry(intervalMsec=RETRY_INTERVAL, timeoutMsec=RETRY_TIMEOUT)
+    public void groupCreated() throws RepositoryException {
+        UserManager userManager = AccessControlUtil.getUserManager(session);
+        Authorizable authorizable = userManager.getAuthorizable("sling7268_group");
+        assertNotNull("Expecting test group to exist", authorizable);
+        assertTrue(authorizable instanceof Group);
+        Iterator<Authorizable> members = ((Group)authorizable).getMembers();
+        assertTrue(members.hasNext());
+        Authorizable firstMember = members.next();
+        assertEquals("sling7268_user", firstMember.getID());
+    }
+
+    @Test
+    @Retry(intervalMsec=RETRY_INTERVAL, timeoutMsec=RETRY_TIMEOUT)
+    public void aceCreated() throws RepositoryException {
+        final String folderPath = contentRootPath + "/SLING-7268"; 
+        assertTrue("Expecting test folder to exist", session.itemExists(folderPath)); 
+
+        AccessControlManager accessControlManager = AccessControlUtil.getAccessControlManager(session);
+		AccessControlPolicy[] policies = accessControlManager.getPolicies(folderPath);
+        List<AccessControlEntry> allEntries = new ArrayList<AccessControlEntry>(); 
+		for (AccessControlPolicy accessControlPolicy : policies) {
+			if (accessControlPolicy instanceof AccessControlList) {
+				AccessControlEntry[] accessControlEntries = ((AccessControlList)accessControlPolicy).getAccessControlEntries();
+                for (AccessControlEntry accessControlEntry : accessControlEntries) {
+					allEntries.add(accessControlEntry);
+				}
+			}
+		}
+		assertEquals(3, allEntries.size());
+		Map<String, AccessControlEntry> aceMap = new HashMap<>();
+		for (AccessControlEntry accessControlEntry : allEntries) {
+			aceMap.put(accessControlEntry.getPrincipal().getName(), accessControlEntry);
+		}
+		
+		//check ACE for sling7268_user
+		AccessControlEntry testUserAce = aceMap.get("sling7268_user");
+		assertNotNull("Expected ACE for test user", testUserAce);
+		assertEquals("sling7268_user", testUserAce.getPrincipal().getName());
+		Privilege[] privileges = testUserAce.getPrivileges();
+		assertNotNull(privileges);
+		assertEquals(2, privileges.length);
+		Set<String> privilegeNames = new HashSet<>();
+		for (Privilege privilege : privileges) {
+			privilegeNames.add(privilege.getName());
+		}
+		assertTrue("Expecting granted read privilege", privilegeNames.contains("jcr:read"));
+		assertTrue("Expecting granted write privilege", privilegeNames.contains("jcr:write"));
+
+		//check ACE for sling7268_group
+		AccessControlEntry testGroupAce = aceMap.get("sling7268_group");
+		assertNotNull("Expected ACE for test user", testGroupAce);
+		assertEquals("sling7268_group", testGroupAce.getPrincipal().getName());
+		privileges = testGroupAce.getPrivileges();
+		assertNotNull(privileges);
+		assertEquals(1, privileges.length);
+		privilegeNames = new HashSet<>();
+		for (Privilege privilege : privileges) {
+			privilegeNames.add(privilege.getName());
+		}
+		assertTrue("Expecting granted modifyAccessControl privilege", privilegeNames.contains("jcr:modifyAccessControl"));
+
+		//check ACE for everyone group
+		AccessControlEntry everyoneAce = aceMap.get("everyone");
+		assertNotNull("Expected ACE for everyone", everyoneAce);
+		assertEquals("everyone", everyoneAce.getPrincipal().getName());
+		privileges = everyoneAce.getPrivileges();
+		assertNotNull(privileges);
+		assertEquals(1, privileges.length);
+
+		assertEquals("Expecting granted read privilege", "jcr:read", privileges[0].getName());
+    }
+}
diff --git a/src/test/resources/initial-content/SLING-7268.json b/src/test/resources/initial-content/SLING-7268.json
new file mode 100644
index 0000000..cc3c300
--- /dev/null
+++ b/src/test/resources/initial-content/SLING-7268.json
@@ -0,0 +1,37 @@
+{
+    "jcr:primaryType" : "sling:Folder",
+    "security:principals": [
+        { 
+            "name": "sling7268_user", 
+            "password": "mypassword"
+        },
+        { 
+            "name": "sling7268_group", 
+            "isgroup": true,
+            "members":[
+               "sling7268_user"
+            ]
+        }
+    ],
+    "security:acl": [
+        { 
+            "principal": "everyone", 
+            "granted": [
+                "jcr:read"
+            ]
+        },
+        { 
+            "principal": "sling7268_user", 
+            "granted": [
+                "jcr:read",
+                "jcr:write"
+            ]
+        },
+        { 
+            "principal": "sling7268_group", 
+            "granted": [
+                "jcr:modifyAccessControl"
+            ]
+        }
+    ]
+}

-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].