This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch feature/console-improvements
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git

commit 11f26ad706a350269e27ca42a2cbcf22a4724ce1
Author: Robert Munteanu <[email protected]>
AuthorDate: Fri Aug 5 14:24:44 2022 +0300

    SLING-11513 - Allow impersonating an user when checking the result of a 
map/resolve call
    
    - extend the form to optionally accept a user to impersonate
    - use the resolver of the current user as a basis for impersonation
    - make sure that we don't accidentally generate imports from the auth.core 
and jcr.resource bundles,
      they are only used for the constant values, which are inlined.
---
 bnd.bnd                                            |  2 +
 pom.xml                                            | 14 ++++++
 .../console/ResourceResolverWebConsolePlugin.java  | 58 +++++++++++++++++++---
 3 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
index d4d7e52..2236400 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -1,6 +1,8 @@
 Import-Package:\
   javax.jcr;resolution:=optional,\
   org.apache.sling.commons.metrics;resolution:=optional,\
+  !org.apache.sling.auth.*,\
+  !org.apache.sling.jcr.*,\
   *
 
 Provide-Capability:\
diff --git a/pom.xml b/pom.xml
index 86a48e1..e79ea3b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -134,6 +134,20 @@
             <version>1.3.4</version>
             <scope>provided</scope>
         </dependency>
+        <!-- for constant values only -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.auth.core</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- for constant values only -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.resource</artifactId>
+            <version>3.0.0</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
diff --git 
a/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java
 
b/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java
index 4ce1629..d453de8 100644
--- 
a/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java
+++ 
b/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java
@@ -26,12 +26,15 @@ import java.net.URLEncoder;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
+import javax.jcr.Session;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -40,12 +43,16 @@ import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.sling.api.request.ResponseUtil;
+import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.resource.mapping.ResourceMapper;
 import org.apache.sling.api.resource.runtime.RuntimeService;
 import org.apache.sling.api.resource.runtime.dto.ResourceProviderDTO;
 import org.apache.sling.api.resource.runtime.dto.ResourceProviderFailureDTO;
 import org.apache.sling.api.resource.runtime.dto.RuntimeDTO;
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.apache.sling.jcr.resource.api.JcrResourceConstants;
 import 
org.apache.sling.resourceresolver.impl.CommonResourceResolverFactoryImpl;
 import org.apache.sling.resourceresolver.impl.helper.URI;
 import org.apache.sling.resourceresolver.impl.helper.URIException;
@@ -63,11 +70,12 @@ public class ResourceResolverWebConsolePlugin extends 
HttpServlet {
     private static final long serialVersionUID = 0;
 
     private static final String ATTR_TEST = "plugin.test";
-
     private static final String ATTR_SUBMIT = "plugin.submit";
+    private static final String ATTR_USER = "plugin.user";
 
     private static final String PAR_MSG = "msg";
     private static final String PAR_TEST = "test";
+    private static final String PAR_USER = "user";
 
     private final transient CommonResourceResolverFactoryImpl resolverFactory;
 
@@ -116,6 +124,7 @@ public class ResourceResolverWebConsolePlugin extends 
HttpServlet {
         } else {
             test = null;
         }
+        final String user = request.getParameter(PAR_USER);
 
         final PrintWriter pw = response.getWriter();
 
@@ -160,14 +169,22 @@ public class ResourceResolverWebConsolePlugin extends 
HttpServlet {
                         + "clearly marked, and the others listed for 
completeness.");
 
         pw.println("<tr class='content'>");
-        pw.println("<td class='content'>Test</td>");
         pw.print("<td class='content' colspan='2'>");
-        pw.print("<form method='post'>");
+        pw.println("<form method='post'>");
+        pw.print("Test ");
         pw.print("<input type='text' name='" + ATTR_TEST + "' value='");
         if (test != null) {
             pw.print(ResponseUtil.escapeXml(test));
         }
-        pw.println("' class='input' size='50'>");
+        pw.println("' class='input' size='20'>");
+        pw.print("User (optional)");
+        pw.print("<input type='text' name='" + ATTR_USER + "' value='");
+        if ( user != null ) {
+            pw.print(ResponseUtil.escapeXml(user));
+        }
+        pw.println("' class='input' size='20'>");
+        pw.println("</td>");
+        pw.print("<td class='content'>");
         pw.println("&nbsp;&nbsp;<input type='submit' name='" + ATTR_SUBMIT
                 + "' value='Resolve' class='submit'>");
         pw.println("&nbsp;&nbsp;<input type='submit' name='" + ATTR_SUBMIT
@@ -213,6 +230,7 @@ public class ResourceResolverWebConsolePlugin extends 
HttpServlet {
             HttpServletResponse response) throws ServletException, IOException 
{
 
         final String test = request.getParameter(ATTR_TEST);
+        final String user = request.getParameter(ATTR_USER);
         String msg = null;
         if (test != null) {
 
@@ -221,7 +239,12 @@ public class ResourceResolverWebConsolePlugin extends 
HttpServlet {
                 // prepare the request for the resource resolver
                 HttpServletRequest helper = new ResolverRequest(request, test);
 
-                resolver = 
resolverFactory.getServiceResourceResolver(this.resolverFactory.getServiceUserAuthenticationInfo("console"));
+                // impersonate if asked
+                if ( user != null && user.length() > 0 ) {
+                    resolver = getImpersonatedResourceResolver(request, user);
+                } else {
+                    resolver = 
resolverFactory.getServiceResourceResolver(this.resolverFactory.getServiceUserAuthenticationInfo("console"));
+                }
 
                 // map or resolve as instructed
                 Object result;
@@ -255,16 +278,39 @@ public class ResourceResolverWebConsolePlugin extends 
HttpServlet {
         // finally redirect
         final String path = request.getContextPath() + request.getServletPath()
         + request.getPathInfo();
-        final String redirectTo;
+        String redirectTo;
         if (msg == null) {
             redirectTo = path;
         } else {
             redirectTo = path + '?' + PAR_MSG + '=' + encodeParam(msg) + '&'
                     + PAR_TEST + '=' + encodeParam(test);
+                if ( user != null && user.length() > 0 ) {
+                    redirectTo += '&' + PAR_USER + '=' + encodeParam(user);
+                }
         }
         response.sendRedirect(redirectTo);
     }
 
+    private ResourceResolver 
getImpersonatedResourceResolver(HttpServletRequest request, final String user)
+            throws LoginException {
+
+        // resolver is set by the auth.core bundle in case of successful 
authentication, so it should
+        // always be there
+        Object resolverAttribute = 
request.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
+        if ( !(resolverAttribute instanceof ResourceResolver) ) {
+            throw new IllegalArgumentException("No " + 
ResourceResolver.class.getSimpleName() + " found in request, unable to proceed 
with impersonation");
+        }
+
+        @SuppressWarnings("resource") // not a leak, we don't own this resolver
+        ResourceResolver currentResolver = (ResourceResolver) 
resolverAttribute;
+
+        Map<String, Object> authenticationInfo = new HashMap<>();
+        authenticationInfo.put(ResourceResolverFactory.USER_IMPERSONATION, 
user);
+        
authenticationInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, 
currentResolver.adaptTo(Session.class));
+
+        return resolverFactory.getResourceResolver(authenticationInfo);
+    }
+
     private static String mappingsToString(Collection<String> allMappings) {
         if ( allMappings.size() == 0 )
             return "(no mappings)"; // should not happen

Reply via email to