1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.jetspeed.sso;
19  
20  import org.apache.jetspeed.security.SecurityException;
21  import org.apache.jetspeed.security.impl.GroupPrincipalImpl;
22  import org.apache.jetspeed.security.impl.UserPrincipalImpl;
23  import org.apache.jetspeed.security.util.test.AbstractSecurityTestcase;
24  import org.apache.jetspeed.sso.SSOProvider;
25  
26  import junit.framework.Test;
27  import junit.framework.TestSuite;
28  
29  import javax.security.auth.Subject;
30  
31  import java.security.Principal;
32  import java.util.ArrayList;
33  import java.util.Arrays;
34  import java.util.HashSet;
35  import java.util.Iterator;
36  import java.util.List;
37  import java.util.Set;
38  
39  import org.apache.jetspeed.sso.SSOException;
40  import java.lang.Exception;
41  
42  /***
43   * @author   David Le Strat
44   */
45  public class TestSSOComponent extends AbstractSecurityTestcase
46  {
47      /***
48       * test url for this UnitTest
49       */
50      static private String TEST_URL = "http://localhost/jetspeed";
51  
52      static private String TEST_URL2 = "http://192.168.2.63/nagios/cgi-bin/status.cgi?hostgroup=all&style=hostdetail";
53  
54      static private String TEST_USER = "joe";
55  
56      static private String REMOTE_USER = "remoteJS";
57  
58      static private String REMOTE_USER2 = "nagiosadmin";
59  
60      static private String REMOTE_PWD_1 = "remote_1";
61  
62      static private String REMOTE_PWD_2 = "nagiosadmin";
63  
64      static private String TEST_GROUP = "engineers";
65  
66      static private String TEST_GROUP_USER = "jack";
67  
68      /*** The property manager. */
69      private static SSOProvider ssoBroker = null;
70  
71      /***
72       * @see junit.framework.TestCase#setUp()
73       */
74      public void setUp() throws Exception
75      {
76          super.setUp();
77  
78          try
79          {
80              ssoBroker = (SSOProvider) ctx.getBean("ssoProvider");
81          }
82          catch (Exception ex)
83          {
84              ex.printStackTrace();
85              throw new Exception("Exception while setup SSO TEST");
86          }
87      }
88  
89      /***
90       * @see junit.framework.TestCase#tearDown()
91       */
92      public void tearDown() throws Exception
93      {
94          clean();
95          // super.tearDown();
96      }
97  
98      public static Test suite()
99      {
100         // All methods starting with "test" will be executed in the test suite.
101         return new TestSuite(TestSSOComponent.class);
102     }
103 
104     /***
105      * <p>
106      * Test user root.
107      * </p>
108      */
109     public void testSSOGroup() throws Exception
110     {
111         System.out.println("*************************************\n" + "Start Unit Test for SSO Group Support"
112                 + "\n*************************************");
113 
114         // Create a user
115         try
116         {
117             ums.addUser(TEST_GROUP_USER, "password");
118         }
119         catch (SecurityException sex)
120         {
121             // assertTrue("user already exists. exception caught: " + sex, false);
122         }
123 
124         // Create a group
125         try
126         {
127             gms.addGroup(TEST_GROUP);
128             System.out.println("Creating Group " + TEST_GROUP + " and adding User " + TEST_GROUP_USER + " succeeded!.");
129         }
130         catch (SecurityException secex)
131         {
132             System.out.println("Creating Group " + TEST_GROUP + " and adding User " + TEST_GROUP_USER
133                     + " failed. Group might already exist. Continue test...");
134             // secex.printStackTrace();
135             // throw new Exception(secex.getMessage());
136         }
137 
138         if (gms.groupExists(TEST_GROUP))
139         {
140             // Add user to Group
141             gms.addUserToGroup(TEST_GROUP_USER, TEST_GROUP);
142         }
143         else
144         {
145             assertTrue("Could not create group. Abort test.", false);
146         }
147 
148         // Initialization of Group
149         Principal principal = new GroupPrincipalImpl(TEST_GROUP);
150         Set principals = new HashSet();
151         principals.add(principal);
152         Subject subject = new Subject(true, principals, new HashSet(), new HashSet());
153 
154         // Add SSO Credential for Group
155         if (ssoBroker.hasSSOCredentials(subject, TEST_URL) == false)
156         {
157             try
158             {
159                 ssoBroker.addCredentialsForSite(subject, REMOTE_USER, TEST_URL, REMOTE_PWD_1);
160                 System.out.println("SSO Credential added for Group:" + TEST_GROUP + " site: " + TEST_URL);
161             }
162             catch (SSOException ssoex)
163             {
164                 System.out.println("SSO Credential add FAILED for Group:" + TEST_GROUP + " site: " + TEST_URL);
165                 ssoex.printStackTrace();
166                 throw new Exception(ssoex.getMessage());
167             }
168         }
169         else
170         {
171             System.out.println("Group:" + TEST_GROUP + " site: " + TEST_URL + " has already a remote credential");
172         }
173 
174         // Create Principal for User
175         principal = new UserPrincipalImpl(TEST_GROUP_USER);
176         principals = new HashSet();
177         principals.add(principal);
178         subject = new Subject(true, principals, new HashSet(), new HashSet());
179 
180         // User should have credential for site
181         if (ssoBroker.hasSSOCredentials(subject, TEST_URL) == false)
182         {
183             // Group expansion failed. User not recognized
184             System.out.println("No SSO Credential for user:" + TEST_GROUP_USER + " site: " + TEST_URL);
185 
186             // Test failure
187             try
188             {
189                 ums.removeUser(TEST_GROUP_USER);
190                 gms.removeGroup(TEST_GROUP);
191             }
192             catch (SecurityException sex)
193             {
194                 assertTrue("could not remove user and group. exception caught: " + sex, false);
195             }
196 
197             throw new Exception("SSO Unit test for Group support failed");
198         }
199         else
200         {
201             // Group lookup succesful
202             System.out.println("SSO Test for Group support successful" + "\nSSO Credential for user:" + TEST_GROUP_USER
203                     + " site: " + TEST_URL + " found. User is member of Group " + TEST_GROUP);
204         }
205 
206         // Cleanup test.
207 
208         /*
209          * For hypersonic the cascading deletes are not generated by Torque and the remove credentials fails with a
210          * constraint error. Comment test out for M1 release but the problem needs to be addressed for the upcoming
211          * releases
212          */
213         try
214         {
215             // Remove credential for Site
216             ssoBroker.removeCredentialsForSite("/group/" + TEST_GROUP, TEST_URL);
217             System.out.println("SSO Credential removed for Group:" + TEST_GROUP + " site: " + TEST_URL);
218         }
219         catch (SSOException ssoex)
220         {
221             System.out.println("SSO Credential remove FAILED for Group:" + TEST_GROUP + " site: " + TEST_URL);
222             throw new Exception(ssoex.getMessage());
223         }
224 
225         try
226         {
227             ums.removeUser(TEST_GROUP_USER);
228             gms.removeGroup(TEST_GROUP);
229         }
230         catch (SecurityException sex)
231         {
232             assertTrue("could not remove user and group. exception caught: " + sex, false);
233         }
234 
235     }
236 
237     public void testSSO() throws Exception
238     {
239         System.out.println("***************************\nStart Unit Test for SSO API\n***************************");
240 
241         // Create a user
242         try
243         {
244             ums.addUser(TEST_USER, "password");
245         }
246         catch (SecurityException sex)
247         {
248             // assertTrue("user already exists. exception caught: " + sex, false);
249         }
250 
251         // Initialization
252         Principal principal = new UserPrincipalImpl(TEST_USER);
253         Set principals = new HashSet();
254         principals.add(principal);
255         Subject subject = new Subject(true, principals, new HashSet(), new HashSet());
256 
257         if (ssoBroker.hasSSOCredentials(subject, TEST_URL) == false)
258         {
259             System.out.println("No SSO Credential for user:" + TEST_USER + " site: " + TEST_URL);
260 
261             // Add credential
262             try
263             {
264                 ssoBroker.addCredentialsForSite(subject, REMOTE_USER, TEST_URL, REMOTE_PWD_1);
265                 System.out.println("SSO Credential added for user:" + TEST_USER + " site: " + TEST_URL);
266             }
267             catch (SSOException ssoex)
268             {
269                 System.out.println("SSO Credential add FAILED for user:" + TEST_USER + " site: " + TEST_URL);
270                 ssoex.printStackTrace();
271                 throw new Exception(ssoex.getMessage());
272             }
273         }
274         else
275         {
276             System.out.println("SSO Credential found for user:" + TEST_USER + " site: " + TEST_URL);
277         }
278 
279         // Add another remote principal for the same user
280         if (ssoBroker.hasSSOCredentials(subject, TEST_URL2) == false)
281         {
282             System.out.println("No SSO Credential for user:" + TEST_USER + " site: " + TEST_URL2);
283 
284             // Add credential
285             try
286             {
287                 ssoBroker.addCredentialsForSite(subject, REMOTE_USER2, TEST_URL2, REMOTE_PWD_2);
288                 ssoBroker.setRealmForSite(TEST_URL2, "Nagios Access");
289                 
290                 System.out.println("SSO Credential added for user:" + TEST_USER + " site: " + TEST_URL2);
291             }
292             catch (SSOException ssoex)
293             {
294                 System.out.println("SSO Credential add FAILED for user:" + TEST_USER + " site: " + TEST_URL2);
295                 ssoex.printStackTrace();
296                 throw new Exception(ssoex.getMessage());
297             }
298         }
299         else
300         {
301             System.out.println("SSO Credential found for user:" + TEST_USER + " site: " + TEST_URL2);
302         }
303 
304         // Add the credentail again -- should get an error
305         try
306         {
307             ssoBroker.addCredentialsForSite(subject, REMOTE_USER2, TEST_URL2, REMOTE_PWD_2);
308             throw new Exception("Added same credentail twice -- API should prevent users from doing that.");
309 
310         }
311         catch (SSOException ssoex)
312         {
313             System.out.println("Adding same SSO Credential twice failed (as expected) Message :" + ssoex.getMessage());
314         }
315         catch (Exception e)
316         {
317             throw new Exception("Adding SSO Credential twice throw an unandled exception. Error: " + e.getMessage());
318         }
319 
320         // Test if the credential where persisted
321 
322         // Test credential update
323         SSOContext ssocontext = ssoBroker.getCredentials(subject, TEST_URL);
324         System.out.println("SSO Credential: User:" + ssocontext.getRemotePrincipalName() + " Password: "
325                 + ssocontext.getRemoteCredential() + " for site: " + TEST_URL);
326 
327         System.out.println("SSO Credential: User:" + ssocontext.getRemotePrincipalName() + " Password: "
328                 + ssocontext.getRemoteCredential() + " for site: " + TEST_URL2);
329 
330         try
331         {
332             // Update Remote credential
333             System.out.println("SSO Credential Update");
334             ssoBroker.updateCredentialsForSite(subject, REMOTE_USER, TEST_URL, REMOTE_PWD_2);
335 
336             ssocontext = ssoBroker.getCredentials(subject, TEST_URL);
337             System.out.println("SSO Credential updated: User:" + ssocontext.getRemotePrincipalName() + " Password: "
338                     + ssocontext.getRemoteCredential());
339 
340         }
341         catch (SSOException ssoex)
342         {
343             System.out.println("SSO Credential update FAILED for user:" + TEST_USER + " site: " + TEST_URL);
344             throw new Exception(ssoex.getMessage());
345         }
346           
347         /*
348          * For hypersonic the cascading deletes are not generated by Torque and the remove credentials fails with a
349          * constraint error. Comment test out for M1 release but the problem needs to be addressed for the upcoming
350          * releases try { // Remove credential for Site ssoBroker.removeCredentialsForSite(subject, TEST_URL);
351          * System.out.println("SSO Credential removed for user:" + TEST_USER+ " site: " + TEST_URL); }
352          * catch(SSOException ssoex) { System.out.println("SSO Credential remove FAILED for user:" + TEST_USER+ " site: " +
353          * TEST_URL); throw new Exception(ssoex.getMessage()); }
354          */
355 
356         Iterator sites = ssoBroker.getSites("");
357         while (sites.hasNext())
358         {
359             SSOSite site = (SSOSite) sites.next();
360             System.out.println("Site = " + site.getName());
361         }
362         // Cleanup
363         try
364         {
365         	ssoBroker.removeCredentialsForSite(subject, TEST_URL);
366         	ssoBroker.removeCredentialsForSite(subject, TEST_URL2);
367         	System.out.println("SSO Credential removed for user:" + TEST_USER+ " sites: " + TEST_URL + " " + TEST_URL2); 
368         }
369         catch(SSOException ssoex) 
370         { 
371         	System.out.println("SSO Credential remove FAILED for user:" + TEST_USER+ " site: " + TEST_URL + " and " + TEST_URL2); 
372         	throw new Exception(ssoex.getMessage());
373         }
374 
375     }
376 
377     /***
378      * <p>
379      * Clean properties.
380      * </p>
381      */
382     protected void clean() throws Exception
383     {
384         // Cleanup any credentails added during the test
385         /*
386          * try { } catch (SSOException ex) { System.out.println("SSOException" + ex); }
387          */
388     }
389 
390     protected String[] getConfigurations()
391     {
392         String[] confs = super.getConfigurations();
393         List confList = new ArrayList(Arrays.asList(confs));
394         confList.add("sso.xml");
395         return (String[]) confList.toArray(new String[1]);
396     }
397 }