001    /**
002     *
003     */
004    package org.springframework.richclient.security.support;
005    
006    import junit.framework.TestCase;
007    
008    import org.springframework.context.support.ClassPathXmlApplicationContext;
009    import org.springframework.richclient.application.Application;
010    import org.springframework.richclient.application.ApplicationServicesLocator;
011    import org.springframework.richclient.application.ApplicationWindow;
012    import org.springframework.richclient.application.ApplicationWindowFactory;
013    import org.springframework.richclient.application.config.ApplicationWindowConfigurer;
014    import org.springframework.richclient.application.config.DefaultApplicationLifecycleAdvisor;
015    import org.springframework.richclient.application.support.DefaultApplicationWindow;
016    import org.springframework.richclient.command.ActionCommand;
017    import org.springframework.richclient.command.CommandManager;
018    import org.springframework.richclient.security.ApplicationSecurityManager;
019    import org.springframework.richclient.security.SecurityController;
020    import org.springframework.richclient.security.SecurityControllerManager;
021    import org.springframework.richclient.security.TestAuthenticationManager;
022    import org.springframework.security.Authentication;
023    
024    /**
025     * @author Larry Streepy
026     *
027     */
028    public class DefaultSecurityControllerManagerTests extends TestCase {
029        private ClassPathXmlApplicationContext applicationContext;
030        private TestAuthorizable testAuth1;
031        private SecurityControllerManager manager;
032    
033        /*
034         * @see TestCase#setUp()
035         */
036        protected void setUp() throws Exception {
037            super.setUp();
038            Application.load( null );
039            TestApplicationLifecycleAdvisor ala = new TestApplicationLifecycleAdvisor();
040            ala.setWindowCommandBarDefinitions( "org/springframework/richclient/security/support/test-command-ctx.xml" );
041            Application app = new Application( ala );
042            applicationContext = new ClassPathXmlApplicationContext(
043                "org/springframework/richclient/security/support/test-security-controller-ctx.xml" );
044            app.setApplicationContext(applicationContext);
045    
046            ala.setStartingPageId( "start" );
047            ala.setApplication( app );
048            app.openWindow( "start" );
049    
050            testAuth1 = (TestAuthorizable) applicationContext.getBean( "testAuth1" );
051            manager = (SecurityControllerManager)ApplicationServicesLocator.services().getService(SecurityControllerManager.class);
052    
053            // Prepare the command context
054            ala.createWindowCommandManager();
055        }
056    
057        /**
058         * Test alias registration
059         */
060        public void testRegisterSecurityControllerAlias() {
061            SecurityController controller = new UserRoleSecurityController();
062            manager.registerSecurityControllerAlias( "newAlias", controller );
063    
064            assertEquals( "Should be same controller", controller, manager.getSecurityController( "newAlias" ) );
065        }
066    
067        /**
068         * Test obtaining controllers
069         */
070        public void testGetSecurityController() {
071            SecurityController write = (SecurityController) applicationContext.getBean( "writeController",
072                SecurityController.class );
073            SecurityController admin = (SecurityController) applicationContext.getBean( "adminController",
074                SecurityController.class );
075    
076            // test defaulting to bean id if no alias registered
077            assertEquals( "Should be same controller", write, manager.getSecurityController( "writeController" ) );
078            assertEquals( "Should be same controller", admin, manager.getSecurityController( "adminController" ) );
079    
080            // Test registered alias
081            assertEquals( "Should be same controller", admin, manager.getSecurityController( "adminAlias" ) );
082        }
083    
084        /**
085         * Test the processing of beans referenced in the app context.
086         */
087        public void testApplicationContext() {
088            ApplicationSecurityManager securityManager = (ApplicationSecurityManager)ApplicationServicesLocator.services().getService(ApplicationSecurityManager.class);
089    
090            int authorizeCount = 1;
091    
092            assertFalse( "Object should not be authorized", testAuth1.isAuthorized() );
093            assertEquals( "Object should be updated", authorizeCount++, testAuth1.getAuthCount() );
094    
095            CommandManager cmgr = Application.instance().getActiveWindow().getCommandManager();
096            ActionCommand cmdWrite = cmgr.getActionCommand( "cmdWrite" );
097            ActionCommand cmdAdmin = cmgr.getActionCommand( "cmdAdmin" );
098            ActionCommand cmdAdminAlias = cmgr.getActionCommand( "cmdAdminAlias" );
099    
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    }