1   /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.ldap;
17  
18  import org.acegisecurity.AcegiMessageSource;
19  import org.acegisecurity.BadCredentialsException;
20  
21  import java.util.Hashtable;
22  
23  import javax.naming.Context;
24  import javax.naming.directory.DirContext;
25  
26  
27  /**
28   * Tests {@link org.acegisecurity.ldap.DefaultInitialDirContextFactory}.
29   *
30   * @author Luke Taylor
31   * @version $Id: DefaultInitialDirContextFactoryTests.java 1496 2006-05-23 13:38:33Z benalex $
32   */
33  public class DefaultInitialDirContextFactoryTests extends AbstractLdapServerTestCase {
34      //~ Instance fields ================================================================================================
35  
36      DefaultInitialDirContextFactory idf;
37  
38      //~ Methods ========================================================================================================
39  
40      public void onSetUp() {
41          idf = getInitialCtxFactory();
42          idf.setMessageSource(new AcegiMessageSource());
43      }
44  
45      public void testAnonymousBindSucceeds() throws Exception {
46          DirContext ctx = idf.newInitialDirContext();
47          // Connection pooling should be set by default for anon users.
48          // Can't rely on this property being there with embedded server
49          // assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
50          ctx.close();
51      }
52  
53      public void testBaseDnIsParsedFromCorrectlyFromUrl() {
54          idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org");
55          assertEquals("dc=acegisecurity,dc=org", idf.getRootDn());
56  
57          // Check with an empty root
58          idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/");
59          assertEquals("", idf.getRootDn());
60  
61          // Empty root without trailing slash
62          idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org");
63          assertEquals("", idf.getRootDn());
64      }
65  
66      public void testBindAsManagerFailsIfNoPasswordSet()
67          throws Exception {
68          idf.setManagerDn(MANAGER_USER);
69  
70          DirContext ctx = null;
71  
72          try {
73              ctx = idf.newInitialDirContext();
74              fail("Binding with no manager password should fail.");
75  
76  // Can't rely on this property being there with embedded server
77  //        assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
78          } catch (BadCredentialsException expected) {}
79  
80          LdapUtils.closeContext(ctx);
81      }
82  
83      public void testBindAsManagerSucceeds() throws Exception {
84          idf.setManagerPassword(MANAGER_PASSWORD);
85          idf.setManagerDn(MANAGER_USER);
86  
87          DirContext ctx = idf.newInitialDirContext();
88  // Can't rely on this property being there with embedded server
89  //        assertEquals("true",ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
90          ctx.close();
91      }
92  
93      public void testConnectionAsSpecificUserSucceeds()
94          throws Exception {
95          DirContext ctx = idf.newInitialDirContext("uid=Bob,ou=people,dc=acegisecurity,dc=org", "bobspassword");
96          // We don't want pooling for specific users.
97          // assertNull(ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool"));
98  //        com.sun.jndi.ldap.LdapPoolManager.showStats(System.out);
99          ctx.close();
100     }
101 
102     public void testConnectionFailure() throws Exception {
103         // Use the wrong port
104         idf = new DefaultInitialDirContextFactory("ldap://localhost:60389");
105         idf.setInitialContextFactory("com.sun.jndi.ldap.LdapCtxFactory");
106 
107         Hashtable env = new Hashtable();
108         env.put("com.sun.jndi.ldap.connect.timeout", "200");
109         idf.setExtraEnvVars(env);
110         idf.setUseConnectionPool(false); // coverage purposes only
111 
112         try {
113             idf.newInitialDirContext();
114             fail("Connection succeeded unexpectedly");
115         } catch (LdapDataAccessException expected) {}
116     }
117 
118     public void testEnvironment() {
119         idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/");
120 
121         // check basic env
122         Hashtable env = idf.getEnvironment();
123         //assertEquals("com.sun.jndi.ldap.LdapCtxFactory", env.get(Context.INITIAL_CONTEXT_FACTORY));
124         assertEquals("ldap://acegisecurity.org/", env.get(Context.PROVIDER_URL));
125         assertEquals("simple", env.get(Context.SECURITY_AUTHENTICATION));
126         assertNull(env.get(Context.SECURITY_PRINCIPAL));
127         assertNull(env.get(Context.SECURITY_CREDENTIALS));
128 
129         // Ctx factory.
130         idf.setInitialContextFactory("org.acegisecurity.NonExistentCtxFactory");
131         env = idf.getEnvironment();
132         assertEquals("org.acegisecurity.NonExistentCtxFactory", env.get(Context.INITIAL_CONTEXT_FACTORY));
133 
134         // Auth type
135         idf.setAuthenticationType("myauthtype");
136         env = idf.getEnvironment();
137         assertEquals("myauthtype", env.get(Context.SECURITY_AUTHENTICATION));
138 
139         // Check extra vars
140         Hashtable extraVars = new Hashtable();
141         extraVars.put("extravar", "extravarvalue");
142         idf.setExtraEnvVars(extraVars);
143         env = idf.getEnvironment();
144         assertEquals("extravarvalue", env.get("extravar"));
145     }
146 
147     public void testInvalidPasswordCausesBadCredentialsException()
148         throws Exception {
149         idf.setManagerDn(MANAGER_USER);
150         idf.setManagerPassword("wrongpassword");
151 
152         DirContext ctx = null;
153 
154         try {
155             ctx = idf.newInitialDirContext();
156             fail("Binding with wrong credentials should fail.");
157         } catch (BadCredentialsException expected) {}
158 
159         LdapUtils.closeContext(ctx);
160     }
161 
162     public void testMultipleProviderUrlsAreAccepted() {
163         idf = new DefaultInitialDirContextFactory("ldaps://acegisecurity.org/dc=acegisecurity,dc=org "
164                 + "ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org");
165     }
166 
167     public void testMultipleProviderUrlsWithDifferentRootsAreRejected() {
168         try {
169             idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org "
170                     + "ldap://monkeymachine.co.uk/dc=someotherplace,dc=org");
171             fail("Different root DNs should cause an exception");
172         } catch (IllegalArgumentException expected) {}
173     }
174 
175     public void testSecureLdapUrlIsSupported() {
176         idf = new DefaultInitialDirContextFactory("ldaps://localhost/dc=acegisecurity,dc=org");
177         assertEquals("dc=acegisecurity,dc=org", idf.getRootDn());
178     }
179 
180 //    public void testNonLdapUrlIsRejected() throws Exception {
181 //        DefaultInitialDirContextFactory idf = new DefaultInitialDirContextFactory();
182 //
183 //        idf.setUrl("http://acegisecurity.org/dc=acegisecurity,dc=org");
184 //        idf.setInitialContextFactory(CoreContextFactory.class.getName());
185 //
186 //        try {
187 //            idf.afterPropertiesSet();
188 //            fail("Expected exception for non 'ldap://' URL");
189 //        } catch(IllegalArgumentException expected) {
190 //        }
191 //    }
192     public void testServiceLocationUrlIsSupported() {
193         idf = new DefaultInitialDirContextFactory("ldap:///dc=acegisecurity,dc=org");
194         assertEquals("dc=acegisecurity,dc=org", idf.getRootDn());
195     }
196 }