/* * Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. * * Licensed 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.jboss.errai.security.test.page.client.local; import java.util.HashSet; import java.util.Set; import org.jboss.errai.common.client.api.extension.InitVotes; import org.jboss.errai.enterprise.client.cdi.AbstractErraiCDITest; import org.jboss.errai.ioc.client.IOCUtil; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.security.client.local.TestLoginPage; import org.jboss.errai.security.client.local.TestPage; import org.jboss.errai.security.client.local.TestSecurityErrorPage; import org.jboss.errai.security.client.local.UnsecuredPageWithState; import org.jboss.errai.security.client.local.api.SecurityContext; import org.jboss.errai.security.client.local.spi.ActiveUserCache; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.jboss.errai.security.test.page.client.res.RequireAuthenticationPage; import org.jboss.errai.security.test.page.client.res.RequiresProvidedRolesPage; import org.jboss.errai.security.test.page.client.res.RequiresRoleBasedPage; import org.jboss.errai.ui.nav.client.local.DefaultPage; import org.jboss.errai.ui.nav.client.local.Navigation; import com.google.common.collect.ImmutableMultimap; import com.google.gwt.user.client.Timer; public class SecureNavigationIntegrationTest extends AbstractErraiCDITest { private SyncBeanManager bm; private ActiveUserCache activeUserCache; private Navigation navigation; private SecurityContext securityContext; @Override public String getModuleName() { return "org.jboss.errai.security.test.page.PageTest"; } @Override protected void gwtSetUp() throws Exception { disableBus = true; super.gwtSetUp(); bm = IOC.getBeanManager(); activeUserCache = bm.lookupBean(ActiveUserCache.class).getInstance(); securityContext = bm.lookupBean(SecurityContext.class).getInstance(); navigation = bm.lookupBean(Navigation.class).getInstance(); activeUserCache.setUser(User.ANONYMOUS); InitVotes.registerOneTimeInitCallback(new Runnable() { @Override public void run() { bm.lookupBean(Navigation.class).getInstance().goToWithRole(DefaultPage.class); } }); } @Override protected void gwtTearDown() throws Exception { bm = null; super.gwtTearDown(); } public void testRequireAuthenticationNotLoggedIn() throws Exception { runNavTest(new Runnable() { @Override public void run() { // Precondition assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo("RequireAuthenticationPage"); assertEquals(TestLoginPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } public void testRequireAuthenticationLoggedIn() throws Exception { runNavTest(new Runnable() { @Override public void run() { final User user = new UserImpl("testuser"); // Cache a logged in user. activeUserCache.setUser(user); // Precondition assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo("RequireAuthenticationPage"); assertEquals(RequireAuthenticationPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } public void testRequireRoleNotLoggedIn() throws Exception { runNavTest(new Runnable() { @Override public void run() { // Precondition assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo("RequiresRoleBasedPage"); assertEquals(TestLoginPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } public void testRequireRoleUnauthorized() throws Exception { runNavTest(new Runnable() { @Override public void run() { final Set<Role> roles = new HashSet<>(); roles.add(new RoleImpl("user")); final User user = new UserImpl("testuser", roles); // Cache a logged in user. activeUserCache.setUser(user); // Precondition assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo("RequiresRoleBasedPage"); assertEquals(TestSecurityErrorPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } public void testRequireRoleAuthorized() throws Exception { runNavTest(new Runnable() { @Override public void run() { final Set<Role> roles = new HashSet<>(); roles.add(new RoleImpl("user")); roles.add(new RoleImpl("admin")); final User user = new UserImpl("testuser", roles); // Cache a logged in user. activeUserCache.setUser(user); // Precondition assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo("RequiresRoleBasedPage"); assertEquals(RequiresRoleBasedPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } public void testSecurityContextReturnsToDeniedPageAfterLogin() throws Exception { runNavTest(new Runnable() { @Override public void run() { final Set<Role> roles = new HashSet<>(); roles.add(new RoleImpl("user")); final User user = new UserImpl("testuser", roles); // Setup assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo("RequireAuthenticationPage"); assertEquals(TestLoginPage.class, navigation.getCurrentPage().contentType()); // Now login and try to go to the page we were denied from. activeUserCache.setUser(user); securityContext.navigateBackOrHome(); assertEquals(RequireAuthenticationPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } public void testSecurityContextReturnsToDeniedPageWithSamePageStateAfterLogin() throws Exception { runNavTest(new Runnable() { @Override public void run() { final Set<Role> roles = new HashSet<>(); roles.add(new RoleImpl("user")); final User user = new UserImpl("testuser", roles); // Setup assertEquals(TestPage.class, navigation.getCurrentPage().contentType()); navigation.goTo(RequireAuthenticationPage.class, ImmutableMultimap.of("state", "foo")); assertEquals(TestLoginPage.class, navigation.getCurrentPage().contentType()); // Now login and try to go to the page we were denied from. activeUserCache.setUser(user); securityContext.navigateBackOrHome(); assertEquals(RequireAuthenticationPage.class, navigation.getCurrentPage().contentType()); final String state = IOCUtil.getInstance(RequireAuthenticationPage.class).getState(); assertEquals("foo", state); finishTest(); } }); } public void testSecurityContextReturnsToPreviouslyDisplayedPageWithPageStateAfterRedirectToSecurityErrorPage() throws Exception { runNavTest(() -> { navigation.goTo(UnsecuredPageWithState.class, ImmutableMultimap.of("state", "foo")); assertEquals(UnsecuredPageWithState.class, navigation.getCurrentPage().contentType()); assertEquals(ImmutableMultimap.of("state", "foo"), navigation.getCurrentState()); securityContext.redirectToSecurityErrorPage(); securityContext.navigateBackOrHome(); assertEquals(UnsecuredPageWithState.class, navigation.getCurrentPage().contentType()); assertEquals(ImmutableMultimap.of("state", "foo"), navigation.getCurrentState()); finishTest(); }); } public void testSecurityContextReturnsToPreviouslyDisplayedPageWithPageStateAfterRedirectToLoginPage() throws Exception { runNavTest(() -> { navigation.goTo(UnsecuredPageWithState.class, ImmutableMultimap.of("state", "foo")); assertEquals(UnsecuredPageWithState.class, navigation.getCurrentPage().contentType()); assertEquals(ImmutableMultimap.of("state", "foo"), navigation.getCurrentState()); securityContext.redirectToLoginPage(); securityContext.navigateBackOrHome(); assertEquals(UnsecuredPageWithState.class, navigation.getCurrentPage().contentType()); assertEquals(ImmutableMultimap.of("state", "foo"), navigation.getCurrentState()); finishTest(); }); } public void testRolesFromProviderAreRequired() throws Exception { runNavTest(new Runnable() { @Override public void run() { final User user = new UserImpl("testuser"); activeUserCache.setUser(user); navigation.goTo(RequiresProvidedRolesPage.class, ImmutableMultimap.<String, String>of()); assertEquals(TestSecurityErrorPage.class, navigation.getCurrentPage().contentType()); finishTest(); } }); } private void runNavTest(final Runnable runnable) { asyncTest(); InitVotes.registerOneTimeInitCallback(new Runnable() { @Override public void run() { /* * This timer is here so that any failed assertions are thrown somewhere * where the test runner can catch them. */ new Timer() { @Override public void run() { runnable.run(); } }.schedule(100); ; } }); } }