UserPropertiesServlet.java 17.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.xss.JSONUtil
 *  com.adobe.granite.xss.XSSFilter
 *  javax.jcr.AccessDeniedException
 *  javax.jcr.Node
 *  javax.jcr.PathNotFoundException
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.ValueFactory
 *  javax.servlet.ServletException
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.jackrabbit.api.security.user.Authorizable
 *  org.apache.jackrabbit.api.security.user.UserManager
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestParameter
 *  org.apache.sling.api.request.RequestParameterMap
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.servlets.HtmlResponse
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.security.user.internal.servlets;

import com.adobe.granite.security.user.UserProperties;
import com.adobe.granite.security.user.UserPropertiesComposite;
import com.adobe.granite.security.user.UserPropertiesManager;
import com.adobe.granite.security.user.UserPropertiesService;
import com.adobe.granite.security.user.internal.servlets.AbstractServlet;
import com.adobe.granite.xss.JSONUtil;
import com.adobe.granite.xss.XSSFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
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.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.request.RequestParameterMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HtmlResponse;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service
@Properties(value={@Property(name="sling.servlet.paths", value={"rep/User/userproperties.json.GET.servlet", "rep/Group/userproperties.json.GET.servlet", "rep/SystemUser/userproperties.json.GET.servlet", "cq/Preferences/userproperties.json.GET.servlet", "cq/security/components/profile/userproperties.json.GET.servlet", "granite/security/search/profile/userproperties.json.GET.servlet", "rep/User/userproperties.html.POST.servlet", "rep/Group/userproperties.html.POST.servlet", "rep/SystemUser/userproperties.html.POST.servlet", "cq/Preferences/userproperties.html.POST.servlet", "cq/security/components/profile/userproperties.html.POST.servlet"})})
public class UserPropertiesServlet
extends AbstractServlet {
    private static final Logger log = LoggerFactory.getLogger(UserPropertiesServlet.class);
    private static final Set<String> RESERVED = Collections.singleton("path");
    private static final String PARAM_AUTHID = "authId";
    @Reference
    private UserPropertiesService service;
    @Reference
    private XSSFilter xss;

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        block19 : {
            HtmlResponse errorResponse = null;
            ResourceResolver resolver = request.getResourceResolver();
            Resource resource = request.getResource();
            try {
                if (this.service != null) {
                    Authorizable authorizable = (Authorizable)resource.adaptTo(Authorizable.class);
                    if (authorizable == null) {
                        String authId = request.getParameter("authId");
                        if (authId != null) {
                            String relRootPath = request.getParameter("path");
                            Session session = ((Node)resource.adaptTo(Node.class)).getSession();
                            UserPropertiesManager mgr = this.service.createUserPropertiesManager(session, resolver);
                            UserPropertiesComposite upc = mgr.getUserPropertiesComposite(authId, relRootPath);
                            this.userPropertiesCompositeToJson(request.getRequestURI() + "?" + request.getQueryString(), authId, response, resource, authorizable, upc);
                        } else {
                            UserProperties userProperties = (UserProperties)resource.adaptTo(UserProperties.class);
                            if (userProperties != null) {
                                UserManager uMgr = (UserManager)resolver.adaptTo(UserManager.class);
                                authorizable = uMgr.getAuthorizable(userProperties.getAuthorizableID());
                            }
                            this.userPropertiesToJson(request, response, resource, authorizable, userProperties);
                        }
                    } else {
                        Session session = ((Node)resource.adaptTo(Node.class)).getSession();
                        UserPropertiesManager mgr = this.service.createUserPropertiesManager(session, resolver);
                        String propPath = request.getParameter("path");
                        if (propPath != null) {
                            String[] paths = propPath.split(",");
                            if (paths.length < 2) {
                                UserProperties userProperties = mgr.getUserProperties(authorizable, paths[0]);
                                this.userPropertiesToJson(request, response, resource, authorizable, userProperties);
                            } else {
                                UserPropertiesComposite upc = mgr.getUserPropertiesComposite(authorizable.getID(), paths);
                                this.userPropertiesCompositeToJson(request.getRequestURI(), propPath, response, resource, authorizable, upc);
                            }
                        }
                    }
                    break block19;
                }
                String msg = "UserPropertiesService not available";
                log.warn(msg);
                errorResponse = UserPropertiesServlet.createErrorResponse(503, msg);
            }
            catch (AccessDeniedException e) {
                log.debug(e.getMessage());
                errorResponse = UserPropertiesServlet.createErrorResponse(401, (Exception)e);
            }
            catch (PathNotFoundException e) {
                log.debug(e.getMessage());
                errorResponse = UserPropertiesServlet.createErrorResponse(404, (Exception)e);
            }
            catch (Exception e) {
                log.debug(e.getMessage());
                errorResponse = UserPropertiesServlet.createErrorResponse(500, e);
            }
            finally {
                if (errorResponse != null) {
                    errorResponse.send((HttpServletResponse)response, true);
                }
            }
        }
    }

    private void userPropertiesToJson(SlingHttpServletRequest request, SlingHttpServletResponse response, Resource resource, Authorizable authorizable, UserProperties userProperties) throws IOException, JSONException, RepositoryException {
        UserPropertiesServlet.setJsonResponseHeader((HttpServletResponse)response);
        JSONWriter writer = new JSONWriter((Writer)response.getWriter());
        writer.object();
        if (userProperties != null) {
            String path = userProperties.getNode().getPath();
            writer.key("path").value((Object)path);
            UserPropertiesServlet.writeUser(userProperties.getAuthorizableID(), authorizable, writer);
            block4 : for (String propName : userProperties.getPropertyNames()) {
                String[] values = userProperties.getProperty(propName, null, String[].class);
                switch (values.length) {
                    case 0: {
                        writer.key(propName).value((Object)"");
                        continue block4;
                    }
                    case 1: {
                        JSONUtil.writeWithProtected((JSONWriter)writer, (String)propName, (String)values[0], (XSSFilter)this.xss);
                        continue block4;
                    }
                    default: {
                        JSONUtil.writeWithProtected((JSONWriter)writer, (String)propName, (String[])values, (XSSFilter)this.xss);
                    }
                }
            }
        } else {
            log.debug("Cannot access user properties at {0} ('path' parameter: {1})", (Object)resource.getPath(), (Object)request.getParameter("path"));
        }
        writer.endObject();
    }

    private void userPropertiesCompositeToJson(String path, String param, SlingHttpServletResponse response, Resource resource, Authorizable authorizable, UserPropertiesComposite upc) throws IOException, JSONException, RepositoryException {
        UserPropertiesServlet.setJsonResponseHeader((HttpServletResponse)response);
        JSONWriter writer = new JSONWriter((Writer)response.getWriter());
        writer.object();
        if (upc != null) {
            writer.key("path").value((Object)path);
            writer.key("composite").array();
            for (String p : upc.getUserPropertiesPaths()) {
                writer.value((Object)p);
            }
            writer.endArray();
            UserPropertiesServlet.writeUser(upc.getAuthorizableId(), authorizable, writer);
            block5 : for (String propName : upc.getPropertyNames()) {
                String[] values = upc.getProperty(propName, null, String[].class);
                switch (values.length) {
                    case 0: {
                        writer.key(propName).value((Object)"");
                        continue block5;
                    }
                    case 1: {
                        JSONUtil.writeWithProtected((JSONWriter)writer, (String)propName, (String)values[0], (XSSFilter)this.xss);
                        continue block5;
                    }
                }
                JSONUtil.writeWithProtected((JSONWriter)writer, (String)propName, (String[])values, (XSSFilter)this.xss);
            }
        } else {
            log.debug("Cannot access user properties at {0} (parameter: {1})", (Object)resource.getPath(), (Object)param);
        }
        writer.endObject();
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        block36 : {
            HtmlResponse errorResponse = null;
            ResourceResolver resolver = request.getResourceResolver();
            Resource resource = request.getResource();
            Session session = null;
            try {
                if (this.service != null) {
                    UserProperties userProperties;
                    session = ((Node)resource.adaptTo(Node.class)).getSession();
                    UserPropertiesManager mgr = this.service.createUserPropertiesManager(session, resolver);
                    String propPath = request.getParameter("path");
                    Authorizable authorizable = (Authorizable)resource.adaptTo(Authorizable.class);
                    if (authorizable == null) {
                        userProperties = (UserProperties)resource.adaptTo(UserProperties.class);
                        if (userProperties != null) {
                            UserManager uMgr = (UserManager)resolver.adaptTo(UserManager.class);
                            authorizable = uMgr.getAuthorizable(userProperties.getAuthorizableID());
                        }
                    } else {
                        userProperties = mgr.getUserProperties(authorizable, propPath);
                    }
                    if (userProperties == null && propPath != null && authorizable != null) {
                        String authId = authorizable.getID();
                        log.debug("Create new user properties for authorizable {0} and path {1}", (Object)authId, (Object)propPath);
                        userProperties = mgr.createUserProperties(authId, propPath);
                    }
                    if (userProperties != null) {
                        Node n = userProperties.getNode();
                        RequestParameterMap params = request.getRequestParameterMap();
                        ValueFactory vf = session.getValueFactory();
                        block23 : for (String paramName : params.keySet()) {
                            if (UserPropertiesServlet.isReservedParameter(paramName, RESERVED)) continue;
                            RequestParameter[] values = params.getValues(paramName);
                            Value[] vs = new Value[values.length];
                            for (int i = 0; i < values.length; ++i) {
                                vs[i] = values[i].isFormField() ? vf.createValue(values[i].getString()) : vf.createValue(values[i].getInputStream());
                            }
                            switch (vs.length) {
                                case 0: {
                                    if (n.hasProperty(paramName)) {
                                        n.getProperty(paramName).remove();
                                        continue block23;
                                    }
                                    log.debug("Ignoring non existing property {0} with empty value.", (Object)paramName);
                                    continue block23;
                                }
                                case 1: {
                                    n.setProperty(paramName, vs[0]);
                                    continue block23;
                                }
                            }
                            n.setProperty(paramName, vs);
                        }
                        if (session.hasPendingChanges()) {
                            session.save();
                        }
                    } else {
                        String msg = "Incomplete request to create or update user properties.";
                        log.warn(msg);
                        errorResponse = UserPropertiesServlet.createErrorResponse(400, msg);
                    }
                    break block36;
                }
                String msg = "UserPropertiesService not available";
                log.warn(msg);
                errorResponse = UserPropertiesServlet.createErrorResponse(503, msg);
            }
            catch (AccessDeniedException e) {
                log.debug(e.getMessage());
                errorResponse = UserPropertiesServlet.createErrorResponse(401, (Exception)e);
            }
            catch (PathNotFoundException e) {
                log.debug(e.getMessage());
                errorResponse = UserPropertiesServlet.createErrorResponse(404, (Exception)e);
            }
            catch (Exception e) {
                log.debug(e.getMessage());
                errorResponse = UserPropertiesServlet.createErrorResponse(500, e);
            }
            finally {
                if (errorResponse != null) {
                    try {
                        if (session != null) {
                            session.refresh(false);
                        }
                    }
                    catch (RepositoryException e) {
                        log.warn("Cannot revert transient modifications.", (Object)e.getMessage());
                    }
                    errorResponse.send((HttpServletResponse)response, true);
                }
            }
        }
    }

    private static void writeUser(String authzId, Authorizable authorizable, JSONWriter writer) throws JSONException, RepositoryException {
        writer.key("user");
        writer.object();
        if (authorizable != null) {
            writer.key("authorizableId").value((Object)authorizable.getID());
            writer.key("home").value((Object)authorizable.getPath());
        } else {
            writer.key("authorizableId").value((Object)authzId);
        }
        writer.endObject();
    }

    protected void bindService(UserPropertiesService userPropertiesService) {
        this.service = userPropertiesService;
    }

    protected void unbindService(UserPropertiesService userPropertiesService) {
        if (this.service == userPropertiesService) {
            this.service = null;
        }
    }

    protected void bindXss(XSSFilter xSSFilter) {
        this.xss = xSSFilter;
    }

    protected void unbindXss(XSSFilter xSSFilter) {
        if (this.xss == xSSFilter) {
            this.xss = null;
        }
    }
}