ExampleContentHealthCheck.java 8.71 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.jcr.vault.packaging.JcrPackage
 *  com.day.jcr.vault.packaging.JcrPackageDefinition
 *  com.day.jcr.vault.packaging.JcrPackageManager
 *  com.day.jcr.vault.packaging.PackageId
 *  com.day.jcr.vault.packaging.PackagingService
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.PropertyUnbounded
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.commons.osgi.PropertiesUtil
 *  org.apache.sling.hc.api.HealthCheck
 *  org.apache.sling.hc.api.Result
 *  org.apache.sling.hc.api.ResultLog
 *  org.apache.sling.hc.util.FormattingResultLog
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.security.hc.packages.impl;

import com.day.jcr.vault.packaging.JcrPackage;
import com.day.jcr.vault.packaging.JcrPackageDefinition;
import com.day.jcr.vault.packaging.JcrPackageManager;
import com.day.jcr.vault.packaging.PackageId;
import com.day.jcr.vault.packaging.PackagingService;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Dictionary;
import java.util.List;
import java.util.TreeSet;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.hc.api.HealthCheck;
import org.apache.sling.hc.api.Result;
import org.apache.sling.hc.api.ResultLog;
import org.apache.sling.hc.util.FormattingResultLog;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=1, label="Adobe CQ Example Content Packages Health Check", description="This check checks if the example content packages have been disabled.")
@Properties(value={@Property(name="hc.name", value={"Example Content Packages"}, label="Name", description="Name of the health check."), @Property(name="hc.tags", unbounded=PropertyUnbounded.ARRAY, value={"login", "content", "example", "security", "production"}, label="Tags", description="Tags for the health check."), @Property(name="hc.mbean.name", value={"exampleContent"}, label="MBean Name", description="Name of the JMX mbean to register for this check.")})
@Service(value={HealthCheck.class})
public class ExampleContentHealthCheck
implements HealthCheck {
    private final Logger log;
    @Reference
    private SlingRepository repository;
    private List<String> defaultContentPackages;
    private static final String GEOMETRIXX_PACKG = "cq-geometrixx:name:You can uninstall all the Geometrixx content packages by uninstalling the cq-geometrixx-all-pkg via the Package Manager";
    @Property(value={"cq-geometrixx:name:You can uninstall all the Geometrixx content packages by uninstalling the cq-geometrixx-all-pkg via the Package Manager"}, unbounded=PropertyUnbounded.ARRAY, label="Example Content Packages", description="The names of the example content packages. Syntax supports optional parametersseparated by semi column: scope (name or group) and instructions, e.g.cq-geometrixx:name:You can uninstall all the Geometrixx content packages by uninstalling the cq-geometrixx-all-pkg via the Package Manager")
    private static final String EXAMPLE_PACKG_NAMES = "example_packages";
    private static final String PACKAGE_LIST_SERVICE = "packageListService";

    public ExampleContentHealthCheck() {
        this.log = LoggerFactory.getLogger(this.getClass());
    }

    @Activate
    public void activate(ComponentContext ctx) {
        this.defaultContentPackages = Arrays.asList(PropertiesUtil.toStringArray(ctx.getProperties().get("example_packages"), (String[])new String[0]));
        this.log.info("Activated, example content packages = {}", this.defaultContentPackages);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public Result execute() {
        FormattingResultLog resultLog;
        block11 : {
            resultLog = new FormattingResultLog();
            int failures = 0;
            Session session = null;
            try {
                session = this.repository.loginService("packageListService", null);
                JcrPackageManager packageManager = PackagingService.getPackageManager((Session)session);
                List packageList = packageManager.listPackages();
                TreeSet<String> instructions = new TreeSet<String>();
                for (String contentPackage : this.defaultContentPackages) {
                    DefinitionMatcher def = DefinitionMatcher.from(contentPackage);
                    if (def == null) {
                        resultLog.debug("Cannot check package(s) matching [{}]. The definition is not valid.", new Object[]{contentPackage});
                        continue;
                    }
                    for (JcrPackage jcrPackage : packageList) {
                        if (!def.matches(jcrPackage.getDefinition(), resultLog)) continue;
                        def.instruct(instructions);
                        ++failures;
                    }
                }
                if (failures == 0) {
                    resultLog.info("No example content packages were found.", new Object[0]);
                    break block11;
                }
                resultLog.warn("[{} example content packages installed.]( )", new Object[]{failures});
                for (String ins : instructions) {
                    resultLog.debug(ins, new Object[0]);
                }
                resultLog.debug("[Check the 'Remove Example Content' section in the security guidelines.](https://www.adobe.com/go/aem6_2_docs_security_example_en)", new Object[0]);
            }
            catch (RepositoryException e) {
                resultLog.warn("Error while getting session object. Could not check if the sample content is installed.", new Object[0]);
            }
            finally {
                if (session != null) {
                    session.logout();
                }
            }
        }
        return new Result((ResultLog)resultLog);
    }

    protected void bindRepository(SlingRepository slingRepository) {
        this.repository = slingRepository;
    }

    protected void unbindRepository(SlingRepository slingRepository) {
        if (this.repository == slingRepository) {
            this.repository = null;
        }
    }

    private static class DefinitionMatcher {
        static final String SEPARATOR = ":";
        static final int MAX_GROUP = 3;
        final String prefix;
        String scope;
        String instructions;

        static DefinitionMatcher from(String def) {
            if (def == null) {
                return null;
            }
            String[] definition = def.split(":", 3);
            if (definition.length == 0 || definition[0].isEmpty()) {
                return null;
            }
            return new DefinitionMatcher(definition);
        }

        private DefinitionMatcher(String[] def) {
            this.prefix = def[0].trim();
            if (def.length > 1) {
                this.scope = def[1];
            }
            if (def.length > 2) {
                this.instructions = def[2];
            }
        }

        boolean matches(JcrPackageDefinition jcrPackageDef, FormattingResultLog resultLog) throws RepositoryException {
            if (jcrPackageDef.getLastUnpacked() == null) {
                return false;
            }
            String packageName = jcrPackageDef.getId().getName();
            String packageGroup = jcrPackageDef.getId().getGroup();
            if ("group".equals(this.scope) && packageGroup != null && packageGroup.trim().startsWith(this.prefix) || "name".equals(this.scope) && packageName != null && packageName.trim().startsWith(this.prefix)) {
                resultLog.warn("Example content package installation found based on {} [{}]): [{}].", new Object[]{this.scope, this.prefix, packageName});
                return true;
            }
            return false;
        }

        void instruct(TreeSet<String> t) {
            if (this.instructions != null) {
                t.add(this.instructions);
            }
        }
    }

}