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

cziegeler pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-core.git


The following commit(s) were added to refs/heads/master by this push:
     new e6e447a  SLING-10255 : Refactor: Move auth handlers management into 
separate component
e6e447a is described below

commit e6e447a26bddf91a906010478d79d8676cf2bef3
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Wed Mar 24 13:47:30 2021 +0100

    SLING-10255 : Refactor: Move auth handlers management into separate 
component
---
 .../impl/AbstractAuthenticationHandlerHolder.java  |   3 +-
 .../sling/auth/core/impl/PathBasedHolder.java      |  25 +++++
 .../sling/auth/core/impl/PathBasedHolderCache.java |  10 +-
 .../sling/auth/core/impl/SlingAuthenticator.java   |  77 ++-----------
 .../sling/auth/core/impl/PathBasedHolderTest.java  | 125 +++++++++++++++++++++
 .../auth/core/impl/SlingAuthenticatorTest.java     |  72 ------------
 6 files changed, 166 insertions(+), 146 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/auth/core/impl/AbstractAuthenticationHandlerHolder.java
 
b/src/main/java/org/apache/sling/auth/core/impl/AbstractAuthenticationHandlerHolder.java
index 91f63cc..33acaa0 100644
--- 
a/src/main/java/org/apache/sling/auth/core/impl/AbstractAuthenticationHandlerHolder.java
+++ 
b/src/main/java/org/apache/sling/auth/core/impl/AbstractAuthenticationHandlerHolder.java
@@ -37,7 +37,7 @@ public abstract class AbstractAuthenticationHandlerHolder 
extends
         PathBasedHolder implements AuthenticationHandler {
 
     protected AbstractAuthenticationHandlerHolder(final String fullPath,
-            final ServiceReference serviceReference) {
+            final ServiceReference<?> serviceReference) {
         super(fullPath, serviceReference);
     }
 
@@ -194,5 +194,4 @@ public abstract class AbstractAuthenticationHandlerHolder 
extends
         }
         return oldValue;
     }
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolder.java 
b/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolder.java
index 26d0379..ea1942e 100644
--- a/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolder.java
+++ b/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolder.java
@@ -145,6 +145,31 @@ public abstract class PathBasedHolder implements 
Comparable<PathBasedHolder> {
     }
 
     /**
+     * Check if the holder matches the provided path
+     * @path The path to check
+     * @return {@code true} If the holder path matches this path.
+     */
+    public boolean isPathRequiresHandler(final String path) {
+        if (("/").equals(this.path)) {
+            return true;
+        }
+
+        final int holderPathLength = this.path.length();
+        if (path.length() < holderPathLength) {
+            return false;
+        }
+
+        if (path.equals(this.path)) {
+            return true;
+        }
+
+        if (path.startsWith(this.path) && (path.charAt(holderPathLength) == 
'/' || path.charAt(holderPathLength) == '.')) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
      * Compares this instance to the <code>other</code> PathBasedHolder
      * instance. Comparison takes into account the {@link #path} first. If they
      * are not equal the result is returned: If the <code>other</code> path is
diff --git 
a/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolderCache.java 
b/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolderCache.java
index 37427c8..68d9ddf 100644
--- a/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolderCache.java
+++ b/src/main/java/org/apache/sling/auth/core/impl/PathBasedHolderCache.java
@@ -80,10 +80,12 @@ public class PathBasedHolderCache<Type extends 
PathBasedHolder> {
     }
 
     public Collection<Type>[] findApplicableHolders(final HttpServletRequest 
request) {
-        final String hostname = request.getServerName()
-              + (request.getServerPort() != 80 && request.getServerPort() != 
443
-                ? ":" + request.getServerPort()
-                : "");
+        final String hostname;
+        if ( request.getServerPort() != 80 && request.getServerPort() != 443 ) 
{
+            hostname = 
request.getServerName().concat(":").concat(String.valueOf(request.getServerPort()));
+        } else {
+            hostname = request.getServerName();
+        }
 
         @SuppressWarnings("unchecked")
         final SortedSet<Type>[] result = new SortedSet[4];
diff --git 
a/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java 
b/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
index 5c5ebef..5fa742d 100644
--- a/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
+++ b/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
@@ -22,16 +22,11 @@ import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Hashtable;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
 
 import javax.jcr.SimpleCredentials;
 import javax.security.auth.login.AccountLockedException;
@@ -53,8 +48,6 @@ import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.auth.core.AuthConstants;
 import org.apache.sling.auth.core.AuthUtil;
 import org.apache.sling.auth.core.AuthenticationSupport;
-import 
org.apache.sling.auth.core.impl.engine.EngineAuthenticationHandlerHolder;
-import org.apache.sling.auth.core.spi.AbstractAuthenticationHandler;
 import org.apache.sling.auth.core.spi.AuthenticationFeedbackHandler;
 import org.apache.sling.auth.core.spi.AuthenticationHandler;
 import org.apache.sling.auth.core.spi.AuthenticationInfo;
@@ -63,8 +56,6 @@ import 
org.apache.sling.auth.core.spi.DefaultAuthenticationFeedbackHandler;
 import org.apache.sling.commons.metrics.MetricsService;
 import org.apache.sling.commons.metrics.Timer;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.FieldOption;
@@ -86,7 +77,6 @@ import org.osgi.service.metatype.annotations.AttributeType;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 import org.osgi.service.metatype.annotations.Option;
-import org.osgi.util.converter.Converters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -523,7 +513,7 @@ public class SlingAuthenticator implements Authenticator,
             final Collection<AbstractAuthenticationHandlerHolder> holderList = 
holdersArray[m];
             if ( holderList != null ) {
                 for (AbstractAuthenticationHandlerHolder holder : holderList) {
-                    if (isNodeRequiresAuthHandler(path, holder.path)) {
+                    if (holder.isPathRequiresHandler(path)) {
                         log.debug("login: requesting authentication using 
handler: {}",
                             holder);
 
@@ -584,7 +574,7 @@ public class SlingAuthenticator implements Authenticator,
             final Collection<AbstractAuthenticationHandlerHolder> holderSet = 
holdersArray[m];
             if (holderSet != null) {
                 for (AbstractAuthenticationHandlerHolder holder : holderSet) {
-                    if (isNodeRequiresAuthHandler(path, holder.path)) {
+                    if (holder.isPathRequiresHandler(path)) {
                         log.debug("logout: dropping authentication using 
handler: {}",
                             holder);
 
@@ -624,33 +614,6 @@ public class SlingAuthenticator implements Authenticator,
         }
     }
 
-    // ---------- WebConsolePlugin support
-
-    /**
-     * Returns the list of registered authentication handlers as a map
-     */
-    Map<String, List<String>> getAuthenticationHandler() {
-        List<AbstractAuthenticationHandlerHolder> registeredHolders = 
this.authHandlersManager.getHolders();
-        LinkedHashMap<String, List<String>> handlerMap = new 
LinkedHashMap<String, List<String>>();
-        for (AbstractAuthenticationHandlerHolder holder : registeredHolders) {
-            List<String> provider = handlerMap.get(holder.fullPath);
-            if (provider == null) {
-                provider = new ArrayList<String>();
-                handlerMap.put(holder.fullPath, provider);
-            }
-            provider.add(holder.getProvider());
-        }
-        if (httpBasicHandler != null) {
-            List<String> provider = handlerMap.get("/");
-            if (provider == null) {
-                provider = new ArrayList<String>();
-                handlerMap.put("/", provider);
-            }
-            provider.add(httpBasicHandler.toString());
-        }
-        return handlerMap;
-    }
-
     // ---------- internal
 
     /**
@@ -687,7 +650,7 @@ public class SlingAuthenticator implements Authenticator,
             final Collection<AbstractAuthenticationHandlerHolder> local = 
localArray[m];
             if (local != null) {
                 for (AbstractAuthenticationHandlerHolder holder : local) {
-                    if (isNodeRequiresAuthHandler(path, holder.path)){
+                    if (holder.isPathRequiresHandler(path)){
                         final AuthenticationInfo authInfo = 
holder.extractCredentials(
                             request, response);
 
@@ -876,7 +839,7 @@ public class SlingAuthenticator implements Authenticator,
             final Collection<AuthenticationRequirementHolder> holders = 
holderSetArray[m];
             if (holders != null) {
                 for (AuthenticationRequirementHolder holder : holders) {
-                    if (isNodeRequiresAuthHandler(path, holder.path)) {
+                    if (holder.isPathRequiresHandler(path)) {
                         return !holder.requiresAuthentication();
                     }
                 }
@@ -887,28 +850,6 @@ public class SlingAuthenticator implements Authenticator,
         return false;
     }
 
-   private boolean isNodeRequiresAuthHandler(String path, String holderPath) {
-        if (("/").equals(holderPath)) {
-            return true;
-        }
-
-        int holderPathLength = holderPath.length();
-
-        if (path.length() < holderPathLength) {
-            return false;
-        }
-
-        if (path.equals(holderPath)) {
-            return true;
-        }
-
-        if (path.startsWith(holderPath) && (path.charAt(holderPathLength) == 
'/' || path.charAt(holderPathLength) == '.')) {
-            return true;
-        }
-        return false;
-    }
-
-
     /**
      * Returns credentials to use for anonymous resource access. If an 
anonymous
      * user is configued, this returns an {@link AuthenticationInfo} instance
@@ -1043,7 +984,7 @@ public class SlingAuthenticator implements Authenticator,
      * are implemented by this method:
      * <ul>
      * <li>If the request is a credentials validation request (see
-     * {@link 
AbstractAuthenticationHandler#isValidateRequest(HttpServletRequest)}
+     * {@link AuthUtil#isValidateRequest(HttpServletRequest)}
      * ) a 403/FORBIDDEN response is sent back.</li>
      * <li>If the request is not considered a
      * {@link #isBrowserRequest(HttpServletRequest) browser request} and the
@@ -1063,12 +1004,12 @@ public class SlingAuthenticator implements 
Authenticator,
      * client.</li>
      * </ul>
      * <p>
-     * If a 403/FORBIDDEN response is sent back the {@link 
AbstractAuthenticationHandler#X_REASON} header is
+     * If a 403/FORBIDDEN response is sent back the {@link AuthUtil#X_REASON} 
header is
      * set to a either the value of the
      * {@link AuthenticationHandler#FAILURE_REASON} request attribute or to 
some
      * generic description describing the reason. To actually send the response
      * the
-     * {@link AbstractAuthenticationHandler#sendInvalid(HttpServletRequest, 
HttpServletResponse)}
+     * {@link AuthUtil#sendInvalid(HttpServletRequest, HttpServletResponse)}
      * method is called.
      * <p>
      * This method is called in three situations:
@@ -1084,10 +1025,10 @@ public class SlingAuthenticator implements 
Authenticator,
      * @param request The current request
      * @param response The response to send the credentials request (or access
      *            denial to)
-     * @see AbstractAuthenticationHandler#isValidateRequest(HttpServletRequest)
+     * @see AuthUtil#isValidateRequest(HttpServletRequest)
      * @see #isBrowserRequest(HttpServletRequest)
      * @see #isAjaxRequest(HttpServletRequest)
-     * @see AbstractAuthenticationHandler#sendInvalid(HttpServletRequest,
+     * @see AuthUtil#sendInvalid(HttpServletRequest,
      *      HttpServletResponse)
      */
     private void doLogin(HttpServletRequest request,
diff --git 
a/src/test/java/org/apache/sling/auth/core/impl/PathBasedHolderTest.java 
b/src/test/java/org/apache/sling/auth/core/impl/PathBasedHolderTest.java
new file mode 100644
index 0000000..fe79ffd
--- /dev/null
+++ b/src/test/java/org/apache/sling/auth/core/impl/PathBasedHolderTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.auth.core.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class PathBasedHolderTest {
+
+    @Test public void TestIsPathRequiresHandlerRoot() {
+        final PathBasedHolder holder = new PathBasedHolder("/", null){};
+
+        assertTrue(holder.isPathRequiresHandler("/"));
+        assertTrue(holder.isPathRequiresHandler("/a"));
+        assertTrue(holder.isPathRequiresHandler("/a/b"));
+        assertTrue(holder.isPathRequiresHandler("/a/b/c"));
+        assertTrue(holder.isPathRequiresHandler("/a.html"));
+        assertTrue(holder.isPathRequiresHandler("/a/b.html"));
+        assertTrue(holder.isPathRequiresHandler("/a/b/c.html"));
+    }
+
+    @Test public void TestIsPathRequiresHandlerPrefix() {
+        final PathBasedHolder holder = new PathBasedHolder("/a/b", null){};
+
+        assertFalse(holder.isPathRequiresHandler("/"));
+        assertFalse(holder.isPathRequiresHandler("/a"));
+        assertTrue(holder.isPathRequiresHandler("/a/b"));
+        assertTrue(holder.isPathRequiresHandler("/a/b/c"));
+        assertFalse(holder.isPathRequiresHandler("/a.html"));
+        assertTrue(holder.isPathRequiresHandler("/a/b.html"));
+        assertTrue(holder.isPathRequiresHandler("/a/b/c.html"));
+
+        assertFalse(holder.isPathRequiresHandler("/a/c"));
+    }
+
+    @Test
+    public void test_childNodeAuthenticationHandlerPath() throws Throwable {
+        final String requestPath = "/content/test/test2";
+        final String handlerPath = "/content/test";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertTrue(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_siblingNodeAuthenticationHandlerPath() throws Throwable {
+        final String requestPath = 
"/content/test2.html/en/2016/09/19/test.html";
+        final String handlerPath = "/content/test";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertFalse(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_actualNodeAuthenticationHandlerPath() throws Throwable {
+        final String requestPath = "/content/test";
+        final String handlerPath = "/content/test";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertTrue(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_rootNodeAuthenticationHandlerPath() throws Throwable {
+        final String requestPath = "/content/test";
+        final String handlerPath = "/";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertTrue(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_requestPathSelectorsAreTakenInConsideration() throws 
Throwable {
+        final String requestPath = 
"/content/test.selector1.selector2.html/en/2016/test.html";
+        final String handlerPath = "/content/test";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertTrue(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_requestPathSelectorsSiblingAreTakenInConsideration() 
throws Throwable {
+        final String requestPath = 
"/content/test.selector1.selector2.html/en/2016/09/19/test.html";
+        final String handlerPath = "/content/test2";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertFalse(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_requestPathBackSlash() throws Throwable {
+        final String requestPath = "/page1\\somesubepage";
+        final String handlerPath = "/page";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertFalse(holder.isPathRequiresHandler(requestPath));
+    }
+
+    @Test
+    public void test_emptyNodeAuthenticationHandlerPath() throws Throwable {
+        final String requestPath = "/content/test";
+        final String handlerPath = "";
+        final PathBasedHolder holder = new PathBasedHolder(handlerPath, 
null){};
+
+        assertTrue(holder.isPathRequiresHandler(requestPath));
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java 
b/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java
index 2954e4e..676f0ce 100644
--- a/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java
+++ b/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java
@@ -322,78 +322,6 @@ public class SlingAuthenticatorTest {
         Assert.assertFalse(AUTH_TYPE.equals(authInfo.getAuthType()));
     }
 
-    @Test
-    public void test_childNodeAuthenticationHandlerPath() throws Throwable {
-        final String requestPath = "/content/test/test2";
-        final String handlerPath = "/content/test";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_siblingNodeAuthenticationHandlerPath() throws Throwable {
-        final String requestPath = 
"/content/test2.html/en/2016/09/19/test.html";
-        final String handlerPath = "/content/test";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertFalse( 
(boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_actualNodeAuthenticationHandlerPath() throws Throwable {
-        final String requestPath = "/content/test";
-        final String handlerPath = "/content/test";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_rootNodeAuthenticationHandlerPath() throws Throwable {
-        final String requestPath = "/content/test";
-        final String handlerPath = "/";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_requestPathSelectorsAreTakenInConsideration() throws 
Throwable {
-        final String requestPath = 
"/content/test.selector1.selector2.html/en/2016/test.html";
-        final String handlerPath = "/content/test";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_requestPathSelectorsSiblingAreTakenInConsideration() 
throws Throwable {
-        final String requestPath = 
"/content/test.selector1.selector2.html/en/2016/09/19/test.html";
-        final String handlerPath = "/content/test2";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertFalse( 
(boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_requestPathBackSlash() throws Throwable {
-        final String requestPath = "/page1\\somesubepage";
-        final String handlerPath = "/page";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertFalse( 
(boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
-    @Test
-    public void test_emptyNodeAuthenticationHandlerPath() throws Throwable {
-        final String requestPath = "/content/test";
-        final String handlerPath = "";
-        final SlingAuthenticator slingAuthenticator = 
this.createSlingAuthenticator();
-
-        Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, 
"isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new 
Object[] {requestPath, handlerPath}));
-    }
-
     //---------------------------- PRIVATE METHODS 
-----------------------------
 
     /**

Reply via email to