/* * Copyright 2015 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.uberfire.backend.server.security; import java.security.Principal; import java.security.acl.Group; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import org.jboss.errai.security.shared.api.GroupImpl; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.junit.Assert.*; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.same; import static org.mockito.Mockito.*; import static org.powermock.api.mockito.PowerMockito.mockStatic; @RunWith(PowerMockRunner.class) @PrepareForTest({JAASAuthenticationService.class}) @PowerMockIgnore("javax.security.*") public class JAASAuthenticationServiceTest { private JAASAuthenticationService tested; @Before public void setup() { tested = spy(new JAASAuthenticationService(JAASAuthenticationService.DEFAULT_DOMAIN)); } @Test public void testNoLogin() throws Exception { assertEquals(User.ANONYMOUS, tested.getUser()); } @Test public void testGetAnnonymous() throws Exception { assertFalse(tested.isLoggedIn()); } @Test public void testLogin() throws Exception { String username = "user1"; String password = "password1"; RoleRegistry.get().registerRole("admin"); RoleRegistry.get().registerRole("role1"); Set<Principal> principals = mockPrincipals("admin", "role1", "group1"); Subject subject = new Subject(); subject.getPrincipals().addAll(principals); LoginContext loginContext = mock(LoginContext.class); when(loginContext.getSubject()).thenReturn(subject); doReturn(loginContext).when(tested).createLoginContext(anyString(), anyString()); User user = tested.login(username, password); assertNotNull(user); assertEquals(username, user.getIdentifier()); assertEquals(2, user.getRoles().size()); assertTrue(user.getRoles().contains(new RoleImpl("admin"))); assertTrue(user.getRoles().contains(new RoleImpl("role1"))); assertEquals(1, user.getGroups().size()); assertTrue(user.getGroups().contains(new GroupImpl("group1"))); } @Test public void testLoginSwitchesClassloaderForJsm() throws Exception { mockStatic(JAASAuthenticationService.class); mockStatic(Thread.class); mockStatic(System.class); final ClassLoader tccl = mock(ClassLoader.class); final Thread thread = mock(Thread.class); when(Thread.currentThread()).thenReturn(thread); when(System.getSecurityManager()).thenReturn(mock(SecurityManager.class)); when(thread.getContextClassLoader()).thenReturn(tccl); String username = "user1"; String password = "password1"; Set<Principal> principals = mockPrincipals("admin", "role1", "group1"); Subject subject = new Subject(); subject.getPrincipals().addAll(principals); LoginContext loginContext = mock(LoginContext.class); when(loginContext.getSubject()).thenReturn(subject); doReturn(loginContext).when(tested).createLoginContext(anyString(), anyString()); tested.login(username, password); InOrder inOrder = inOrder(thread); inOrder.verify(thread).setContextClassLoader(tested.getClass().getClassLoader()); inOrder.verify(thread).setContextClassLoader(same(tccl)); } @Test public void testLoginNoPrincipal() throws Exception { String username = "user1"; String password = "password1"; Subject subject = new Subject(); LoginContext loginContext = mock(LoginContext.class); when(loginContext.getSubject()).thenReturn(subject); doReturn(loginContext).when(tested).createLoginContext(anyString(), anyString()); User user = tested.login(username, password); assertNotNull(user); assertEquals(username, user.getIdentifier()); assertEquals(0, user.getRoles().size()); assertEquals(0, user.getGroups().size()); } @Test public void testLoginSubjectGroups() throws Exception { String username = "user1"; String password = "password1"; RoleRegistry.get().registerRole("admin"); RoleRegistry.get().registerRole("role1"); Set<Principal> principals = mockPrincipals("admin", "role1", "group1"); Group aclGroup = mock(Group.class); doReturn(JAASAuthenticationService.DEFAULT_ROLE_PRINCIPLE_NAME).when(aclGroup).getName(); Set<Principal> aclGroups = mockPrincipals("g1", "g2"); Enumeration<? extends Principal> aclGroupsEnum = Collections.enumeration(aclGroups); doReturn(aclGroupsEnum).when(aclGroup).members(); Subject subject = new Subject(); subject.getPrincipals().addAll(principals); subject.getPrincipals().add(aclGroup); LoginContext loginContext = mock(LoginContext.class); when(loginContext.getSubject()).thenReturn(subject); doReturn(loginContext).when(tested).createLoginContext(anyString(), anyString()); User user = tested.login(username, password); assertNotNull(user); assertEquals(username, user.getIdentifier()); assertEquals(2, user.getRoles().size()); assertTrue(user.getRoles().contains(new RoleImpl("admin"))); assertTrue(user.getRoles().contains(new RoleImpl("role1"))); assertEquals(3, user.getGroups().size()); assertTrue(user.getGroups().contains(new GroupImpl("group1"))); assertTrue(user.getGroups().contains(new GroupImpl("g1"))); assertTrue(user.getGroups().contains(new GroupImpl("g2"))); } @Test public void testLoggedIn() throws Exception { String username = "user1"; String password = "password1"; RoleRegistry.get().registerRole("admin"); Set<Principal> principals = mockPrincipals("admin"); Subject subject = new Subject(); subject.getPrincipals().addAll(principals); LoginContext loginContext = mock(LoginContext.class); when(loginContext.getSubject()).thenReturn(subject); doReturn(loginContext).when(tested).createLoginContext(anyString(), anyString()); tested.login(username, password); assertTrue(tested.isLoggedIn()); } @Test public void testGetUser() throws Exception { String username = "user1"; String password = "password1"; RoleRegistry.get().registerRole("admin"); Set<Principal> principals = mockPrincipals("admin"); Subject subject = new Subject(); subject.getPrincipals().addAll(principals); LoginContext loginContext = mock(LoginContext.class); when(loginContext.getSubject()).thenReturn(subject); doReturn(loginContext).when(tested).createLoginContext(anyString(), anyString()); User user = tested.login(username, password); User user1 = tested.getUser(); assertEquals(user, user1); } private Set<Principal> mockPrincipals(String... names) { Set<Principal> principals = new HashSet<Principal>(); for (String name : names) { Principal p1 = mock(Principal.class); when(p1.getName()).thenReturn(name); principals.add(p1); } return principals; } }