You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2019/01/16 23:28:44 UTC

[sling-org-apache-sling-jcr-repoinit] branch master updated: Adding support for creating / deleting groups via repoinit (#4)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 25b5064  Adding support for creating / deleting groups via repoinit (#4)
25b5064 is described below

commit 25b50641c18da60c1be3dae058ee875185d113fd
Author: Dan Klco <kl...@users.noreply.github.com>
AuthorDate: Wed Jan 16 18:28:40 2019 -0500

    Adding support for creating / deleting groups via repoinit (#4)
    
    * Adding support for creating / deleting groups via repoinit
    
    * Fixing method names
    
    Fixing as per SLING-8219
---
 .../sling/jcr/repoinit/impl/DoNothingVisitor.java  | 10 +++
 .../apache/sling/jcr/repoinit/impl/UserUtil.java   | 11 ++-
 .../sling/jcr/repoinit/impl/UserVisitor.java       | 79 ++++++++++++++++-----
 .../sling/jcr/repoinit/CreateGroupsTest.java       | 82 ++++++++++++++++++++++
 .../apache/sling/jcr/repoinit/impl/TestUtil.java   | 20 +++++-
 5 files changed, 183 insertions(+), 19 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java
index a1a6a31..340fc62 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java
@@ -18,9 +18,11 @@ package org.apache.sling.jcr.repoinit.impl;
 
 import javax.jcr.Session;
 
+import org.apache.sling.repoinit.parser.operations.CreateGroup;
 import org.apache.sling.repoinit.parser.operations.CreatePath;
 import org.apache.sling.repoinit.parser.operations.CreateServiceUser;
 import org.apache.sling.repoinit.parser.operations.CreateUser;
+import org.apache.sling.repoinit.parser.operations.DeleteGroup;
 import org.apache.sling.repoinit.parser.operations.DeleteServiceUser;
 import org.apache.sling.repoinit.parser.operations.DeleteUser;
 import org.apache.sling.repoinit.parser.operations.DisableServiceUser;
@@ -105,4 +107,12 @@ class DoNothingVisitor implements OperationVisitor {
     @Override
     public void visitDisableServiceUser(DisableServiceUser dsu) {
     }
+
+    @Override
+    public void visitCreateGroup(CreateGroup g) {
+    }
+
+    @Override
+    public void visitDeleteGroup(DeleteGroup g) {
+    }
 }
diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/UserUtil.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/UserUtil.java
index 0f8eb63..696a548 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/UserUtil.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/UserUtil.java
@@ -17,10 +17,12 @@
 package org.apache.sling.jcr.repoinit.impl;
 
 import java.security.Principal;
+
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.api.security.user.UserManager;
@@ -57,6 +59,13 @@ public class UserUtil {
         }
     }
 
+    public static PrincipalManager getPrincipalManager(Session session) throws RepositoryException {
+        if(!(session instanceof JackrabbitSession)) {
+            throw new IllegalArgumentException("Session is not a JackrabbitSession");
+        }
+        return ((JackrabbitSession)session).getPrincipalManager();
+    }
+
     public static UserManager getUserManager(Session session) throws RepositoryException {
         if(!(session instanceof JackrabbitSession)) {
             throw new IllegalArgumentException("Session is not a JackrabbitSession");
@@ -84,7 +93,7 @@ public class UserUtil {
         return result;
     }
 
-    public static boolean deleteUser(Session session, String id) throws RepositoryException {
+    public static boolean deleteAuthorizable(Session session, String id) throws RepositoryException {
         final Authorizable authorizable = getUserManager(session).getAuthorizable(id);
         if(authorizable != null) {
             authorizable.remove();
diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/UserVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/UserVisitor.java
index ea39463..bb0877c 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/UserVisitor.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/UserVisitor.java
@@ -16,23 +16,30 @@
  */
 package org.apache.sling.jcr.repoinit.impl;
 
+import java.security.Principal;
+
 import javax.jcr.Session;
 
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.sling.repoinit.parser.operations.CreateGroup;
 import org.apache.sling.repoinit.parser.operations.CreateServiceUser;
 import org.apache.sling.repoinit.parser.operations.CreateUser;
+import org.apache.sling.repoinit.parser.operations.DeleteGroup;
 import org.apache.sling.repoinit.parser.operations.DeleteServiceUser;
 import org.apache.sling.repoinit.parser.operations.DeleteUser;
 import org.apache.sling.repoinit.parser.operations.DisableServiceUser;
 
-/** OperationVisitor which processes only operations related to
- *  service users and ACLs. Having several such specialized visitors
- *  makes it easy to control the execution order.
+/**
+ * OperationVisitor which processes only operations related to service users and
+ * ACLs. Having several such specialized visitors makes it easy to control the
+ * execution order.
  */
 class UserVisitor extends DoNothingVisitor {
 
-    /** Create a visitor using the supplied JCR Session.
-     * @param s must have sufficient rights to create users
-     *      and set ACLs.
+    /**
+     * Create a visitor using the supplied JCR Session.
+     * 
+     * @param s must have sufficient rights to create users and set ACLs.
      */
     public UserVisitor(Session s) {
         super(s);
@@ -51,7 +58,7 @@ class UserVisitor extends DoNothingVisitor {
                 final String message = String.format("Existing user %s is not a service user.", username);
                 throw new RuntimeException(message);
             }
-        } catch(Exception e) {
+        } catch (Exception e) {
             report(e, "Unable to create service user [" + username + "]:" + e);
         }
     }
@@ -61,23 +68,61 @@ class UserVisitor extends DoNothingVisitor {
         final String username = s.getUsername();
         log.info("Deleting service user {}", username);
         try {
-            UserUtil.deleteUser(session, username);
-        } catch(Exception e) {
+            UserUtil.deleteAuthorizable(session, username);
+        } catch (Exception e) {
             report(e, "Unable to delete service user [" + username + "]:" + e);
         }
     }
 
     @Override
+    public void visitCreateGroup(CreateGroup g) {
+        final String groupname = g.getGroupname();
+        try {
+            Authorizable group = UserUtil.getAuthorizable(session, groupname);
+            if (group == null || !group.isGroup()) {
+                log.info("Creating group {}", groupname);
+                if (g.getPath() == null) {
+                    UserUtil.getUserManager(session).createGroup(groupname);
+                } else {
+                    UserUtil.getUserManager(session).createGroup(new Principal() {
+                        public String getName() {
+                            return groupname;
+                        }
+                    }, g.getPath());
+                }
+            } else {
+                log.info("Group {} already exists, no changes made", groupname);
+            }
+        } catch (Exception e) {
+            report(e, "Unable to create group [" + groupname + "]:" + e);
+        }
+    }
+
+    @Override
+    public void visitDeleteGroup(DeleteGroup g) {
+        final String groupname = g.getGroupname();
+        log.info("Deleting group {}", groupname);
+        try {
+            if (!UserUtil.deleteAuthorizable(session, groupname)) {
+                log.debug("Group {} doesn't exist - assuming delete to be a noop.", groupname);
+            }
+        } catch (Exception e) {
+            report(e, "Unable to delete group [" + groupname + "]:" + e);
+        }
+    }
+
+    @Override
     public void visitCreateUser(CreateUser u) {
         final String username = u.getUsername();
         try {
-            if(!UserUtil.userExists(session, username)) {
+            if (!UserUtil.userExists(session, username)) {
                 final String pwd = u.getPassword();
-                if(pwd != null) {
+                if (pwd != null) {
                     // TODO we might revise this warning once we're able
                     // to create users by providing their encoded password
                     // using u.getPasswordEncoding - for now I think only cleartext works
-                    log.warn("Creating user {} with cleartext password - should NOT be used on production systems", username);
+                    log.warn("Creating user {} with cleartext password - should NOT be used on production systems",
+                            username);
                 } else {
                     log.info("Creating user {}", username);
                 }
@@ -85,7 +130,7 @@ class UserVisitor extends DoNothingVisitor {
             } else {
                 log.info("User {} already exists, no changes made", username);
             }
-        } catch(Exception e) {
+        } catch (Exception e) {
             report(e, "Unable to create user [" + username + "]:" + e);
         }
     }
@@ -95,10 +140,10 @@ class UserVisitor extends DoNothingVisitor {
         final String username = u.getUsername();
         log.info("Deleting user {}", username);
         try {
-            if (!UserUtil.deleteUser(session, username)) {
+            if (!UserUtil.deleteAuthorizable(session, username)) {
                 log.debug("User {} doesn't exist - assuming delete to be a noop.", username);
             }
-        } catch(Exception e) {
+        } catch (Exception e) {
             report(e, "Unable to delete user [" + username + "]:" + e);
         }
     }
@@ -107,12 +152,12 @@ class UserVisitor extends DoNothingVisitor {
     public void visitDisableServiceUser(DisableServiceUser dsu) {
         final String username = dsu.getUsername();
         final String reason = dsu.getParametersDescription();
-        log.info("Disabling service user {} reason {}", new String[]{username, reason});
+        log.info("Disabling service user {} reason {}", new String[] { username, reason });
         try {
             if (!UserUtil.disableUser(session, username, reason)) {
                 log.debug("Service user {} doesn't exist - assuming disable to be a noop.", username);
             }
-        } catch(Exception e) {
+        } catch (Exception e) {
             report(e, "Unable to disable service user [" + username + "]:" + e);
         }
     }
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/CreateGroupsTest.java b/src/test/java/org/apache/sling/jcr/repoinit/CreateGroupsTest.java
new file mode 100644
index 0000000..d0adc87
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/repoinit/CreateGroupsTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.repoinit;
+
+import java.util.Random;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.jcr.repoinit.impl.TestUtil;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/** Test the creation of groups */
+public class CreateGroupsTest {
+
+    @Rule
+    public final SlingContext context = new SlingContext(ResourceResolverType.JCR_OAK);
+
+    private static final Random random = new Random(42);
+    private String namePrefix;
+    private TestUtil U;
+
+    @Before
+    public void setup() throws RepositoryException {
+        U = new TestUtil(context);
+        namePrefix = "group_" + random.nextInt();
+    }
+
+    @Test
+    public void createGroup() throws Exception {
+        final String groupId = namePrefix + "_cg";
+        U.parseAndExecute("create group " + groupId);
+        U.assertGroup("after creating group " + groupId, groupId, true);
+    }
+    
+    @Test
+    public void createDeleteSingleTest() throws Exception {
+        final String groupId = namePrefix + "_cdst";
+        U.assertGroup("at start of test", groupId, false);
+        U.parseAndExecute("create group " + groupId);
+        U.assertGroup("after creating group", groupId, true);
+        U.parseAndExecute("delete group " + groupId);
+        U.assertGroup("after deleting group", groupId, false);
+    }
+
+    @Test
+    public void createGroupWithPathTest() throws Exception {
+        final String groupId = namePrefix + "_cgwpt";
+        final String path = "testgroup/folder_for_" + groupId;
+        U.parseAndExecute("create group " + groupId + " with path " + path);
+        U.assertGroup("after creating group " + groupId, groupId, true, path);
+    }
+
+    @Test
+    public void createGroupMultipleTimes() throws Exception {
+        final String groupname = namePrefix + "_cgm";
+        U.assertGroup("before test", groupname, false);
+        final String input = "create group " + groupname;
+        for (int i = 0; i < 50; i++) {
+            U.parseAndExecute(input);
+        }
+        U.assertGroup("after creating it multiple times", groupname, true);
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java b/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
index e1320ee..f57fee9 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
@@ -35,6 +35,7 @@ import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.sling.repoinit.parser.RepoInitParsingException;
 import org.apache.sling.repoinit.parser.impl.RepoInitParserService;
@@ -64,7 +65,7 @@ public class TestUtil {
         }
     }
 
-    private void assertPathContains(User u, String pathShouldContain) throws RepositoryException {
+    private void assertPathContains(Authorizable u, String pathShouldContain) throws RepositoryException {
         if(pathShouldContain != null) {
             final String path = u.getPath();
             assertTrue(
@@ -73,6 +74,23 @@ public class TestUtil {
             );
         }
     }
+    
+
+
+    public void assertGroup(String info, String id, boolean expectToExist) throws RepositoryException {
+        assertGroup(info, id, expectToExist, null);
+    }
+
+    public void assertGroup(String info, String id, boolean expectToExist, String pathShouldContain) throws RepositoryException {
+        final Authorizable a = UserUtil.getUserManager(adminSession).getAuthorizable(id);
+        if(!expectToExist) {
+            assertNull(info + ", expecting Principal to be absent:" + id, a);
+        } else {
+            assertNotNull(info + ", expecting Principal to exist:" + id, a);
+            final Group g = (Group)a;
+            assertPathContains(g, pathShouldContain);
+        }
+    }
 
     public void assertUser(String info, String id, boolean expectToExist) throws RepositoryException {
         assertUser(info, id, expectToExist, null);