You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by an...@apache.org on 2010/11/30 21:01:39 UTC

svn commit: r1040746 - in /directory/apacheds/branches/antoine: core-annotations/src/main/java/org/apache/directory/server/core/annotations/ core-annotations/src/main/java/org/apache/directory/server/core/factory/ core/src/main/java/org/apache/director...

Author: antoine
Date: Tue Nov 30 20:01:38 2010
New Revision: 1040746

URL: http://svn.apache.org/viewvc?rev=1040746&view=rev
Log:
adding one test for delegating authentication

Added:
    directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateAuthenticator.java
    directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java
Modified:
    directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateDS.java
    directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java
    directory/apacheds/branches/antoine/core/src/main/java/org/apache/directory/server/core/authn/DelegatingAuthenticator.java
    directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java
    directory/apacheds/branches/antoine/test-framework/src/main/java/org/apache/directory/server/core/integ/FrameworkRunner.java

Added: directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateAuthenticator.java?rev=1040746&view=auto
==============================================================================
--- directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateAuthenticator.java (added)
+++ directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateAuthenticator.java Tue Nov 30 20:01:38 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.directory.server.core.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.directory.server.core.authn.AnonymousAuthenticator;
+import org.apache.directory.server.core.authn.Authenticator;
+
+/**
+ * An authenticator creation
+ * a name and a suffix, plus some other characteristics. Here is an example :
+ * <pre>
+ * @CreateAuthenticator(
+ *     type = "org.apache.directory.server.core.authn.StrongAuthenticator"
+ *     )
+ * )
+ * </pre>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target( {ElementType.METHOD, ElementType.TYPE } )
+public @interface CreateAuthenticator
+{
+    /** The authenticator implementation class */
+    Class<? extends Authenticator> type() default AnonymousAuthenticator.class;
+    /** Delegate host, use for testing DelegatingAuthenticator */
+    String delegateHost();
+    /** Delegate port, use for testing DelegatingAuthenticator */
+    int delegatePort();
+    
+}

Modified: directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateDS.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateDS.java?rev=1040746&r1=1040745&r2=1040746&view=diff
==============================================================================
--- directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateDS.java (original)
+++ directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/annotations/CreateDS.java Tue Nov 30 20:01:38 2010
@@ -54,4 +54,7 @@ public @interface CreateDS
     
     /** additional interceptors */
     Class<?>[] additionalInterceptors() default {};
+    
+    /** additional authenticators */
+    CreateAuthenticator[] additionalAuthenticators() default {};
 }

Modified: directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java?rev=1040746&r1=1040745&r2=1040746&view=diff
==============================================================================
--- directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java (original)
+++ directory/apacheds/branches/antoine/core-annotations/src/main/java/org/apache/directory/server/core/factory/DSAnnotationProcessor.java Tue Nov 30 20:01:38 2010
@@ -24,14 +24,19 @@ import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.lang.reflect.Method;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.directory.server.core.DirectoryService;
 import org.apache.directory.server.core.annotations.ApplyLdifFiles;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.annotations.ContextEntry;
+import org.apache.directory.server.core.annotations.CreateAuthenticator;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.annotations.CreateIndex;
 import org.apache.directory.server.core.annotations.CreatePartition;
+import org.apache.directory.server.core.authn.AuthenticationInterceptor;
+import org.apache.directory.server.core.authn.Authenticator;
+import org.apache.directory.server.core.authn.DelegatingAuthenticator;
 import org.apache.directory.server.core.interceptor.Interceptor;
 import org.apache.directory.server.core.partition.Partition;
 import org.apache.directory.server.core.partition.impl.btree.BTreePartition;
@@ -49,23 +54,27 @@ import org.slf4j.LoggerFactory;
 
 /**
  * A Helper class used to create a DS from the annotations
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory
+ *         Project</a>
  */
 public class DSAnnotationProcessor
 {
     /** A logger for this class */
-    private static final Logger LOG = LoggerFactory.getLogger( DSAnnotationProcessor.class );
+    private static final Logger LOG = LoggerFactory
+            .getLogger( DSAnnotationProcessor.class );
 
 
     /**
      * Create the DirectoryService
      */
-    private static DirectoryService createDS( CreateDS dsBuilder ) throws Exception
+    private static DirectoryService createDS( CreateDS dsBuilder )
+            throws Exception
     {
         LOG.debug( "Starting DS {}...", dsBuilder.name() );
         Class<?> factory = dsBuilder.factory();
-        DirectoryServiceFactory dsf = ( DirectoryServiceFactory ) factory.newInstance();
+        DirectoryServiceFactory dsf = ( DirectoryServiceFactory ) factory
+                .newInstance();
 
         DirectoryService service = dsf.getDirectoryService();
         service.setAccessControlEnabled( dsBuilder.enableAccessControl() );
@@ -78,6 +87,38 @@ public class DSAnnotationProcessor
             interceptorList.add( ( Interceptor ) interceptorClass.newInstance() );
         }
 
+        if ( dsBuilder.additionalAuthenticators().length != 0 )
+        {
+            AuthenticationInterceptor authenticationInterceptor = null;
+            for ( Interceptor interceptor : interceptorList )
+            {
+                if ( interceptor instanceof AuthenticationInterceptor )
+                {
+                    authenticationInterceptor = ( AuthenticationInterceptor ) interceptor;
+                    break;
+                }
+            }
+            if ( authenticationInterceptor == null )
+            {
+                throw new IllegalStateException(
+                        "authentication interceptor not found" );
+            }
+            Set<Authenticator> authenticators = authenticationInterceptor
+                    .getAuthenticators();
+            for ( CreateAuthenticator createAuthenticator : dsBuilder
+                    .additionalAuthenticators() )
+            {
+                Authenticator auth = createAuthenticator.type().newInstance();
+                if ( auth instanceof DelegatingAuthenticator )
+                {
+                    DelegatingAuthenticator dauth = ( DelegatingAuthenticator ) auth;
+                    dauth.setDelegateHost( createAuthenticator.delegateHost() );
+                    dauth.setDelegatePort( createAuthenticator.delegatePort() );
+                }
+                authenticators.add( auth );
+            }
+        }
+
         service.setInterceptors( interceptorList );
 
         dsf.init( dsBuilder.name() );
@@ -91,20 +132,25 @@ public class DSAnnotationProcessor
             if ( createPartition.type() == Partition.class )
             {
                 // The annotation does not specify a specific partition type.
-                // We use the partition factory to create partition and index instances.
+                // We use the partition factory to create partition and index
+                // instances.
                 PartitionFactory partitionFactory = dsf.getPartitionFactory();
-                partition = partitionFactory.createPartition( createPartition.name(), createPartition.suffix(),
-                    createPartition.cacheSize(), new File( service.getInstanceLayout().getPartitionsDirectory(), createPartition.name() ) );
+                partition = partitionFactory.createPartition( createPartition
+                        .name(), createPartition.suffix(), createPartition
+                        .cacheSize(), new File( service.getInstanceLayout()
+                        .getPartitionsDirectory(), createPartition.name() ) );
 
                 CreateIndex[] indexes = createPartition.indexes();
                 for ( CreateIndex createIndex : indexes )
                 {
-                    partitionFactory.addIndex( partition, createIndex.attribute(), createIndex.cacheSize() );
+                    partitionFactory.addIndex( partition,
+                            createIndex.attribute(), createIndex.cacheSize() );
                 }
             }
             else
             {
-                // The annotation contains a specific partition type, we use that type.
+                // The annotation contains a specific partition type, we use
+                // that type.
                 partition = createPartition.type().newInstance();
                 partition.setId( createPartition.name() );
                 partition.setSuffix( new DN( createPartition.suffix() ) );
@@ -113,18 +159,21 @@ public class DSAnnotationProcessor
                 {
                     BTreePartition<?> btreePartition = ( BTreePartition<?> ) partition;
                     btreePartition.setCacheSize( createPartition.cacheSize() );
-                    btreePartition.setPartitionDir( new File( service.getInstanceLayout().getPartitionsDirectory(), createPartition.name() ) );
+                    btreePartition.setPartitionDir( new File( service
+                            .getInstanceLayout().getPartitionsDirectory(),
+                            createPartition.name() ) );
 
                     // Process the indexes if any
                     CreateIndex[] indexes = createPartition.indexes();
 
                     for ( CreateIndex createIndex : indexes )
                     {
-                        // The annotation does not specify a specific index type.
+                        // The annotation does not specify a specific index
+                        // type.
                         // We use the generic index implementation.
                         JdbmIndex index = new JdbmIndex();
                         index.setAttributeId( createIndex.attribute() );
-                        
+
                         btreePartition.addIndexedAttributes( index );
                     }
                 }
@@ -150,11 +199,14 @@ public class DSAnnotationProcessor
 
     /**
      * Create a DirectoryService from a Unit test annotation
-     *
-     * @param description The annotations containing the info from which we will create the DS
+     * 
+     * @param description
+     *            The annotations containing the info from which we will create
+     *            the DS
      * @return A valid DS
      */
-    public static DirectoryService getDirectoryService( Description description ) throws Exception
+    public static DirectoryService getDirectoryService( Description description )
+            throws Exception
     {
         CreateDS dsBuilder = description.getAnnotation( CreateDS.class );
 
@@ -171,11 +223,11 @@ public class DSAnnotationProcessor
 
 
     /**
-     * Create a DirectoryService from an annotation. The @CreateDS annotation must
-     * be associated with either the method or the encapsulating class. We will first
-     * try to get the annotation from the method, and if there is none, then we try
-     * at the class level. 
-     *
+     * Create a DirectoryService from an annotation. The @CreateDS annotation
+     * must be associated with either the method or the encapsulating class. We
+     * will first try to get the annotation from the method, and if there is
+     * none, then we try at the class level.
+     * 
      * @return A valid DS
      */
     public static DirectoryService getDirectoryService() throws Exception
@@ -185,7 +237,8 @@ public class DSAnnotationProcessor
         // Get the caller by inspecting the stackTrace
         StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
 
-        // In Java5 the 0th stacktrace element is: java.lang.Thread.dumpThreads(Native Method)
+        // In Java5 the 0th stacktrace element is:
+        // java.lang.Thread.dumpThreads(Native Method)
         int index = stackTrace[0].getMethodName().equals( "dumpThreads" ) ? 3 : 2;
 
         // Get the enclosing class
@@ -224,19 +277,25 @@ public class DSAnnotationProcessor
     /**
      * injects an LDIF entry in the given DirectoryService
      * 
-     * @param entry the LdifEntry to be injected
-     * @param service the DirectoryService
+     * @param entry
+     *            the LdifEntry to be injected
+     * @param service
+     *            the DirectoryService
      * @throws Exception
      */
-    private static void injectEntry( LdifEntry entry, DirectoryService service ) throws LdapException
+    private static void injectEntry( LdifEntry entry, DirectoryService service )
+            throws LdapException
     {
         if ( entry.isChangeAdd() || entry.isLdifContent() )
         {
-            service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), entry.getEntry() ) );
+            service.getAdminSession().add(
+                    new DefaultEntry( service.getSchemaManager(), entry
+                            .getEntry() ) );
         }
         else if ( entry.isChangeModify() )
         {
-            service.getAdminSession().modify( entry.getDn(), entry.getModificationItems() );
+            service.getAdminSession().modify( entry.getDn(),
+                    entry.getModificationItems() );
         }
         else
         {
@@ -249,20 +308,25 @@ public class DSAnnotationProcessor
     /**
      * injects the LDIF entries present in a LDIF file
      * 
-     * @param service the DirectoryService 
-     * @param ldifFiles the array of LDIF file names (only )
+     * @param service
+     *            the DirectoryService
+     * @param ldifFiles
+     *            the array of LDIF file names (only )
      * @throws Exception
      */
-    public static void injectLdifFiles( Class<?> clazz, DirectoryService service, String[] ldifFiles ) throws Exception
+    public static void injectLdifFiles( Class<?> clazz,
+            DirectoryService service, String[] ldifFiles ) throws Exception
     {
         if ( ( ldifFiles != null ) && ( ldifFiles.length > 0 ) )
         {
             for ( String ldifFile : ldifFiles )
             {
-                InputStream is = clazz.getClassLoader().getResourceAsStream( ldifFile );
+                InputStream is = clazz.getClassLoader().getResourceAsStream(
+                        ldifFile );
                 if ( is == null )
                 {
-                    throw new FileNotFoundException( "LDIF file '" + ldifFile + "' not found." );
+                    throw new FileNotFoundException( "LDIF file '" + ldifFile
+                            + "' not found." );
                 }
                 else
                 {
@@ -281,14 +345,17 @@ public class DSAnnotationProcessor
 
 
     /**
-     * Inject an ldif String into the server. DN must be relative to the
-     * root.
-     *
-     * @param service the directory service to use 
-     * @param ldif the ldif containing entries to add to the server.
-     * @throws Exception if there is a problem adding the entries from the LDIF
+     * Inject an ldif String into the server. DN must be relative to the root.
+     * 
+     * @param service
+     *            the directory service to use
+     * @param ldif
+     *            the ldif containing entries to add to the server.
+     * @throws Exception
+     *             if there is a problem adding the entries from the LDIF
      */
-    public static void injectEntries( DirectoryService service, String ldif ) throws Exception
+    public static void injectEntries( DirectoryService service, String ldif )
+            throws Exception
     {
         LdifReader reader = new LdifReader();
         List<LdifEntry> entries = reader.parseLdif( ldif );
@@ -306,18 +373,21 @@ public class DSAnnotationProcessor
     /**
      * Apply the LDIF entries to the given service
      */
-    public static void applyLdifs( Description desc, DirectoryService service ) throws Exception
+    public static void applyLdifs( Description desc, DirectoryService service )
+            throws Exception
     {
         if ( desc == null )
         {
             return;
         }
 
-        ApplyLdifFiles applyLdifFiles = desc.getAnnotation( ApplyLdifFiles.class );
+        ApplyLdifFiles applyLdifFiles = desc
+                .getAnnotation( ApplyLdifFiles.class );
 
         if ( applyLdifFiles != null )
         {
-            LOG.debug( "Applying {} to {}", applyLdifFiles.value(), desc.getDisplayName() );
+            LOG.debug( "Applying {} to {}", applyLdifFiles.value(),
+                    desc.getDisplayName() );
             injectLdifFiles( desc.getClass(), service, applyLdifFiles.value() );
         }
 

Modified: directory/apacheds/branches/antoine/core/src/main/java/org/apache/directory/server/core/authn/DelegatingAuthenticator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/core/src/main/java/org/apache/directory/server/core/authn/DelegatingAuthenticator.java?rev=1040746&r1=1040745&r2=1040746&view=diff
==============================================================================
--- directory/apacheds/branches/antoine/core/src/main/java/org/apache/directory/server/core/authn/DelegatingAuthenticator.java (original)
+++ directory/apacheds/branches/antoine/core/src/main/java/org/apache/directory/server/core/authn/DelegatingAuthenticator.java Tue Nov 30 20:01:38 2010
@@ -1,5 +1,25 @@
+/*
+ *   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.directory.server.core.authn;
 
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -17,6 +37,12 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.util.StringTools;
 
+
+/**
+ * Authenticator delegating to another LDAP server.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
 public class DelegatingAuthenticator extends AbstractAuthenticator
 {
     /**
@@ -28,7 +54,8 @@ public class DelegatingAuthenticator ext
         super( AuthenticationLevel.SIMPLE );
     }
 
-    protected DelegatingAuthenticator(AuthenticationLevel type)
+
+    protected DelegatingAuthenticator( AuthenticationLevel type )
     {
         super( type );
     }
@@ -39,55 +66,74 @@ public class DelegatingAuthenticator ext
     private int delegatePort;
     private List<String> dnPatterns = new ArrayList<String>();
 
+
     public String getDelegateHost()
     {
         return delegateHost;
     }
 
+
     public void setDelegateHost( String delegateHost )
     {
         this.delegateHost = delegateHost;
     }
 
+
     public int getDelegatePort()
     {
         return delegatePort;
     }
 
+
     public void setDelegatePort( int delegatePort )
     {
         this.delegatePort = delegatePort;
     }
 
+
     public List<String> getDnPatterns()
     {
         return dnPatterns;
     }
 
+
     public void setDnPatterns( List<String> dnPatterns )
     {
         this.dnPatterns = dnPatterns;
     }
 
+
     public LdapPrincipal authenticate( BindOperationContext bindContext )
             throws Exception
     {
-        LdapPrincipal principal = null; 
+        LdapPrincipal principal = null;
         if ( IS_DEBUG )
         {
             LOG.debug( "Authenticating {}", bindContext.getDn() );
         }
-        LdapConnection ldapConnection = LdapConnectionFactory.getNetworkConnection(delegateHost, delegatePort);
-        try {
-            BindResponse bindResponse = ldapConnection.bind(bindContext.getDn(), StringTools.utf8ToString( bindContext.getCredentials() ));
-            if (bindResponse.getLdapResult().getResultCode() != ResultCodeEnum.SUCCESS) {
+        LdapConnection ldapConnection = LdapConnectionFactory.getNetworkConnection( delegateHost, delegatePort );
+        try
+        {
+            BindResponse bindResponse = ldapConnection.bind( bindContext.getDn(),
+                StringTools.utf8ToString( bindContext.getCredentials() ) );
+            if ( bindResponse.getLdapResult().getResultCode() != ResultCodeEnum.SUCCESS )
+            {
                 String message = I18n.err( I18n.ERR_230, bindContext.getDn().getName() );
                 LOG.info( message );
                 throw new LdapAuthenticationException( message );
             }
-            // Create the new principal before storing it in the cache
-            principal = new LdapPrincipal( bindContext.getDn(), AuthenticationLevel.SIMPLE, bindContext.getCredentials() );
-        } catch (LdapException e) {
+            else
+            {
+                // no need to remain bound to delegate host
+                ldapConnection.unBind();
+            }
+            // Create the new principal
+            principal = new LdapPrincipal( bindContext.getDn(), AuthenticationLevel.SIMPLE,
+                bindContext.getCredentials() );
+
+        }
+        catch ( LdapException e )
+        {
             // Bad password ...
             String message = I18n.err( I18n.ERR_230, bindContext.getDn().getName() );
             LOG.info( message );
@@ -96,9 +142,10 @@ public class DelegatingAuthenticator ext
         return principal;
     }
 
+
     public void checkPwdPolicy( Entry userEntry ) throws LdapException
     {
-        // TODO Auto-generated method stub
+        // no check for delegating authentication
 
     }
 
@@ -111,7 +158,7 @@ public class DelegatingAuthenticator ext
 
     public void invalidateCache( DN bindDn )
     {
-        // TODO Auto-generated method stub
+        // cache is not implemented here
 
     }
 

Added: directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java?rev=1040746&view=auto
==============================================================================
--- directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java (added)
+++ directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/operations/bind/DelegatedAuthIT.java Tue Nov 30 20:01:38 2010
@@ -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.directory.server.operations.bind;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionFactory;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifs;
+import org.apache.directory.server.core.annotations.CreateAuthenticator;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.authn.DelegatingAuthenticator;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.shared.ldap.message.BindResponse;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Tests the server to make sure standard compare operations work properly.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(FrameworkRunner.class)
+@ApplyLdifs(
+    {
+        // Entry # 1
+        "dn: uid=antoine,ou=users,ou=system",
+        "objectClass: uidObject",
+        "objectClass: person",
+        "objectClass: top",
+        "uid: antoine",
+        "cn: Antoine Levy-Lambert",
+        "sn: Levy-Lambert",
+        "userPassword: secret" })
+@CreateDS(allowAnonAccess = true, name = "DelegatedAuthIT-class")
+@CreateLdapServer(
+    transports =
+    {
+        @CreateTransport(protocol = "LDAP", port = 10200)
+    })
+public class DelegatedAuthIT extends AbstractLdapTestUnit
+{
+
+    /**
+     * Test with bindDn which is not even found under any namingContext of the
+     * server.
+     * 
+     * @throws Exception 
+     */
+    @CreateDS(
+        allowAnonAccess = true,
+        name = "DelegatedAuthIT-method",
+        additionalAuthenticators =
+            {
+            @CreateAuthenticator(
+                type = DelegatingAuthenticator.class,
+                delegateHost = "localhost",
+                delegatePort = 10200) })
+    @CreateLdapServer(
+        transports =
+    {
+        @CreateTransport(protocol = "LDAP")
+    })
+    @Test
+    public void testDelegatedAuthentication() throws Exception
+    {
+        assertTrue( service.isStarted() );
+        assertEquals( "DelegatedAuthIT-method", service.getInstanceId() );
+        LdapConnection ldapConnection = LdapConnectionFactory.getNetworkConnection( "localhost", ldapServer.getPort() );
+        BindResponse bindResponse = ldapConnection.bind( "uid=antoine,ou=users,ou=system", "secret" );
+        if ( bindResponse.getLdapResult().getResultCode() != ResultCodeEnum.SUCCESS )
+        {
+            fail( "this authentication should have been successful, got result code : "
+                + bindResponse.getLdapResult().getResultCode() );
+        }
+        ldapConnection.unBind();
+        bindResponse = ldapConnection.bind( "uid=antoine,ou=users,ou=system", "sesame" );
+        if ( bindResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+        {
+            fail( "this authentication should have failed due to wrong password, got result code : "
+                + bindResponse.getLdapResult().getResultCode() );
+        }
+        ldapConnection.unBind();
+        try
+        {
+            bindResponse = ldapConnection.bind( "uid=ivanhoe,ou=users,ou=system", "secret" );
+            if ( bindResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+            {
+                fail( "this authentication should fail, user does not exist, got result code : "
+                    + bindResponse.getLdapResult().getResultCode() );
+            }
+            ldapConnection.unBind();
+        }
+        catch ( Exception exc )
+        {
+            System.out.println( "exception happened" + exc.getMessage() );
+        }
+    }
+
+}

Modified: directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java?rev=1040746&r1=1040745&r2=1040746&view=diff
==============================================================================
--- directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java (original)
+++ directory/apacheds/branches/antoine/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java Tue Nov 30 20:01:38 2010
@@ -32,6 +32,7 @@ import org.apache.directory.server.kerbe
 import org.apache.directory.server.operations.add.AddIT;
 import org.apache.directory.server.operations.add.AddingEntriesWithSpecialCharactersInRDNIT;
 import org.apache.directory.server.operations.bind.BindIT;
+import org.apache.directory.server.operations.bind.DelegatedAuthIT;
 import org.apache.directory.server.operations.bind.MiscBindIT;
 import org.apache.directory.server.operations.bind.SaslBindIT;
 import org.apache.directory.server.operations.bind.SimpleBindIT;
@@ -84,6 +85,7 @@ import org.junit.runners.Suite;
 
         // operations.bind
         BindIT.class,
+        DelegatedAuthIT.class,
         MiscBindIT.class,
         SaslBindIT.class,
         SimpleBindIT.class,

Modified: directory/apacheds/branches/antoine/test-framework/src/main/java/org/apache/directory/server/core/integ/FrameworkRunner.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/antoine/test-framework/src/main/java/org/apache/directory/server/core/integ/FrameworkRunner.java?rev=1040746&r1=1040745&r2=1040746&view=diff
==============================================================================
--- directory/apacheds/branches/antoine/test-framework/src/main/java/org/apache/directory/server/core/integ/FrameworkRunner.java (original)
+++ directory/apacheds/branches/antoine/test-framework/src/main/java/org/apache/directory/server/core/integ/FrameworkRunner.java Tue Nov 30 20:01:38 2010
@@ -182,23 +182,7 @@ public class FrameworkRunner extends Blo
             // then use the DS created above
             if ( classLdapServerBuilder != null )
             {
-                int minPort = 0;
-
-                if ( suite != null )
-                {
-                    LdapServer suiteServer = suite.getLdapServer();
-
-                    if ( suiteServer != null )
-                    {
-                        for ( Transport transport : suiteServer.getTransports() )
-                        {
-                            if ( minPort <= transport.getPort() )
-                            {
-                                minPort = transport.getPort();
-                            }
-                        }
-                    }
-                }
+                int minPort = getMinPort();
 
                 classLdapServer = ServerAnnotationProcessor.createLdapServer( getDescription(), directoryService,
                     minPort + 1 );
@@ -270,12 +254,37 @@ public class FrameworkRunner extends Blo
     }
 
 
+    private int getMinPort()
+    {
+        int minPort = 0;
+
+        if ( suite != null )
+        {
+            LdapServer suiteServer = suite.getLdapServer();
+
+            if ( suiteServer != null )
+            {
+                for ( Transport transport : suiteServer.getTransports() )
+                {
+                    if ( minPort <= transport.getPort() )
+                    {
+                        minPort = transport.getPort();
+                    }
+                }
+            }
+        }
+        return minPort;
+    }
+
+
     /**
      * {@inheritDoc}
      */
     @Override
     protected void runChild( FrameworkMethod method, RunNotifier notifier )
     {
+        /** The LdapServer for this method, if any */
+        LdapServer methodLdapServer = null;
         // Don't run the test if the @Ignored annotation is used
         if ( method.getAnnotation( Ignore.class ) != null )
         {
@@ -295,6 +304,10 @@ public class FrameworkRunner extends Blo
         Description classDescription = getDescription();
         Description methodDescription = describeChild( method );
 
+        // Before running any test, check to see if we must create a class DS
+        // Get the LdapServerBuilder, if any
+        CreateLdapServer methodLdapServerBuilder = methodDescription.getAnnotation( CreateLdapServer.class );
+        //if (meth)
         // Ok, ready to run the test
         try
         {
@@ -352,6 +365,13 @@ public class FrameworkRunner extends Blo
 
                 DSAnnotationProcessor.applyLdifs( methodDescription, directoryService );
             }
+            if ( methodLdapServerBuilder != null )
+            {
+                int minPort = getMinPort();
+
+                methodLdapServer = ServerAnnotationProcessor.createLdapServer( methodDescription, directoryService,
+                    minPort + 1 );
+            }
 
             // At this point, we know which service to use.
             // Inject it into the class
@@ -369,7 +389,13 @@ public class FrameworkRunner extends Blo
             DirectoryService oldLdapServerDirService = null;
             DirectoryService oldKdcServerDirService = null;
             
-            if ( classLdapServer != null )
+            if ( methodLdapServer != null ) {
+                // setting the directoryService is required to inject the correct level DS instance in the class or suite level LdapServer
+                methodLdapServer.setDirectoryService( directoryService );
+                
+                ldapServerField.set( getTestClass().getJavaClass(), methodLdapServer );
+            }    
+            else if ( classLdapServer != null )
             {
                 oldLdapServerDirService = classLdapServer.getDirectoryService();
                 
@@ -392,6 +418,11 @@ public class FrameworkRunner extends Blo
             // Run the test
             super.runChild( method, notifier );
 
+            if ( methodLdapServer != null )
+            {
+                methodLdapServer.stop();
+            }
+
             if ( oldLdapServerDirService != null )
             {
                 classLdapServer.setDirectoryService( oldLdapServerDirService );



Re: svn commit: r1040746 - in /directory/apacheds/branches/antoine: core-annotations/src/main/java/org/apache/directory/server/core/annotations/ core-annotations/src/main/java/org/apache/directory/server/core/factory/ core/src/main/java/org/apache/director...

Posted by Antoine Levy-Lambert <an...@gmx.de>.
Hi,

added unit test. The unit test is using 2 LDAP servers, so I changed the 
FrameworkRunner to be able to deal with a method level LDAP server. One 
thing could be improved, currently the suite level LDAP server has a 
hard coded port number 10200. The delegating authentication setup refers 
to this 10200.

Regards,

Antoine

On 11/30/2010 3:01 PM, antoine@apache.org wrote:
> Author: antoine
> Date: Tue Nov 30 20:01:38 2010
> New Revision: 1040746
>
> URL: http://svn.apache.org/viewvc?rev=1040746&view=rev
> Log:
> adding one test for delegating authentication
>