ProjectsAdjuster.java 10.5 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.security.AccessControlEntry
 *  javax.jcr.security.AccessControlManager
 *  javax.jcr.security.AccessControlPolicy
 *  javax.jcr.security.Privilege
 *  org.apache.commons.lang3.ArrayUtils
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.jackrabbit.api.JackrabbitSession
 *  org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry
 *  org.apache.jackrabbit.api.security.JackrabbitAccessControlList
 *  org.apache.jackrabbit.api.security.user.Authorizable
 *  org.apache.jackrabbit.api.security.user.UserManager
 *  org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.apache.sling.api.resource.ValueMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.compat.codeupgrade.impl.projects;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.Privilege;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ProjectsAdjuster {
    private static final Logger LOGGER = LoggerFactory.getLogger(ProjectsAdjuster.class);
    private static final Map<String, String> oldToNewMapping = new HashMap<String, String>();

    public static boolean adjustProjectResourceTypes(Resource projectHome) {
        return ProjectsAdjuster.checkResource(projectHome);
    }

    private static boolean checkResource(Resource resource) {
        boolean hasModifications = false;
        Iterable children = resource.getChildren();
        for (Resource child : children) {
            ModifiableValueMap mvp = (ModifiableValueMap)child.adaptTo(ModifiableValueMap.class);
            if (mvp != null) {
                String[] mixins;
                ArrayList<String> mixinList;
                String currentResourceType = (String)mvp.get("sling:resourceType", String.class);
                if (oldToNewMapping.containsKey(currentResourceType)) {
                    String newResourceType = oldToNewMapping.get(currentResourceType);
                    LOGGER.debug("adjusting {} from resource type {} to {}", (Object[])new String[]{child.getPath(), currentResourceType, newResourceType});
                    mvp.put((Object)"sling:resourceType", (Object)newResourceType);
                    hasModifications = true;
                }
                if ("cq/gui/components/projects/admin/card/projectcard".equalsIgnoreCase((String)mvp.get((Object)"sling:resourceType")) && mvp.containsKey((Object)"jcr:mixinTypes") && !(mixinList = new ArrayList<String>(Arrays.asList(mixins = (String[])mvp.get((Object)"jcr:mixinTypes")))).contains("cq:Project)")) {
                    LOGGER.debug("{} - does not have project mixin.  Has: {}", (Object)child.getPath(), (Object)mixins);
                    mixinList.add("cq:Project");
                    mvp.put((Object)"jcr:mixinTypes", (Object)mixinList.toArray(new String[mixinList.size()]));
                    LOGGER.debug("added cq:Project mixin to {} ", (Object)child.getPath());
                }
            }
            if (!ProjectsAdjuster.checkResource(child)) continue;
            hasModifications = true;
        }
        return hasModifications;
    }

    public static void adjustProjectACLs(Resource projectHome) throws RepositoryException {
        Session session = (Session)projectHome.getResourceResolver().adaptTo(Session.class);
        AccessControlManager accessControlManager = session.getAccessControlManager();
        UserManager userSessionUserManager = ((JackrabbitSession)session).getUserManager();
        Principal everyone = AccessControlUtils.getEveryonePrincipal((Session)session);
        Authorizable projectAdminsGroup = userSessionUserManager.getAuthorizable("projects-administrators");
        Authorizable projectUsersGroup = userSessionUserManager.getAuthorizable("projects-users");
        if (projectAdminsGroup != null && projectUsersGroup != null && ProjectsAdjuster.adjustProjectACLs(accessControlManager, projectHome, everyone, projectAdminsGroup.getPrincipal(), projectUsersGroup.getPrincipal())) {
            session.save();
        }
    }

    private static boolean adjustProjectACLs(AccessControlManager accessControlManager, Resource currentResource, Principal everyone, Principal projectAdminsGroup, Principal projectUsersGroup) throws RepositoryException {
        boolean result = false;
        if (currentResource.isResourceType("cq/gui/components/projects/admin/card/projectcard")) {
            ValueMap vm;
            String damFolderPath;
            LOGGER.debug("Project ACLs: checking {}", (Object)currentResource.getPath());
            result = ProjectsAdjuster.updateEveryoneACL(accessControlManager, currentResource, everyone, projectAdminsGroup, projectUsersGroup, result);
            Resource jcrContent = currentResource.getChild("jcr:content");
            if (jcrContent != null && !ResourceUtil.isNonExistingResource((Resource)jcrContent) && StringUtils.isNotBlank((CharSequence)(damFolderPath = (String)(vm = jcrContent.getValueMap()).get("damFolderPath", String.class)))) {
                Resource damResourcePath = currentResource.getResourceResolver().getResource(damFolderPath);
                if (damResourcePath != null && !ResourceUtil.isNonExistingResource((Resource)damResourcePath)) {
                    LOGGER.debug("Adjust dam folder {} for project {}", (Object)damFolderPath, (Object)currentResource.getPath());
                    ProjectsAdjuster.updateEveryoneACL(accessControlManager, damResourcePath, everyone, projectAdminsGroup, projectUsersGroup, result);
                } else {
                    LOGGER.error("Can't find dam folder {} for project {}", (Object)damFolderPath, (Object)currentResource.getPath());
                }
            }
        } else {
            for (Resource childResource : currentResource.getChildren()) {
                result = ProjectsAdjuster.adjustProjectACLs(accessControlManager, childResource, everyone, projectAdminsGroup, projectUsersGroup) || result;
            }
        }
        return result;
    }

    private static boolean updateEveryoneACL(AccessControlManager accessControlManager, Resource currentResource, Principal everyone, Principal projectAdminsGroup, Principal projectUsersGroup, boolean result) throws RepositoryException {
        AccessControlEntry[] entries;
        JackrabbitAccessControlList jacl = AccessControlUtils.getAccessControlList((AccessControlManager)accessControlManager, (String)currentResource.getPath());
        for (AccessControlEntry entry : entries = jacl.getAccessControlEntries()) {
            if (!everyone.equals(entry.getPrincipal()) || !(entry instanceof JackrabbitAccessControlEntry)) continue;
            JackrabbitAccessControlEntry jEntry = (JackrabbitAccessControlEntry)entry;
            Privilege jcrAll = accessControlManager.privilegeFromName("{http://www.jcp.org/jcr/1.0}all");
            if (jEntry.isAllow() || !ArrayUtils.contains((Object[])entry.getPrivileges(), (Object)jcrAll)) continue;
            LOGGER.debug("Project ACLs: fixing deny all for everyone on project path {}", (Object)currentResource.getPath());
            if (jacl.addEntry(projectUsersGroup, new Privilege[]{jcrAll}, false)) {
                AccessControlEntry usersGroupEntry = ProjectsAdjuster.findEntry(jacl, projectUsersGroup, jcrAll, false);
                if (usersGroupEntry != null) {
                    jacl.orderBefore(usersGroupEntry, (AccessControlEntry)jEntry);
                    if (jacl.addEntry(projectAdminsGroup, new Privilege[]{jcrAll}, false)) {
                        AccessControlEntry adminGroupEntry = ProjectsAdjuster.findEntry(jacl, projectAdminsGroup, jcrAll, false);
                        if (adminGroupEntry != null) {
                            jacl.orderBefore(adminGroupEntry, usersGroupEntry);
                            jacl.removeAccessControlEntry(entry);
                        }
                    } else {
                        LOGGER.debug("Project ACLs: project {} already contains the projects-administrators deny all entry", (Object)currentResource.getPath());
                    }
                }
            } else {
                LOGGER.debug("Project ACLs: project {} already contains the projects-users deny all entry", (Object)currentResource.getPath());
            }
            accessControlManager.setPolicy(currentResource.getPath(), (AccessControlPolicy)jacl);
            result = true;
        }
        return result;
    }

    private static AccessControlEntry findEntry(JackrabbitAccessControlList jacl, Principal principal, Privilege privilege, boolean allow) throws RepositoryException {
        for (JackrabbitAccessControlEntry entry : (JackrabbitAccessControlEntry[])jacl.getAccessControlEntries()) {
            if (!principal.equals(entry.getPrincipal()) || entry.isAllow() != allow || !ArrayUtils.contains((Object[])entry.getPrivileges(), (Object)privilege)) continue;
            return entry;
        }
        return null;
    }

    static {
        oldToNewMapping.put("cq/gui/components/projects/admin/assetlink", "cq/gui/components/projects/admin/card/assetlinkcard");
        oldToNewMapping.put("cq/gui/components/projects/admin/projectcard", "cq/gui/components/projects/admin/card/projectcard");
        oldToNewMapping.put("cq/gui/components/projects/admin/projectlink", "cq/gui/components/projects/admin/card/linkcard");
    }
}