ExperienceLogConfigServlet.java 10.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.RepositoryException
 *  javax.servlet.ServletException
 *  org.apache.commons.lang3.StringUtils
 *  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.jackrabbit.api.security.user.Group
 *  org.apache.jackrabbit.api.security.user.User
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.servlets.SlingAllMethodsServlet
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.commons.osgi.PropertiesUtil
 *  org.osgi.framework.Bundle
 *  org.osgi.framework.BundleContext
 *  org.osgi.service.cm.Configuration
 *  org.osgi.service.cm.ConfigurationAdmin
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.experiencelog.impl;

import com.adobe.cq.experiencelog.ExperienceLogConfig;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.jcr.RepositoryException;
import javax.servlet.ServletException;
import org.apache.commons.lang3.StringUtils;
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.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
@Component(metatype=1)
@Service
@Properties(value={@Property(name="sling.servlet.methods", value={"GET", "POST"}, propertyPrivate=1), @Property(name="sling.servlet.resourceTypes", value={"cq/experiencelog/config"}, propertyPrivate=1), @Property(name="sling.servlet.extensions", value={"json", ""}, propertyPrivate=1)})
public class ExperienceLogConfigServlet
extends SlingAllMethodsServlet
implements ExperienceLogConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExperienceLogConfigServlet.class);
    private static final String PID = ExperienceLogConfigServlet.class.getName();
    private static final int CACHE_MAX_AGE = 300;
    private static final boolean DEFAULT_ENABLED = false;
    @Property(boolValue={0})
    private static final String ENABLED = "enabled";
    @Property(unbounded=PropertyUnbounded.ARRAY)
    private static final String DISABLED_FOR_GROUPS = "disabledForGroups";
    private static final String DEFAULT_TRACKING_SCRIPT = "//assets.adobedtm.com/1867257065c7cb4f78763290bcf397ea29532e02/satelliteLib-9ce1a537693e6ed273b97bfd3920c9cf81db52d2.js";
    @Property(value={"//assets.adobedtm.com/1867257065c7cb4f78763290bcf397ea29532e02/satelliteLib-9ce1a537693e6ed273b97bfd3920c9cf81db52d2.js"}, propertyPrivate=1)
    private static final String TRACKING_SCRIPT = "trackingScript";
    private String bundleLocation;
    private boolean enabled;
    private Set<String> disabledForGroups;
    private String trackingScript;
    @Reference
    private ConfigurationAdmin configurationAdmin = null;

    @Activate
    private void activate(ComponentContext context) throws IOException {
        this.bundleLocation = context.getBundleContext().getBundle().getLocation();
        Dictionary properties = context.getProperties();
        this.enabled = PropertiesUtil.toBoolean(properties.get("enabled"), (boolean)false);
        String[] disabledForGroupsArray = PropertiesUtil.toStringArray(properties.get("disabledForGroups"), (String[])new String[0]);
        this.disabledForGroups = new HashSet<String>(Arrays.asList(disabledForGroupsArray));
        this.trackingScript = PropertiesUtil.toString(properties.get("trackingScript"), (String)"//assets.adobedtm.com/1867257065c7cb4f78763290bcf397ea29532e02/satelliteLib-9ce1a537693e6ed273b97bfd3920c9cf81db52d2.js");
    }

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        this.sendConfig(request, response);
    }

    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        String operation = request.getParameter(":operation");
        if (!"updateConfig".equals(operation)) {
            throw new ServletException("Unexpected operation: " + operation);
        }
        this.updateConfig(request, response);
    }

    private void sendConfig(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        try {
            boolean enabledForUser = this.isEnabled(request);
            JSONObject responseObj = new JSONObject();
            responseObj.put("enabled", enabledForUser);
            if (enabledForUser) {
                responseObj.put("trackingScript", (Object)this.trackingScript);
            }
            if (request.getRequestURI().endsWith(".json")) {
                response.setHeader("Cache-Control", "private, max-age=300");
                response.setHeader("Content-Type", "application/json; charset=utf-8");
            }
            responseObj.write((Writer)response.getWriter());
        }
        catch (Exception e) {
            LOGGER.error("Unable to send config:", (Throwable)e);
            throw new ServletException("Unable to send config: " + e.getMessage(), (Throwable)e);
        }
    }

    private void updateConfig(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        ResourceResolver resolver = request.getResourceResolver();
        if (this.isAuthorizedToUpdateGlobalConfig(resolver)) {
            LOGGER.info("Update global config.");
            try {
                String enabled;
                String disabledForGroups;
                Configuration configuration = this.configurationAdmin.getConfiguration(PID);
                configuration.setBundleLocation(this.bundleLocation);
                Hashtable<String, Boolean> properties = configuration.getProperties();
                if (properties == null) {
                    properties = new Hashtable<String, Boolean>();
                }
                if ((enabled = request.getParameter("enabled")) != null) {
                    properties.put("enabled", Boolean.parseBoolean(enabled));
                }
                if ((disabledForGroups = request.getParameter("disabledForGroups")) != null) {
                    properties.put("disabledForGroups", (Boolean)this.parseDisabledForGroups(disabledForGroups));
                }
                LOGGER.debug("Config properties: {}", properties);
                configuration.update(properties);
            }
            catch (IOException e) {
                LOGGER.error("Unable to update global config: ", (Throwable)e);
                throw new ServletException("Unable to update global config: " + e.getMessage(), (Throwable)e);
            }
        } else {
            LOGGER.warn("User is not authorized to update global config: " + resolver.getUserID());
            response.sendError(403);
        }
    }

    private boolean isAuthorizedToUpdateGlobalConfig(ResourceResolver resolver) {
        User user = (User)resolver.adaptTo(User.class);
        return user.isAdmin();
    }

    private boolean isMemberOf(User user, Set<String> groups) {
        try {
            Iterator groupIterator = user.memberOf();
            while (groupIterator.hasNext()) {
                Group group = (Group)groupIterator.next();
                if (!groups.contains(group.getID())) continue;
                return true;
            }
            return false;
        }
        catch (RepositoryException e) {
            throw new RuntimeException("Unable to check membership: " + e.getMessage(), (Throwable)e);
        }
    }

    private String[] parseDisabledForGroups(String disabledForGroupsString) {
        String[] disabledForGroupsArray = StringUtils.defaultString((String)disabledForGroupsString).split("\\s*,\\s*");
        LinkedHashSet<String> disabledForGroupsSet = new LinkedHashSet<String>(Arrays.asList(disabledForGroupsArray));
        disabledForGroupsSet.remove("");
        disabledForGroupsArray = disabledForGroupsSet.toArray(new String[disabledForGroupsSet.size()]);
        return disabledForGroupsArray;
    }

    @Override
    public boolean isEnabled(SlingHttpServletRequest request) {
        boolean enabledForUser = this.enabled;
        if (enabledForUser && !this.disabledForGroups.isEmpty()) {
            User user = (User)request.getResourceResolver().adaptTo(User.class);
            enabledForUser = !this.isMemberOf(user, this.disabledForGroups);
        }
        return enabledForUser;
    }

    @Override
    public String getTrackingScript() {
        return this.trackingScript;
    }

    protected void bindConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = configurationAdmin;
    }

    protected void unbindConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        if (this.configurationAdmin == configurationAdmin) {
            this.configurationAdmin = null;
        }
    }
}