/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.userdirectory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.opencastproject.util.data.Collections.set;
import static org.opencastproject.util.persistence.PersistenceUtil.newTestEntityManagerFactory;
import org.opencastproject.security.api.Role;
import org.opencastproject.security.api.SecurityConstants;
import org.opencastproject.security.api.SecurityService;
import org.opencastproject.security.api.UnauthorizedException;
import org.opencastproject.security.api.User;
import org.opencastproject.security.impl.jpa.JpaOrganization;
import org.opencastproject.security.impl.jpa.JpaRole;
import org.opencastproject.security.impl.jpa.JpaUser;
import org.opencastproject.util.NotFoundException;
import org.opencastproject.util.PasswordEncoder;
import org.opencastproject.util.data.Collections;
import org.apache.commons.collections.IteratorUtils;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class JpaUserProviderTest {
private JpaUserAndRoleProvider provider = null;
private JpaOrganization org1 = null;
private JpaOrganization org2 = null;
@Before
public void setUp() throws Exception {
org1 = new JpaOrganization("org1", "org1", "localhost", 80, "admin", "anon", null);
org2 = new JpaOrganization("org2", "org2", "127.0.0.1", 80, "admin", "anon", null);
SecurityService securityService = mockSecurityServiceWithUser(
createUserWithRoles(org1, "admin", SecurityConstants.GLOBAL_SYSTEM_ROLES));
JpaGroupRoleProvider groupRoleProvider = EasyMock.createNiceMock(JpaGroupRoleProvider.class);
provider = new JpaUserAndRoleProvider();
provider.setSecurityService(securityService);
provider.setEntityManagerFactory(newTestEntityManagerFactory(JpaUserAndRoleProvider.PERSISTENCE_UNIT));
provider.setGroupRoleProvider(groupRoleProvider);
provider.activate(null);
}
@Test
public void testAddAndGetUser() throws Exception {
JpaUser user = createUserWithRoles(org1, "user1", "ROLE_ASTRO_101_SPRING_2011_STUDENT");
provider.addUser(user);
User loadUser = provider.loadUser("user1");
assertNotNull(loadUser);
assertEquals(user.getUsername(), loadUser.getUsername());
assertEquals(PasswordEncoder.encode(user.getPassword(), user.getUsername()), loadUser.getPassword());
assertEquals(user.getOrganization(), loadUser.getOrganization());
assertEquals(user.getRoles(), loadUser.getRoles());
assertNull("Loading 'does not exist' should return null", provider.loadUser("does not exist"));
assertNull("Loading 'does not exist' should return null", provider.loadUser("user1", org2.getId()));
loadUser = provider.loadUser("user1", org1.getId());
assertNotNull(loadUser);
assertEquals(user.getUsername(), loadUser.getUsername());
assertEquals(PasswordEncoder.encode(user.getPassword(), user.getUsername()), loadUser.getPassword());
assertEquals(user.getOrganization(), loadUser.getOrganization());
assertEquals(user.getRoles(), loadUser.getRoles());
}
@Test
public void testAddAndGetRole() throws Exception {
JpaRole astroRole = new JpaRole("ROLE_ASTRO_105_SPRING_2013_STUDENT", org1, "Astro role");
provider.addRole(astroRole);
Iterator<Role> roles = provider.getRoles();
assertTrue("There should be one role", roles.hasNext());
Role role = roles.next();
assertEquals(astroRole.getName(), role.getName());
assertEquals(astroRole.getOrganization(), role.getOrganization());
assertEquals(astroRole.getDescription(), role.getDescription());
assertFalse("There should onyl be one role", roles.hasNext());
}
@Test
public void testAddUserWithGlobalAdminRole() throws Exception {
JpaUser adminUser = createUserWithRoles(org1, "admin1", SecurityConstants.GLOBAL_ADMIN_ROLE);
provider.addUser(adminUser);
User loadedUser = provider.loadUser(adminUser.getUsername());
assertNotNull("The currently added user isn't loaded as expected", loadedUser);
assertEquals(adminUser.getUsername(), loadedUser.getUsername());
assertEquals(adminUser.getRoles(), loadedUser.getRoles());
}
@Test
public void testAddUserWithOrgAdminRoleAsGlobalAdmin() throws Exception {
JpaUser newUser = createUserWithRoles(org1, "org_admin2", org1.getAdminRole());
provider.addUser(newUser);
User loadedUser = provider.loadUser(newUser.getUsername());
assertNotNull("The currently added user isn't loaded as expected", loadedUser);
assertEquals(newUser.getUsername(), loadedUser.getUsername());
assertEquals(newUser.getRoles(), loadedUser.getRoles());
}
@Test
public void testAddUserWithOrgAdminRoleAsOrgAdmin() throws Exception {
provider.setSecurityService(mockSecurityServiceWithUser(
createUserWithRoles(org1, "org_admin", org1.getAdminRole())));
JpaUser newUser = createUserWithRoles(org1, "org_admin2", org1.getAdminRole());
provider.addUser(newUser);
User loadedUser = provider.loadUser(newUser.getUsername());
assertNotNull("The currently added user isn't loaded as expected", loadedUser);
assertEquals(newUser.getUsername(), loadedUser.getUsername());
assertEquals(newUser.getRoles(), loadedUser.getRoles());
}
@Test(expected = UnauthorizedException.class)
public void testAddUserWithGlobalAdminRoleNotAllowedAsNonAdminUser() throws Exception {
provider.setSecurityService(mockSecurityServiceWithUser(
createUserWithRoles(org1, "user1", "ROLE_USER")));
JpaUser newUser = createUserWithRoles(org1, "admin2", SecurityConstants.GLOBAL_ADMIN_ROLE);
provider.addUser(newUser);
fail("The current user shouldn't able to create an global admin user.");
}
@Test(expected = UnauthorizedException.class)
public void testAddUserWithGlobalAdminRoleNotAllowedAsOrgAdmin() throws Exception {
provider.setSecurityService(mockSecurityServiceWithUser(
createUserWithRoles(org1, "org1_admin", org1.getAdminRole())));
JpaUser newUser = createUserWithRoles(org1, "admin2", SecurityConstants.GLOBAL_ADMIN_ROLE);
provider.addUser(newUser);
fail("The current user shouldn't able to create an global admin user.");
}
@Test(expected = UnauthorizedException.class)
public void testAddUserWithOrgAdminRoleNotAllowedAsNonAdminUser() throws Exception {
provider.setSecurityService(mockSecurityServiceWithUser(
createUserWithRoles(org1, "user1", "ROLE_USER")));
JpaUser newUser = createUserWithRoles(org1, "org_admin2", org1.getAdminRole());
provider.addUser(newUser);
fail("The current user shouldn't able to create an global admin user.");
}
@Test
public void testDeleteUser() throws Exception {
JpaUser user1 = createUserWithRoles(org1, "user1", "ROLE_ASTRO_101_SPRING_2011_STUDENT");
JpaUser user2 = createUserWithRoles(org1, "user2", "ROLE_ASTRO_101_SPRING_2011_STUDENT");
JpaUser user3 = createUserWithRoles(org1, "user3", "ROLE_ASTRO_101_SPRING_2011_STUDENT");
JpaUser user4 = createUserWithRoles(org1, "user4", "ROLE_ASTRO_101_SPRING_2011_STUDENT");
provider.addUser(user1);
provider.addUser(user2);
provider.addUser(user3);
provider.addUser(user4);
User loadUser = provider.loadUser("user1");
assertNotNull(loadUser);
provider.deleteUser("user1", user1.getOrganization().getId());
provider.deleteUser("user2", user1.getOrganization().getId());
provider.deleteUser("user3", user1.getOrganization().getId());
assertNull(provider.loadUser("user1", org1.getId()));
assertNull(provider.loadUser("user2", org1.getId()));
assertNull(provider.loadUser("user3", org1.getId()));
assertNotNull(provider.loadUser("user4", org1.getId()));
try {
provider.deleteUser("user1", user1.getOrganization().getId());
fail("Should throw a NotFoundException");
} catch (NotFoundException e) {
assertTrue("User not found.", true);
}
}
@Test(expected = UnauthorizedException.class)
public void testDeleteUserNotAllowedAsNonAdmin() throws UnauthorizedException, Exception {
JpaUser adminUser = createUserWithRoles(org1, "admin", "ROLE_ADMIN");
JpaUser nonAdminUser = createUserWithRoles(org1, "user1", "ROLE_USER");
try {
provider.addUser(adminUser);
provider.addUser(nonAdminUser);
} catch (UnauthorizedException ex) {
fail("The user shuld be created");
}
provider.setSecurityService(mockSecurityServiceWithUser(nonAdminUser));
provider.deleteUser(adminUser.getUsername(), org1.getId());
fail("An non admin user may not delete an admin user");
}
@Test
public void testUpdateUser() throws Exception {
Set<JpaRole> authorities = new HashSet<JpaRole>();
authorities.add(new JpaRole("ROLE_ASTRO_101_SPRING_2011_STUDENT", org1));
JpaUser user = new JpaUser("user1", "pass1", org1, provider.getName(), true, authorities);
provider.addUser(user);
User loadUser = provider.loadUser("user1");
assertNotNull(loadUser);
authorities.add(new JpaRole("ROLE_ASTRO_101_SPRING_2013_STUDENT", org1));
String newPassword = "newPassword";
JpaUser updateUser = new JpaUser(user.getUsername(), newPassword, org1, provider.getName(), true, authorities);
User loadUpdatedUser = provider.updateUser(updateUser);
// User loadUpdatedUser = provider.loadUser(user.getUsername());
assertNotNull(loadUpdatedUser);
assertEquals(user.getUsername(), loadUpdatedUser.getUsername());
assertEquals(PasswordEncoder.encode(newPassword, user.getUsername()), loadUpdatedUser.getPassword());
assertEquals(authorities.size(), loadUpdatedUser.getRoles().size());
updateUser = new JpaUser("unknown", newPassword, org1, provider.getName(), true, authorities);
try {
provider.updateUser(updateUser);
fail("Should throw a NotFoundException");
} catch (NotFoundException e) {
assertTrue("User not found.", true);
}
}
@Test
public void testUpdateUserForbiddenForNonAdminUsers() throws Exception {
JpaUser adminUser = createUserWithRoles(org1, "admin", SecurityConstants.GLOBAL_ADMIN_ROLE);
JpaUser user = createUserWithRoles(org1, "user", "ROLE_USER");
provider.addUser(adminUser);
provider.addUser(user);
provider.setSecurityService(mockSecurityServiceWithUser(user));
// try to add ROLE_USER
Set<JpaRole> updatedRoles = Collections.set(
new JpaRole("ROLE_USER", org1),
new JpaRole(SecurityConstants.GLOBAL_ADMIN_ROLE, org1));
try {
provider.updateUser(new JpaUser(adminUser.getUsername(), adminUser.getPassword(), org1,
adminUser.getName(), true, updatedRoles));
fail("The current user may not edit an admin user");
} catch (UnauthorizedException e) {
// pass
}
// try to remove ROLE_ADMIN
updatedRoles = Collections.set(new JpaRole("ROLE_USER", org1));
try {
provider.updateUser(new JpaUser(adminUser.getUsername(), adminUser.getPassword(), org1,
adminUser.getName(), true, updatedRoles));
fail("The current user may not remove the admin role on other user");
} catch (UnauthorizedException e) {
// pass
}
}
@Test
public void testRoles() throws Exception {
JpaUser userOne = createUserWithRoles(org1, "user1", "ROLE_ONE");
provider.addUser(userOne);
Set<JpaRole> authoritiesTwo = new HashSet<JpaRole>();
authoritiesTwo.add(new JpaRole("ROLE_ONE", org1));
authoritiesTwo.add(new JpaRole("ROLE_TWO", org1));
JpaUser userTwo = createUserWithRoles(org1, "user2", "ROLE_ONE", "ROLE_TWO");
provider.addUser(userTwo);
assertEquals("There should be two roles", 2, IteratorUtils.toList(provider.getRoles()).size());
}
@Test
public void testUsers() throws Exception {
Set<JpaRole> authorities = new HashSet<JpaRole>();
authorities.add(new JpaRole("ROLE_COOL_ONE", org1));
JpaUser userOne = createUserWithRoles(org1, "user_test_1", "ROLE_COOL_ONE");
JpaUser userTwo = createUserWithRoles(org1, "user2", "ROLE_CCOL_ONE");
JpaUser userThree = createUserWithRoles(org1, "user3", "ROLE_COOL_ONE");
JpaUser userFour = createUserWithRoles(org1, "user_test_4", "ROLE_COOL_ONE");
provider.addUser(userOne);
provider.addUser(userTwo);
provider.addUser(userThree);
provider.addUser(userFour);
assertEquals("There should be two roles", 4, IteratorUtils.toList(provider.getUsers()).size());
}
@Test
public void testDuplicateUser() {
Set<JpaRole> authorities1 = set(new JpaRole("ROLE_COOL_ONE", org1));
Set<JpaRole> authorities2 = set(new JpaRole("ROLE_COOL_ONE", org2));
try {
provider.addUser(createUserWithRoles(org1, "user1", "ROLE_COOL_ONE"));
provider.addUser(createUserWithRoles(org1, "user2", "ROLE_COOL_ONE"));
provider.addUser(createUserWithRoles(org2, "user1", "ROLE_COOL_ONE"));
} catch (UnauthorizedException e) {
fail("User should be created");
}
try {
provider.addUser(createUserWithRoles(org1, "user1", "ROLE_COOL_ONE"));
fail("Duplicate user");
} catch (Exception ignore) {
}
}
@Test
public void testRolesForUser() {
JpaRole astroRole = new JpaRole("ROLE_ASTRO_105_SPRING_2013_STUDENT", org1, "Astro role");
provider.addRole(astroRole);
JpaUser userOne = createUserWithRoles(org1, "user1", "ROLE_ONE", "ROLE_TWO");
try {
provider.addUser(userOne);
} catch (UnauthorizedException e) {
fail("User should be created");
}
assertEquals("There should be three roles", 3, IteratorUtils.toList(provider.getRoles()).size());
List<Role> rolesForUser = provider.getRolesForUser("user1");
assertEquals("There should be two roles", 2, rolesForUser.size());
assertEquals("ROLE_ONE", rolesForUser.get(0).getName());
assertEquals("ROLE_TWO", rolesForUser.get(1).getName());
}
@Test
public void testFindUsers() throws UnauthorizedException {
JpaUser userOne = createUserWithRoles(org1, "user_test_1", "ROLE_COOL_ONE");
JpaUser userTwo = createUserWithRoles(org1, "user2", "ROLE_COOL_ONE");
JpaUser userThree = createUserWithRoles(org1, "user3", "ROLE_COOL_ONE");
JpaUser userFour = createUserWithRoles(org1, "user_test_4", "ROLE_COOL_ONE");
provider.addUser(userOne);
provider.addUser(userTwo);
provider.addUser(userThree);
provider.addUser(userFour);
assertEquals(2, IteratorUtils.toList(provider.findUsers("%tEsT%", 0, 0)).size());
assertEquals(1, IteratorUtils.toList(provider.findUsers("%tEsT%", 0, 1)).size());
User user = provider.findUsers("%tEsT%", 1, 1).next();
assertEquals(userFour, user);
}
@Test
public void testFindRoles() throws UnauthorizedException {
JpaRole astroRole = new JpaRole("ROLE_ASTRO_105_SPRING_2013_STUDENT", org1, "Astro role");
provider.addRole(astroRole);
JpaUser userOne = createUserWithRoles(org1, "user1", "ROLE_COOL_ONE", "ROLE_COOL_TWO");
provider.addUser(userOne);
// We expect findRoles() for this provider to return an empty set,
// as it is not authoritative for roles that it persists.
assertEquals(0, IteratorUtils.toList(provider.findRoles("%coOL%", Role.Target.ALL, 0, 0)).size());
assertEquals(0, IteratorUtils.toList(provider.findRoles("%cOoL%", Role.Target.ALL, 0, 1)).size());
assertEquals(0, IteratorUtils.toList(provider.findRoles("%oLe%", Role.Target.ALL, 0, 0)).size());
assertEquals(0, IteratorUtils.toList(provider.findRoles("%olE%", Role.Target.ALL, 1, 2)).size());
}
private static SecurityService mockSecurityServiceWithUser(User currentUser) {
// Set the security sevice
SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
EasyMock.expect(securityService.getOrganization()).andReturn(currentUser.getOrganization()).anyTimes();
EasyMock.expect(securityService.getUser()).andReturn(currentUser).anyTimes();
EasyMock.replay(securityService);
return securityService;
}
private static JpaUser createUserWithRoles(JpaOrganization org, String username, String... roles) {
Set<JpaRole> userRoles = new HashSet<>();
for (String adminRole : roles) {
userRoles.add(new JpaRole(adminRole, org));
}
return new JpaUser(username, "pass1", org, "opencast", true, userRoles);
}
}