11 Replies Latest reply on Feb 27, 2013 5:15 PM by Kristian Wright

    How to create a CQ package to export all the users and their permissions.

    Ram Atmakur Level 1

      Hi All,

                Hope you all are doing great. Have a qn regarding the packge export via package manager. I am trying to export all the users and their permissions from one env to the other. I can get the users and groups but not their permissions. Can any one suggest me a way of how to do this? I was not able to get the include/exclude filters right..

       

      Regards

      Rama

        • 1. Re: How to create a CQ package to export all the users and their permissions.
          hypnotec Adobe Employee

          try attached (demo) servlet which will create a package containing ACL definitions, which you can install on a publish using "Merge" (ACL) mode. once you have created a package with the servlet, you can introspect its filters as documentation on how to create such packages manually as well.

           

          package com.adobe.migration;

           

           

          import org.apache.commons.lang.StringUtils;

          import org.apache.felix.scr.annotations.Component;

          import org.apache.felix.scr.annotations.Reference;

          import org.apache.felix.scr.annotations.sling.SlingServlet;

          import org.apache.sling.api.SlingHttpServletRequest;

          import org.apache.sling.api.SlingHttpServletResponse;

          import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

          import org.apache.sling.jcr.api.SlingRepository;

          import org.slf4j.Logger;

          import org.slf4j.LoggerFactory;

           

           

          import javax.jcr.*;

          import javax.jcr.query.Query;

          import javax.jcr.query.QueryResult;

          import javax.servlet.ServletException;

          import java.io.ByteArrayInputStream;

          import java.io.IOException;

          import java.io.Writer;

          import java.util.*;

           

           

          /**

          * Presents an interface for easy creation of policy export package defintions

          */

          @org.apache.felix.scr.annotations.Property(

                  name = "service.description",

                  value = "Migration Tools - Create Policy Export Package Servlet"

          )

          @Component(

                  metatype = false

          )

          @SlingServlet(

                  methods = {"GET"},

                  paths = {"/bin/cpep.html"},

                  generateComponent = false

          )

          public class CreatePolicyExportPackagesSevlet extends SlingSafeMethodsServlet {

           

           

              private static final Logger log = LoggerFactory.getLogger(CreatePolicyExportPackagesSevlet.class);

           

           

              @Reference

              SlingRepository repo;

           

           

              @Override

              protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {

           

           

                  // init response

                  response.setContentType("text/html");

                  response.setCharacterEncoding("utf-8");

                  Writer out = response.getWriter();

           

           

                  out.write("<html><head><title>Create Policy Export Package</title></head><body>");

                 

                  out.write("<h2>Create Policy Export Package</h2>");

           

           

                  out.write("<a href=\"/bin/cpep.html\">Start Over</a>");

           

           

                  Session session = null;

                  try {

                      session = repo.loginAdministrative(null);

           

           

                      String parentPath = StringUtils.defaultString(request.getParameter("parentPath"));

                      String runType = StringUtils.defaultString(request.getParameter("runType"));

                      boolean dryRun = !"real".equals(runType);

           

           

                      Map parameters = request.getParameterMap();

                      if (parameters.containsKey("createExportPackages")) {

                          out.write("<h3>Result</h3>");

                      }

                      if (parameters.containsKey("createExportPackages")) {

                          startCreation(session, out, parentPath, dryRun);

                          // finished

                          out.write("<br/><br/>");

                          out.write("COMPLETE");

                      }

           

           

                      out.write("<h3>Configuration</h3>");

                      out.write("<form method=\"GET\" action=\"/bin/cpep.html\">");

                      out.write("<label for=\"parentPath\">Path to export policies from</label>");

                      out.write(" ");

                      out.write("<input type=\"text\" id=\"parentPath\" name=\"parentPath\" value=\"" + parentPath + "\" style=\"width: 400px;\" />");

                      out.write("<br/>");

                      out.write("<label for=\"runType\">Run Type</label>");

                      out.write("<br/>");

                      out.write("<input type=\"radio\" id=\"runType\" name=\"runType\" value=\"real\" /> Real");

                      out.write("<br/>");

                      out.write("<input type=\"radio\" id=\"runType\" name=\"runType\" value=\"dry\" checked=\"checked\" /> Dry");

                      out.write("<br/>");

                      out.write("<input type=\"hidden\" name=\"createExportPackages\" value=\"true\" />");

                      out.write("<input type=\"submit\" value=\"Create\" />");

                      out.write("</form>");

           

           

                  } catch (RepositoryException e) {

                      out.write("<br/>");

                      out.write("<br/>");

                      out.write("ERROR: " + e.getMessage());

                  } finally {

                      if (session != null) {

                          session.logout();

                      }

                  }

           

           

                  out.write("</body></html>");

              }

           

           

              private void startCreation(Session session, Writer out, String parentPath, boolean dryRun) throws IOException, RepositoryException {

                  try {

                      Node packageFolder = getPackageFolderNode(session);

                      createExportPackageForFolder(session, out, parentPath, dryRun, "", packageFolder);

                  } catch (PathNotFoundException e) {

                      out.write("Could not find parent path '" + parentPath + "'");

                  }

              }

           

           

              private void createExportPackageForFolder(Session session, Writer out, String parentPath, boolean dryRun, String prefix, Node packageFolder) throws IOException, RepositoryException {

           

           

                  String packageName = "policyexport_" + (new Date()).getTime();

                  Node packageNode = null;

                  if (!dryRun) {

                      packageNode = createPackage(session, packageFolder, packageName);

                  }

                  out.write((dryRun?"Would create":"Created") + " package " + packageName + "<br/>");

           

           

                  if (parentPath.endsWith(("/"))) {

                     parentPath = StringUtils.substringBeforeLast(parentPath, "/");

                  }

                  String pathFilter = (!parentPath.isEmpty()) ? "where jcr:path like '" + parentPath + "/%'" : "";

                  String queryString = "select * from rep:ACL " + pathFilter + " order by jcr:path";

                  out.write("<i>Using query string: " + queryString + "</i><br/><br/>");

           

           

                  // create and excute query

                  Query query = session.getWorkspace().getQueryManager().createQuery(queryString, Query.SQL);

                  QueryResult queryResult = query.execute();

           

           

                  // loop results

                  int filterCount = 1;

                  for (Node node : new IterableIterator<Node>(queryResult.getNodes())) {

                       if (!dryRun) {

                              addNodeToPackage(session, packageNode, node, filterCount);

                          }

                          filterCount++;

                          out.write("- " + node.getPath() + "<br/>");

                          out.flush();

                  }

           

           

                  if (!dryRun) {

                      out.write("<br/><br/>");

                      out.write("Package located at <a href=\"" + packageNode.getPath() + ".html\" target=\"_blank\">" + packageNode.getPath() + ".html</a>");

                  }

           

           

              }

           

           

              private void addNodeToPackage(Session session, Node packageNode, Node nodeToAdd, int filterCount) throws RepositoryException {

                  Node filterlistNode = packageNode.getNode("jcr:content/vlt:definition/filter");

                  Node filterNode = filterlistNode.addNode("filter_"+filterCount, "nt:unstructured");

                  filterNode.setProperty("root", nodeToAdd.getPath());

                  filterNode.setProperty("sling:resourceType", "cq/packaging/components/pack/definition/filter");

                  session.save();

              }

           

           

              private Node createPackage(Session session, Node packageFolder, String packageName) throws RepositoryException {

                  // create package node

                  Node packageNode = packageFolder.addNode(packageName + ".zip", "nt:file");

                  packageNode.addMixin("cq:PseudoPage");

                  // create jcr:content below package node

                  Node contentNode = packageNode.addNode("jcr:content", "nt:resource");

                  contentNode.addMixin("vlt:Package");

                  contentNode.addMixin("sling:Resource");

                  contentNode.setProperty("sling:resourceType", "cq/packaging/components/pack");

                  contentNode.setProperty("jcr:mimeType", "application/zip");

                  contentNode.setProperty("jcr:data", new ByteArrayInputStream(new byte[0]));

                  contentNode.setProperty("jcr:lastModified", Calendar.getInstance());

                  // create package defintion below package node

                  Node definitionNode = contentNode.addNode("vlt:definition", "vlt:PackageDefinition");

                  definitionNode.setProperty("version", "");

                  definitionNode.setProperty("acHandling", "overwrite");

                  definitionNode.setProperty("cqVersion", "5.4");

                  definitionNode.setProperty("path", packageNode.getPath());

                  // add the filterlist

                  Node filterlistNode = definitionNode.addNode("filter", "nt:unstructured");

                  filterlistNode.setProperty("sling:resourceType", "cq/packaging/components/pack/definition/filterlist");

                  session.save();

                  return packageNode;

              }

           

           

              private Node getPackageFolderNode(Session session) throws RepositoryException {

                  return (Node)session.getItem("/etc/packages");

              }

           

           

          }

          • 2. Re: How to create a CQ package to export all the users and their permissions.
            Ram Atmakur Level 1

            Hi Hypnotec,

             

                      Thanks for giving me some direction on this. I would go thorugh this code and try to identify how I can achieve what I wanted.

             

            Thanks Again

            Rama.

            • 3. Re: How to create a CQ package to export all the users and their permissions.
              Davide G Adobe Employee

              Hi Rama,

               

              Just remember that the actual permissions are stored under the node. So if

              you need to get the ACL for the user A from node /foo/bar it means that

              the permissions will be stored under /foo/bar or his ancestors.

               

              HTH

              Davide

              1 person found this helpful
              • 4. Re: How to create a CQ package to export all the users and their permissions.
                Ram Atmakur Level 1

                Hi Davide,

                      Thanks a tonn for having sent that code. I did not knew there was sql like querying capability. This code does solve my issue, but also has given me some more insights into the API. Thanks for the help and your suggestions. You rock ..

                 

                Rama.

                • 6. Re: How to create a CQ package to export all the users and their permissions.
                  Ram Atmakur Level 1

                  Oops ! ..

                   

                  Sorry Hyptonic, Apologize for that. Thanks for that piece of code.

                   

                  Hyptonic, I have used your code and was able to build the package. I was able to import the package with the permissions from other environment and it looks like it is doing what it has to do, copying the permissions for all the users and groups. But I see on the 'useradmin' the option for 'Replicator' permission is not copied. Is it anything special with the Replicator permissions or I missed anything?

                   

                  Thanks again for the help.

                   

                  Regards

                  Rama.

                  • 7. Re: How to create a CQ package to export all the users and their permissions.
                    hypnotec Adobe Employee

                    hi

                     

                    replication permission is not a repository-level ACL, but a "privilege". you can find a user's or group's privileges under its home directory, e.g. /home/users/a/author/privileges/. thus you'll have to extend the code to package up these as well.

                     

                    HTH

                    dom.

                    • 8. Re: How to create a CQ package to export all the users and their permissions.
                      JakeP74

                      Hello,

                       

                      I would really like to try this and have copied the code example, but I think one import might be missing - I'm not sure IterableIterator comes from.  Could anyone point me to a library?

                       

                      Thanks,

                      Jake

                      • 9. Re: How to create a CQ package to export all the users and their permissions.
                        hypnotec Adobe Employee

                        i can't find the IterableIterator, but you can easily use the query result directly:

                         

                        NodeIterator nit = queryResult.getNodes();

                        while (nit.hasNext()) {

                            Node n = nit.nextNode();

                            ...

                        }

                        • 11. Re: How to create a CQ package to export all the users and their permissions.
                          Kristian Wright Level 1

                          Thanks for the code, hypnotec.  It worked very nicely and gave me a good idea on what filters need to be applied to grab the permissions.

                           

                          However you state that 'you can install on a publish using "Merge" (ACL) mode'.  I've tried replicating the package with the permissions from the author to the publisher, and the permissions did not appear on the publisher.  I tried logging into the publisher and installing the package directly with "Merge" mode, and the permissions were now there.

                           

                          Is this the only way to get the permissions across to a publisher?  Is there any way at all to use replication from the author to achieve this, or do you always need to implicitly do this on the publisher?

                           

                          Thanks,

                          K