You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2021/07/22 15:07:13 UTC

[sling-org-apache-sling-testing-clients] branch SLING-10649 created (now 32bafcf)

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

dklco pushed a change to branch SLING-10649
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git.


      at 32bafcf  SLING-10649 - Adding support for impersonation

This branch includes the following new commits:

     new 32bafcf  SLING-10649 - Adding support for impersonation

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[sling-org-apache-sling-testing-clients] 01/01: SLING-10649 - Adding support for impersonation

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch SLING-10649
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-clients.git

commit 32bafcf1192b020e143c82fd82d6a684c9785ba9
Author: Dan Klco <kl...@adobe.com>
AuthorDate: Thu Jul 22 11:06:42 2021 -0400

    SLING-10649 - Adding support for impersonation
---
 README.md                                          |   4 +
 .../apache/sling/testing/clients/SlingClient.java  |  36 +++++++
 .../sling/testing/clients/email/package-info.java  |   2 +-
 .../sling/testing/clients/html/package-info.java   |   2 +-
 .../apache/sling/testing/clients/package-info.java |   2 +-
 .../clients/SlingClientImpersonationTest.java      | 106 +++++++++++++++++++++
 6 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 2f862e7..8fe63b4 100644
--- a/README.md
+++ b/README.md
@@ -214,3 +214,7 @@ We have tried to make these methods as robust as possible. Their job is very cle
 
 Any input that does not respect the contract might not work. Check `AbstractSlingClientGetPathTest` and `AbstractSlingClientGetUrlTest`
 for an extensive list of cases that we have considered when writing these methods.
+
+##### How can I impersonate a user?
+* `client.impersonate(userId)` to impersonate
+* `client.impersonate(null)` to clear impersonation
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/testing/clients/SlingClient.java b/src/main/java/org/apache/sling/testing/clients/SlingClient.java
index baa3a0c..0785840 100644
--- a/src/main/java/org/apache/sling/testing/clients/SlingClient.java
+++ b/src/main/java/org/apache/sling/testing/clients/SlingClient.java
@@ -22,7 +22,9 @@ import static org.apache.http.HttpStatus.SC_OK;
 import java.io.File;
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
@@ -41,6 +43,7 @@ import org.apache.http.entity.ContentType;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.cookie.BasicClientCookie;
 import org.apache.sling.testing.clients.interceptors.DelayRequestInterceptor;
 import org.apache.sling.testing.clients.interceptors.HttpRequestResponseInterceptor;
 import org.apache.sling.testing.clients.interceptors.TestDescriptionInterceptor;
@@ -64,6 +67,7 @@ public class SlingClient extends AbstractSlingClient {
 
     public static final String DEFAULT_NODE_TYPE = "sling:OrderedFolder";
     public static final String CLIENT_CONNECTION_TIMEOUT_PROP = "sling.client.connection.timeout.seconds";
+    public static final String SUDO_COOKIE_NAME = "sling.sudo.cookie.name";
 
     /**
      * Constructor used by Builders and adaptTo(). <b>Should never be called directly from the code.</b>
@@ -543,6 +547,10 @@ public class SlingClient extends AbstractSlingClient {
         return importContent(parentPath, "json", json.toString(), expectedStatus);
     }
 
+    private String getSudoCookieName() {
+        return Optional.ofNullable(this.getValue(SUDO_COOKIE_NAME)).orElse("sling.sudo");
+    }
+
     /**
      * Get the UUID of a repository path
      *
@@ -580,6 +588,34 @@ public class SlingClient extends AbstractSlingClient {
         return uuidNode.getValueAsText();
     }
 
+    @Override
+    public String getUser() {
+        // get the username from the sudo cookie or default from client config
+        return getCookieStore().getCookies().stream().filter(c -> c.getName().equals(getSudoCookieName())).findFirst()
+                .map(c -> c.getValue().replace("\"", "")).orElse(super.getUser());
+    }
+
+    /**
+     * Impersonate user with the given <code>userId</code>
+     * <p>
+     * By impersonating a user SlingClient can access content from that user eye view.
+     * </p>
+     *Passing a <code>null</code> will clear impersonation.
+     *
+     * @param userId   the user to impersonate. A <code>null</code> value clears impersonation
+     */
+    public SlingClient impersonate(String userId)  {
+        BasicClientCookie c = new BasicClientCookie(getSudoCookieName(), "\"" + userId + "\"");
+        c.setPath("/");
+        c.setDomain(getUrl().getHost());
+        if(userId == null || "-".equals(userId)){
+            // setting expiry date in the past will remove the cookie
+            c.setExpiryDate(new Date(0));
+        }
+        getCookieStore().addCookie(c);
+        return this;
+    }
+
     //
     // InternalBuilder class and builder related methods
     //
diff --git a/src/main/java/org/apache/sling/testing/clients/email/package-info.java b/src/main/java/org/apache/sling/testing/clients/email/package-info.java
index 906392d..01de7b2 100644
--- a/src/main/java/org/apache/sling/testing/clients/email/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/email/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("1.2.0")
+@Version("1.3.0")
 package org.apache.sling.testing.clients.email;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/html/package-info.java b/src/main/java/org/apache/sling/testing/clients/html/package-info.java
index 7c795ae..2723070 100644
--- a/src/main/java/org/apache/sling/testing/clients/html/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/html/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("2.3.0")
+@Version("2.4.0")
 package org.apache.sling.testing.clients.html;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/testing/clients/package-info.java b/src/main/java/org/apache/sling/testing/clients/package-info.java
index 9e17199..8b3a108 100644
--- a/src/main/java/org/apache/sling/testing/clients/package-info.java
+++ b/src/main/java/org/apache/sling/testing/clients/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-@Version("2.3.0")
+@Version("2.4.0")
 package org.apache.sling.testing.clients;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/test/java/org/apache/sling/testing/clients/SlingClientImpersonationTest.java b/src/test/java/org/apache/sling/testing/clients/SlingClientImpersonationTest.java
new file mode 100644
index 0000000..789a646
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/clients/SlingClientImpersonationTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.testing.clients;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.http.cookie.Cookie;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SlingClientImpersonationTest {
+
+    private SlingClient slingClient;
+
+    @Before
+    public void setup() throws ClientException, URISyntaxException {
+        slingClient = new SlingClient(new URI("http://localhost:8080"), "admin", "pass");
+        assertEquals("admin", slingClient.getUser());
+    }
+
+    private Cookie getSudoCookie(String cookieName) {
+        return slingClient.getCookieStore().getCookies().stream().filter(c -> c.getName().equals(cookieName)).findAny()
+                .orElse(null);
+    }
+
+    @Test
+    public void testImpersonate() throws Exception {
+
+        slingClient.impersonate("user");
+
+        assertEquals("user", slingClient.getUser());
+
+        Cookie sudoCookie = getSudoCookie("sling.sudo");
+
+        assertNotNull(sudoCookie);
+        assertEquals("\"user\"", sudoCookie.getValue());
+    }
+
+    @Test
+    public void testUndoImpersonation() throws Exception {
+
+        slingClient.impersonate("user");
+
+        assertEquals("user", slingClient.getUser());
+
+        slingClient.impersonate("-");
+        assertEquals("admin", slingClient.getUser());
+
+        Cookie sudoCookie = getSudoCookie("sling.sudo");
+
+        assertNull(sudoCookie);
+    }
+
+    @Test
+    public void testNullImpersonation() throws Exception {
+
+        slingClient.impersonate("user");
+
+        assertEquals("user", slingClient.getUser());
+
+        slingClient.impersonate(null);
+        assertEquals("admin", slingClient.getUser());
+
+        Cookie sudoCookie = getSudoCookie("sling.sudo");
+
+        assertNull(sudoCookie);
+    }
+
+    @Test
+    public void testDifferentSudoCookie() throws Exception {
+        String sudoCookieName = "sudo.make.me.a.sandwich";
+
+        slingClient.addValue(SlingClient.SUDO_COOKIE_NAME, sudoCookieName);
+
+        slingClient.impersonate("user");
+
+        assertEquals("user", slingClient.getUser());
+
+        Cookie defaultSudoCookie = getSudoCookie("sling.sudo");
+        assertNull(defaultSudoCookie);
+
+        Cookie customSudoCookie = getSudoCookie(sudoCookieName);
+        assertNotNull(customSudoCookie);
+        assertEquals("\"user\"", customSudoCookie.getValue());
+    }
+
+}