You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2009/04/21 22:14:28 UTC

svn commit: r767281 - in /ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication: ./ api/ example/

Author: jaz
Date: Tue Apr 21 20:14:27 2009
New Revision: 767281

URL: http://svn.apache.org/viewvc?rev=767281&view=rev
Log:
initial implementation of new Authenticator API. 

Part 1: define the API for external authentication modules (done)
Part 2: update LoginServices to call AuthHelper for external modules (in progress)
Part 3: create example Authenticator (in progress)
Part 4: update LDAP implementation to use new API (not started)

Added:
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthHelper.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthInterfaceResolver.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthenticationComparator.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/Authenticator.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/AuthenticatorException.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestFailAuthenticator.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestPassAuthenticator.java

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthHelper.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthHelper.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthHelper.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthHelper.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,93 @@
+package org.ofbiz.common.authentication;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.common.authentication.api.Authenticator;
+import org.ofbiz.common.authentication.api.AuthenticatorException;
+import org.ofbiz.service.LocalDispatcher;
+
+/**
+ * AuthHelper
+ */
+public class AuthHelper {
+
+    private static final String module = AuthHelper.class.getName();
+    protected static List<Authenticator> authenticators = new ArrayList<Authenticator>();
+    protected static boolean authenticatorsLoaded = false;
+
+
+    public static boolean authenticate(String username, String password, boolean isServiceAuth) throws AuthenticatorException {
+        if (!authenticatorsLoaded) throw new AuthenticatorException("Authenticators never loaded; be sure to call AuthHelper.loadAuthenticators()");
+        for (Authenticator auth : authenticators) {
+            boolean pass = auth.authenticate(username, password, isServiceAuth);
+            if (pass) {
+                return true;
+            } else if (auth.isSingleAuthenticator()) {
+                throw new AuthenticatorException();
+            }
+        }
+        return false;
+    }
+
+    public static void logout(String username) throws AuthenticatorException {
+        if (!authenticatorsLoaded) throw new AuthenticatorException("Authenticators never loaded; be sure to call AuthHelper.loadAuthenticators()");
+        for (Authenticator auth : authenticators) {
+            auth.logout(username);
+        }
+    }
+
+    public static void syncUser(String username) throws AuthenticatorException {
+        if (!authenticatorsLoaded) throw new AuthenticatorException("Authenticators never loaded; be sure to call AuthHelper.loadAuthenticators()");
+        for (Authenticator auth : authenticators) {
+            if (auth.isUserSynchronized()) {
+                auth.syncUser(username);
+            }
+        }
+    }
+
+    public static void updatePassword(String username, String password, String newPassword) throws AuthenticatorException {
+        if (!authenticatorsLoaded) throw new AuthenticatorException("Authenticators never loaded; be sure to call AuthHelper.loadAuthenticators()");
+        for (Authenticator auth : authenticators) {
+            auth.updatePassword(username, password, newPassword);            
+        }
+    }
+
+    public static boolean authenticatorsLoaded() {
+        return authenticatorsLoaded;
+    }
+    
+    public static void loadAuthenticators(LocalDispatcher dispatcher) {
+        if (!authenticatorsLoaded) {
+            loadAuthenticators_internal(dispatcher);
+        }
+    }
+
+    private synchronized static void loadAuthenticators_internal(LocalDispatcher dispatcher) {
+        if (!authenticatorsLoaded) {
+            AuthInterfaceResolver resolver = new AuthInterfaceResolver();
+            List<Class> implementations = resolver.getImplementations();
+
+            for (Class c : implementations) {
+                try {
+                    Authenticator auth = (Authenticator) c.newInstance();
+                    if (auth.isEnabled()) {
+                        auth.initialize(dispatcher);                    
+                        authenticators.add(auth);
+                    }
+                } catch (InstantiationException e) {
+                    Debug.logError(e, module);
+                } catch (IllegalAccessException e) {
+                    Debug.logError(e, module);
+                } catch (ClassCastException e) {
+                    Debug.logError(e, module);
+                }
+            }
+
+            Collections.sort(authenticators, new AuthenticationComparator());
+            authenticatorsLoaded = true;
+        }
+    }
+}

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthInterfaceResolver.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthInterfaceResolver.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthInterfaceResolver.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthInterfaceResolver.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,159 @@
+package org.ofbiz.common.authentication;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.common.authentication.api.Authenticator;
+
+/**
+ * AuthInterfaceResolver
+ */
+public class AuthInterfaceResolver {
+
+    private static final String module = AuthInterfaceResolver.class.getName();
+    protected List<Class> authenticators = new ArrayList<Class>();
+    protected ClassLoader loader;
+
+    public AuthInterfaceResolver() {
+        loader = getContextClassLoader();
+    }
+
+    public List<Class> getImplementations() {
+        find("org.ofbiz");
+        return authenticators;
+    }
+
+    protected void find(String packageName) {
+        packageName = packageName.replace('.', '/');
+        Enumeration<URL> urls;
+
+        try {
+            urls = loader.getResources(packageName);
+        }
+        catch (IOException io) {
+            Debug.logWarning(io, "Could not read package: " + packageName, module);
+            return;
+        }
+
+        while (urls.hasMoreElements()) {
+            try {
+                String urlPath = urls.nextElement().getFile();
+                urlPath = URLDecoder.decode(urlPath, "UTF-8");
+                if (Debug.verboseOn())
+                    Debug.logVerbose("Found library file [" + urlPath + "]", module);
+
+                if (urlPath.startsWith("file:")) {
+                    urlPath = urlPath.substring(5);
+                }
+
+                if (urlPath.indexOf('!') > 0) {
+                    urlPath = urlPath.substring(0, urlPath.indexOf('!'));
+                }
+
+                if (Debug.verboseOn())
+                    Debug.logVerbose("Scanning for classes in [" + urlPath + "]", module);
+
+                File file = new File(urlPath);
+                if (file.isDirectory()) {
+                    readDirectory(packageName, file);
+                } else {
+                    readJar(packageName, file);
+                }
+            }
+            catch (IOException io) {
+                Debug.logError(io, "Could not read resource entries", module);
+            }
+        }
+    }
+
+    protected void readDirectory(String parent, File location) {
+        File[] files = location.listFiles();
+        StringBuffer buf;
+
+        if (files == null) {
+            Debug.logWarning("Could not list directory " + location.getAbsolutePath() + " when looking for component classes", module);
+            return;
+        }
+
+        for (File file : files) {
+            buf = new StringBuffer();
+            buf.append(parent);
+            if (buf.length() > 0)
+                buf.append("/");
+            buf.append(file.getName());
+            String packageOrClass = (parent == null ? file.getName() : buf.toString());
+
+            if (file.isDirectory()) {
+                readDirectory(packageOrClass, file);
+            } else if (file.getName().endsWith(".class")) {
+                checkFile(packageOrClass);
+            }
+        }
+    }
+
+    protected void readJar(String parent, File jarfile) {
+        try {
+            JarEntry entry;
+            JarInputStream jarStream = new JarInputStream(new FileInputStream(jarfile));
+
+            while ((entry = jarStream.getNextJarEntry()) != null) {
+                String name = entry.getName();
+                if (!entry.isDirectory() && name.startsWith(parent) && name.endsWith(".class")) {
+                    checkFile(name);
+                }
+            }
+        }
+        catch (IOException io) {
+            Debug.logError(io, "Could not search jar file [" + jarfile + "]", module);
+        }
+    }
+
+    protected void checkFile(String name) {
+        String externalName = name.substring(0, name.indexOf('.')).replace('/', '.');
+        if (Debug.verboseOn())
+            Debug.logVerbose("Converted file value [" + name + "] to class [" + externalName + "]", module);
+        try {
+            resolveClass(loader.loadClass(externalName));
+        } catch (ClassNotFoundException e) {
+            Debug.logWarning("No class found - " + externalName, module);
+        }
+    }
+
+    protected ClassLoader getContextClassLoader() {
+        return AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        ClassLoader cl = null;
+                        try {
+                            cl = Thread.currentThread().getContextClassLoader();
+
+                        } catch (SecurityException e) {
+                            Debug.logError(e, e.getMessage(), module);
+                        }
+                        return cl;
+                    }
+                });
+    }
+
+
+    public void resolveClass(Class clazz) {
+        Class[] ifaces = clazz.getInterfaces();
+        for (Class iface : ifaces) {
+            if (Authenticator.class.equals(iface)) {
+                authenticators.add(clazz);
+            }
+        }
+    }
+}
+

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthenticationComparator.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthenticationComparator.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthenticationComparator.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/AuthenticationComparator.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,55 @@
+package org.ofbiz.common.authentication;
+
+import java.util.Comparator;
+
+import org.ofbiz.common.authentication.api.Authenticator;
+
+/**
+ * AuthenticationComparator
+ */
+public class AuthenticationComparator implements Comparator {
+
+    /**
+     * Compares its two arguments for order.  Returns a negative integer,
+     * zero, or a positive integer as the first argument is less than, equal
+     * to, or greater than the second.<p>
+     * <p/>
+     * The implementor must ensure that <tt>sgn(compare(x, y)) ==
+     * -sgn(compare(y, x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This
+     * implies that <tt>compare(x, y)</tt> must throw an exception if and only
+     * if <tt>compare(y, x)</tt> throws an exception.)<p>
+     * <p/>
+     * The implementor must also ensure that the relation is transitive:
+     * <tt>((compare(x, y)&gt;0) &amp;&amp; (compare(y, z)&gt;0))</tt> implies
+     * <tt>compare(x, z)&gt;0</tt>.<p>
+     * <p/>
+     * Finally, the implementer must ensure that <tt>compare(x, y)==0</tt>
+     * implies that <tt>sgn(compare(x, z))==sgn(compare(y, z))</tt> for all
+     * <tt>z</tt>.<p>
+     * <p/>
+     * It is generally the case, but <i>not</i> strictly required that
+     * <tt>(compare(x, y)==0) == (x.equals(y))</tt>.  Generally speaking,
+     * any comparator that violates this condition should clearly indicate
+     * this fact.  The recommended language is "Note: this comparator
+     * imposes orderings that are inconsistent with equals."
+     *
+     * @param o1 the first object to be compared.
+     * @param o2 the second object to be compared.
+     * @return a negative integer, zero, or a positive integer as the
+     *         first argument is less than, equal to, or greater than the
+     *         second.
+     * @throws ClassCastException if the arguments' types prevent them from
+     *                            being compared by this Comparator.
+     */    
+    public int compare(Object o1, Object o2) {
+        Authenticator a1 = (Authenticator) o1;
+        Authenticator a2 = (Authenticator) o2;
+        if (a1.getWeight() < a2.getWeight()) {
+            return -1;
+        } else if (a1.getWeight() > a2.getWeight()) {
+            return 1;
+        } else {
+            return a1.getClass().getName().compareTo(a2.getClass().getName());
+        }
+    }
+}

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/Authenticator.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/Authenticator.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/Authenticator.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/Authenticator.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,73 @@
+package org.ofbiz.common.authentication.api;
+
+import org.ofbiz.service.LocalDispatcher;
+
+/**
+ * Authenticator
+ */
+public interface Authenticator {
+
+    /**
+     * Method called when authenticator is first initialized (the delegator
+     * object can be obtained from the LocalDispatcher)
+     * @param dispatcher The ServiceDispatcher to use for this Authenticator
+     */
+    public void initialize(LocalDispatcher dispatcher);
+
+    /**
+     * Method to authenticate a user
+     * @param username User's username
+     * @param password User's password
+     * @param isServiceAuth true if authentication is for a service call
+     * @return true if the user is authenticated
+     * @throws AuthenticatorException when a fatal error occurs during authentication
+     */
+    public boolean authenticate(String username, String password, boolean isServiceAuth) throws AuthenticatorException;
+
+    /**
+     * Logs a user out
+     * @param username User's username
+     * @throws AuthenticatorException when logout fails
+     */
+    public void logout(String username) throws AuthenticatorException;
+
+    /**
+     * Reads user information and syncs it to OFBiz (i.e. UserLogin, Person, etc)
+     * @param username User's username
+     * @throws AuthenticatorException user synchronization fails
+     */
+    public void syncUser(String username) throws AuthenticatorException;
+
+    /**
+     * Updates a user's password
+     * @param username User's username
+     * @param password User's current password
+     * @param newPassword User's new password
+     * @throws AuthenticatorException when update password fails
+     */
+    public void updatePassword(String username, String password, String newPassword) throws AuthenticatorException;
+
+    /**
+     * Weight of this authenticator (lower weights are run first)
+     * @return the weight of this Authenicator
+     */
+    public float getWeight();
+
+    /**
+     * Is the user synchronzied back to OFBiz 
+     * @return true if the user record is copied to the OFB database
+     */
+    public boolean isUserSynchronized();
+
+    /**
+     * Is this expected to be the only authenticator, if so errors will be thrown when users cannot be found 
+     * @return true if this is expected to be the only Authenticator
+     */
+    public boolean isSingleAuthenticator();
+
+    /**
+     * Flag to test if this Authenticator is enabled
+     * @return true if the Authenticator is enabled
+     */
+    public boolean isEnabled();
+}

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/AuthenticatorException.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/AuthenticatorException.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/AuthenticatorException.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/api/AuthenticatorException.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,81 @@
+package org.ofbiz.common.authentication.api;
+
+import java.util.List;
+
+import org.ofbiz.base.util.GeneralException;
+
+/**
+ * AuthenticatorException
+ */
+public class AuthenticatorException extends GeneralException {
+
+    /**
+     * Creates new <code>GeneralException</code> without detail message.
+     */
+    public AuthenticatorException() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>GeneralException</code> with the specified detail message.
+     *
+     * @param msg the detail message.
+     */
+    public AuthenticatorException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructs an <code>GeneralException</code> with the specified detail message and nested Exception.
+     *
+     * @param msg    the detail message.
+     * @param nested the nested exception.
+     */
+    public AuthenticatorException(String msg, Throwable nested) {
+        super(msg, nested);
+    }
+
+    /**
+     * Constructs an <code>GeneralException</code> with the specified detail message and nested Exception.
+     *
+     * @param nested the nested exception.
+     */
+    public AuthenticatorException(Throwable nested) {
+        super(nested);
+    }
+
+    /**
+     * Constructs an <code>GeneralException</code> with the specified detail message, list and nested Exception.
+     *
+     * @param msg      the detail message.
+     * @param messages error message list.
+     */
+    public AuthenticatorException(String msg, List<String> messages) {
+        super(msg, messages);
+    }
+
+    /**
+     * Constructs an <code>GeneralException</code> with the specified detail message, list and nested Exception.
+     *
+     * @param msg      the detail message.
+     * @param messages error message list.
+     * @param nested   the nexted exception
+     */
+    public AuthenticatorException(String msg, List<String> messages, Throwable nested) {
+        super(msg, messages, nested);
+    }
+
+    /**
+     * Constructs an <code>GeneralException</code> with the specified detail message list and nested Exception.
+     *
+     * @param messages error message list.
+     * @param nested   the nested exception.
+     */
+    public AuthenticatorException(List<String> messages, Throwable nested) {
+        super(messages, nested);
+    }
+
+    public AuthenticatorException(List<String> messages) {
+        super(messages);
+    }
+}

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestFailAuthenticator.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestFailAuthenticator.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestFailAuthenticator.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestFailAuthenticator.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,119 @@
+package org.ofbiz.common.authentication.example;
+
+import org.ofbiz.common.authentication.api.Authenticator;
+import org.ofbiz.common.authentication.api.AuthenticatorException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.entity.GenericDelegator;
+import org.ofbiz.base.util.Debug;
+
+/**
+ * LocalAuthenticator
+ */
+public class TestFailAuthenticator implements Authenticator {
+
+    private static final String module = TestFailAuthenticator.class.getName();
+    protected GenericDelegator delegator;
+    protected LocalDispatcher dispatcher;
+    protected float weight = 1;
+
+    /**
+     * Method called when authenticator is first initialized (the delegator
+     * object can be obtained from the LocalDispatcher)
+     *
+     * @param dispatcher The ServiceDispatcher to use for this Authenticator
+     */
+    public void initialize(LocalDispatcher dispatcher) {
+        this.dispatcher = dispatcher;
+        this.delegator = dispatcher.getDelegator();
+        Debug.logInfo(this.getClass().getName() + " Authenticator initialized", module);
+    }
+
+    /**
+     * Method to authenticate a user
+     *
+     * @param username      User's username
+     * @param password      User's password
+     * @param isServiceAuth true if authentication is for a service call
+     * @return true if the user is authenticated
+     * @throws org.ofbiz.common.authentication.api.AuthenticatorException
+     *          when a fatal error occurs during authentication
+     */
+    public boolean authenticate(String username, String password, boolean isServiceAuth) throws AuthenticatorException {
+        Debug.logInfo(this.getClass().getName() + " Authenticator authenticate() -- returning false", module);
+        return false;
+    }
+
+    /**
+     * Logs a user out
+     *
+     * @param username User's username
+     * @throws org.ofbiz.common.authentication.api.AuthenticatorException
+     *          when logout fails
+     */
+    public void logout(String username) throws AuthenticatorException {
+        Debug.logInfo(this.getClass().getName() + " Authenticator logout()", module);
+    }
+
+    /**
+     * Reads user information and syncs it to OFBiz (i.e. UserLogin, Person, etc)
+     *
+     * @param username User's username
+     * @throws org.ofbiz.common.authentication.api.AuthenticatorException
+     *          user synchronization fails
+     */
+    public void syncUser(String username) throws AuthenticatorException {
+        Debug.logInfo(this.getClass().getName() + " Authenticator syncUser()", module);
+        // no user info to sync
+    }
+
+    /**
+     * Updates a user's password
+     *
+     * @param username    User's username
+     * @param password    User's current password
+     * @param newPassword User's new password
+     * @throws org.ofbiz.common.authentication.api.AuthenticatorException
+     *          when update password fails
+     */
+    public void updatePassword(String username, String password, String newPassword) throws AuthenticatorException {
+        Debug.logInfo(this.getClass().getName() + " Authenticator updatePassword()", module);
+    }
+
+    /**
+     * Weight of this authenticator (lower weights are run first)
+     *
+     * @return the weight of this Authenicator
+     */
+    public float getWeight() {
+        return 1;
+    }
+
+    /**
+     * Is the user synchronzied back to OFBiz
+     *
+     * @return true if the user record is copied to the OFB database
+     */
+    public boolean isUserSynchronized() {
+        Debug.logInfo(this.getClass().getName() + " Authenticator isUserSynchronized()", module);
+        return true;
+    }
+
+    /**
+     * Is this expected to be the only authenticator, if so errors will be thrown when users cannot be found
+     *
+     * @return true if this is expected to be the only Authenticator
+     */
+    public boolean isSingleAuthenticator() {
+        Debug.logInfo(this.getClass().getName() + " Authenticator isSingleAuthenticator()", module);
+        return false;
+    }
+
+    /**
+     * Flag to test if this Authenticator is enabled
+     *
+     * @return true if the Authenticator is enabled
+     */
+    public boolean isEnabled() {
+        return false;
+    }
+}

Added: ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestPassAuthenticator.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestPassAuthenticator.java?rev=767281&view=auto
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestPassAuthenticator.java (added)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/authentication/example/TestPassAuthenticator.java Tue Apr 21 20:14:27 2009
@@ -0,0 +1,39 @@
+package org.ofbiz.common.authentication.example;
+
+import org.ofbiz.common.authentication.api.AuthenticatorException;
+import org.ofbiz.common.authentication.api.Authenticator;
+import org.ofbiz.base.util.Debug;
+
+/**
+ * TestPassAuthenticator
+ */
+public class TestPassAuthenticator extends TestFailAuthenticator implements Authenticator {
+
+    private static final String module = TestPassAuthenticator.class.getName();
+
+    /**
+     * Method to authenticate a user
+     *
+     * @param username      User's username
+     * @param password      User's password
+     * @param isServiceAuth true if authentication is for a service call
+     * @return true if the user is authenticated
+     * @throws org.ofbiz.common.authentication.api.AuthenticatorException
+     *          when a fatal error occurs during authentication
+     */
+    @Override
+    public boolean authenticate(String username, String password, boolean isServiceAuth) throws AuthenticatorException {
+        Debug.logInfo(this.getClass().getName() + " Authenticator authenticate() -- returning false", module);
+        return true;
+    }
+
+    /**
+     * Flag to test if this Authenticator is enabled
+     *
+     * @return true if the Authenticator is enabled
+     */
+    @Override
+    public boolean isEnabled() {
+        return false;
+    }
+}