1   /**
2    *
3    */
4   package org.springframework.richclient.security.support;
5   
6   import junit.framework.TestCase;
7   
8   import org.springframework.context.support.ClassPathXmlApplicationContext;
9   import org.springframework.richclient.application.Application;
10  import org.springframework.richclient.application.ApplicationServicesLocator;
11  import org.springframework.richclient.application.ApplicationWindow;
12  import org.springframework.richclient.application.ApplicationWindowFactory;
13  import org.springframework.richclient.application.config.ApplicationWindowConfigurer;
14  import org.springframework.richclient.application.config.DefaultApplicationLifecycleAdvisor;
15  import org.springframework.richclient.application.support.DefaultApplicationWindow;
16  import org.springframework.richclient.command.ActionCommand;
17  import org.springframework.richclient.command.CommandManager;
18  import org.springframework.richclient.security.ApplicationSecurityManager;
19  import org.springframework.richclient.security.SecurityController;
20  import org.springframework.richclient.security.SecurityControllerManager;
21  import org.springframework.richclient.security.TestAuthenticationManager;
22  import org.springframework.security.Authentication;
23  
24  /**
25   * @author Larry Streepy
26   *
27   */
28  public class DefaultSecurityControllerManagerTests extends TestCase {
29      private ClassPathXmlApplicationContext applicationContext;
30      private TestAuthorizable testAuth1;
31      private SecurityControllerManager manager;
32  
33      /*
34       * @see TestCase#setUp()
35       */
36      protected void setUp() throws Exception {
37          super.setUp();
38          Application.load( null );
39          TestApplicationLifecycleAdvisor ala = new TestApplicationLifecycleAdvisor();
40          ala.setWindowCommandBarDefinitions( "org/springframework/richclient/security/support/test-command-ctx.xml" );
41          Application app = new Application( ala );
42          applicationContext = new ClassPathXmlApplicationContext(
43              "org/springframework/richclient/security/support/test-security-controller-ctx.xml" );
44          app.setApplicationContext(applicationContext);
45  
46          ala.setStartingPageId( "start" );
47          ala.setApplication( app );
48          app.openWindow( "start" );
49  
50          testAuth1 = (TestAuthorizable) applicationContext.getBean( "testAuth1" );
51          manager = (SecurityControllerManager)ApplicationServicesLocator.services().getService(SecurityControllerManager.class);
52  
53          // Prepare the command context
54          ala.createWindowCommandManager();
55      }
56  
57      /**
58       * Test alias registration
59       */
60      public void testRegisterSecurityControllerAlias() {
61          SecurityController controller = new UserRoleSecurityController();
62          manager.registerSecurityControllerAlias( "newAlias", controller );
63  
64          assertEquals( "Should be same controller", controller, manager.getSecurityController( "newAlias" ) );
65      }
66  
67      /**
68       * Test obtaining controllers
69       */
70      public void testGetSecurityController() {
71          SecurityController write = (SecurityController) applicationContext.getBean( "writeController",
72              SecurityController.class );
73          SecurityController admin = (SecurityController) applicationContext.getBean( "adminController",
74              SecurityController.class );
75  
76          // test defaulting to bean id if no alias registered
77          assertEquals( "Should be same controller", write, manager.getSecurityController( "writeController" ) );
78          assertEquals( "Should be same controller", admin, manager.getSecurityController( "adminController" ) );
79  
80          // Test registered alias
81          assertEquals( "Should be same controller", admin, manager.getSecurityController( "adminAlias" ) );
82      }
83  
84      /**
85       * Test the processing of beans referenced in the app context.
86       */
87      public void testApplicationContext() {
88          ApplicationSecurityManager securityManager = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
89  
90          int authorizeCount = 1;
91  
92          assertFalse( "Object should not be authorized", testAuth1.isAuthorized() );
93          assertEquals( "Object should be updated", authorizeCount++, testAuth1.getAuthCount() );
94  
95          CommandManager cmgr = Application.instance().getActiveWindow().getCommandManager();
96          ActionCommand cmdWrite = cmgr.getActionCommand( "cmdWrite" );
97          ActionCommand cmdAdmin = cmgr.getActionCommand( "cmdAdmin" );
98          ActionCommand cmdAdminAlias = cmgr.getActionCommand( "cmdAdminAlias" );
99  
100         assertFalse( "Object should not be authorized", cmdWrite.isAuthorized() );
101         assertFalse( "Object should not be authorized", cmdAdmin.isAuthorized() );
102         assertFalse( "Object should not be authorized", cmdAdminAlias.isAuthorized() );
103 
104         // Now login with ROLE_WRITE
105         Authentication auth = TestAuthenticationManager.makeAuthentication( "test", "test", "ROLE_WRITE" );
106         securityManager.doLogin( auth );
107 
108         assertTrue( "Object should be authorized", cmdWrite.isAuthorized() );
109         assertFalse( "Object should not be authorized", cmdAdmin.isAuthorized() );
110         assertFalse( "Object should not be authorized", cmdAdminAlias.isAuthorized() );
111         assertFalse( "Object should not be authorized", testAuth1.isAuthorized() );
112         assertEquals( "Object should be updated", authorizeCount++, testAuth1.getAuthCount() );
113 
114         // Now login with ROLE_ADMIN
115         auth = TestAuthenticationManager.makeAuthentication( "test", "test", "ROLE_ADMIN" );
116         securityManager.doLogin( auth );
117 
118         assertTrue( "Object should be authorized", cmdWrite.isAuthorized() );
119         assertTrue( "Object should be authorized", cmdAdmin.isAuthorized() );
120         assertTrue( "Object should be authorized", cmdAdminAlias.isAuthorized() );
121         assertTrue( "Object should be authorized", testAuth1.isAuthorized() );
122         assertEquals( "Object should be updated", authorizeCount++, testAuth1.getAuthCount() );
123     }
124 
125     /**
126      * Test that the authorized state overrides the enabled state
127      */
128     public void testAuthorizedOverridesEnabled() {
129         ApplicationSecurityManager securityManager = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
130         CommandManager cmgr = Application.instance().getActiveWindow().getCommandManager();
131         ActionCommand cmdWrite = cmgr.getActionCommand( "cmdWrite" );
132 
133         // We start with no authentication, so nothing should be authorized
134         assertFalse( "Object should not be authorized", cmdWrite.isAuthorized() );
135         assertFalse( "Object should not be enabled", cmdWrite.isEnabled() );
136 
137         // Try to enable them, should not happen
138         cmdWrite.setEnabled( true );
139         assertFalse( "Object should not be enabled", cmdWrite.isEnabled() );
140 
141         // Now authorize it
142         Authentication auth = TestAuthenticationManager.makeAuthentication( "test", "test", "ROLE_WRITE" );
143         securityManager.doLogin( auth );
144 
145         assertTrue( "Object should be authorized", cmdWrite.isAuthorized() );
146         assertTrue( "Object should be enabled", cmdWrite.isEnabled() );
147 
148         // Now we should be able to disable and re-enabled it
149         cmdWrite.setEnabled( false );
150         assertFalse( "Object should not be enabled", cmdWrite.isEnabled() );
151         cmdWrite.setEnabled( true );
152         assertTrue( "Object should be enabled", cmdWrite.isEnabled() );
153 
154         // Now leave it disabled, remove the authorization, re-authorize and it
155         // should still be disabled
156         cmdWrite.setEnabled( false );
157         assertFalse( "Object should not be enabled", cmdWrite.isEnabled() );
158         securityManager.doLogout();
159 
160         assertFalse( "Object should not be authorized", cmdWrite.isAuthorized() );
161         assertFalse( "Object should not be enabled", cmdWrite.isEnabled() );
162 
163         securityManager.doLogin( auth );
164 
165         assertTrue( "Object should be authorized", cmdWrite.isAuthorized() );
166         assertFalse( "Object should not be enabled", cmdWrite.isEnabled() );
167     }
168 
169     public static class TestApplicationWindowFactory implements ApplicationWindowFactory {
170         public ApplicationWindow createApplicationWindow() {
171             return new TestApplicationWindow();
172         }
173     }
174 
175     /**
176      * Special ApplicationWindow class for testing.
177      */
178     public static class TestApplicationWindow extends DefaultApplicationWindow {
179 
180         public TestApplicationWindow() {
181             super( 1 );
182         }
183 
184         public void showPage(String pageId) {
185             System.out.println( "showPage: " + pageId );
186         }
187     }
188 
189     public static class TestApplicationLifecycleAdvisor extends DefaultApplicationLifecycleAdvisor {
190 
191     	public TestApplicationLifecycleAdvisor() {
192     		setWindowCommandManagerBeanName("windowCommandManager");
193     	}
194 
195         public void onPreWindowOpen(ApplicationWindowConfigurer configurer) {
196             // Do nothing
197         }
198     }
199 }