/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.security.validation;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.createNiceMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.geoserver.security.validation.RoleServiceException.ADMIN_ROLE_NOT_REMOVABLE_$1;
import static org.geoserver.security.validation.RoleServiceException.ALREADY_EXISTS;
import static org.geoserver.security.validation.RoleServiceException.ALREADY_EXISTS_IN;
import static org.geoserver.security.validation.RoleServiceException.GROUPNAME_NOT_FOUND_$1;
import static org.geoserver.security.validation.RoleServiceException.GROUPNAME_REQUIRED;
import static org.geoserver.security.validation.RoleServiceException.GROUP_ADMIN_ROLE_NOT_REMOVABLE_$1;
import static org.geoserver.security.validation.RoleServiceException.NAME_REQUIRED;
import static org.geoserver.security.validation.RoleServiceException.NOT_FOUND;
import static org.geoserver.security.validation.RoleServiceException.RESERVED_NAME;
import static org.geoserver.security.validation.RoleServiceException.ROLE_IN_USE_$2;
import static org.geoserver.security.validation.RoleServiceException.USERNAME_NOT_FOUND_$1;
import static org.geoserver.security.validation.RoleServiceException.USERNAME_REQUIRED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.Arrays;
import java.util.TreeSet;
import org.geoserver.data.test.MockCreator;
import org.geoserver.data.test.MockTestData;
import org.geoserver.security.GeoServerRoleStore;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.GeoServerUserGroupStore;
import org.geoserver.security.impl.DataAccessRule;
import org.geoserver.security.impl.DataAccessRuleDAO;
import org.geoserver.security.impl.GeoServerRole;
import org.geoserver.security.impl.ServiceAccessRule;
import org.geoserver.security.impl.ServiceAccessRuleDAO;
import org.geoserver.test.GeoServerMockTestSupport;
import org.junit.Test;
//@TestSetup(run=TestSetupFrequency.REPEAT)
public class RoleStoreValidationWrapperTest extends GeoServerMockTestSupport {
protected void assertSecurityException(IOException ex, String id, Object... params) {
assertTrue(ex.getCause() instanceof AbstractSecurityException);
AbstractSecurityException secEx = (AbstractSecurityException) ex.getCause();
assertEquals(id, secEx.getId());
for (int i = 0; i < params.length; i++) {
assertEquals(params[i], secEx.getArgs()[i]);
}
}
@Test
public void testRoleStoreWrapper() throws Exception {
setMockCreator(new MockCreator() {
@Override
public GeoServerSecurityManager createSecurityManager(MockTestData testData) throws Exception {
GeoServerSecurityManager secMgr = createMock(GeoServerSecurityManager.class);
GeoServerRoleStore roleStore1 = createRoleStore("test", secMgr, "role1", "parent1");
addRolesToCreate(roleStore1, "", "duplicated", "xxx");
GeoServerRoleStore roleStore2 = createRoleStore("test1", secMgr, "duplicated");
expect(secMgr.listRoleServices()).andReturn(
new TreeSet<String>(Arrays.asList("test", "test1"))).anyTimes();
replay(roleStore1, roleStore2, secMgr);
return secMgr;
}
});
GeoServerSecurityManager secMgr = getSecurityManager();
GeoServerRoleStore roleStore = (GeoServerRoleStore) secMgr.loadRoleService("test");
RoleStoreValidationWrapper store = new RoleStoreValidationWrapper(roleStore);
try {
store.addRole(store.createRoleObject(""));
fail("empty role name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, NAME_REQUIRED);
}
try {
store.addRole(store.createRoleObject(""));
fail("empty role name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, NAME_REQUIRED);
}
GeoServerRole role1 = store.getRoleByName("role1");
try {
store.addRole(role1);
fail("already existing role name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, ALREADY_EXISTS, "role1");
}
for (GeoServerRole srole : GeoServerRole.SystemRoles) {
try {
store.addRole(store.createRoleObject(srole.getAuthority()));
fail("reserved role name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, RESERVED_NAME, srole.getAuthority());
}
}
GeoServerRoleStore roleStore1 = (GeoServerRoleStore) secMgr.loadRoleService("test1");
RoleStoreValidationWrapper store1 = new RoleStoreValidationWrapper(roleStore1);
try {
store.addRole(store.createRoleObject("duplicated"));
fail("reserved role name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, ALREADY_EXISTS_IN, "duplicated",store1.getName());
}
try {
String authRole = GeoServerRole.AUTHENTICATED_ROLE.getAuthority();
store.addRole(store.createRoleObject(authRole));
fail(authRole + " is reserved and should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, RESERVED_NAME, GeoServerRole.AUTHENTICATED_ROLE.getAuthority());
}
try {
store.updateRole(store.createRoleObject("xxx"));
fail("update role object that does not exist should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, NOT_FOUND, "xxx");
}
try {
store.setParentRole(role1, store.createRoleObject("xxx"));
} catch (IOException ex) {
assertSecurityException(ex, NOT_FOUND, "xxx");
}
try {
store.associateRoleToGroup(role1, "");
fail("empty group name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, GROUPNAME_REQUIRED);
}
try {
store.disAssociateRoleFromGroup(role1, "");
fail("empty group name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, GROUPNAME_REQUIRED);
}
try {
store.associateRoleToUser(role1, "");
fail("empty user name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, USERNAME_REQUIRED);
}
try {
store.disAssociateRoleFromUser(role1, "");
fail("empty user name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, USERNAME_REQUIRED);
}
try {
store.getRolesForUser(null);
fail("null user name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, USERNAME_REQUIRED);
}
try {
store.getRolesForGroup(null);
fail("null group name should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, GROUPNAME_REQUIRED);
}
}
@Test
public void testRoleServiceWrapperAccessRules() throws Exception {
setMockCreator(new MockCreator() {
@Override
public GeoServerSecurityManager createSecurityManager( MockTestData testData) throws Exception {
GeoServerSecurityManager secMgr = createNiceMock(GeoServerSecurityManager.class);
GeoServerRoleStore roleStore = createRoleStore("test", secMgr, "role1", "parent1");
expect(roleStore.removeRole(new GeoServerRole("unused"))).andReturn(true);
DataAccessRule dataAccessRule = createNiceMock(DataAccessRule.class);
expect(dataAccessRule.compareTo(dataAccessRule)).andReturn(0).anyTimes();
expect(dataAccessRule.getKey()).andReturn("foo").anyTimes();
expect(dataAccessRule.getRoles()).andReturn(new TreeSet<String>(Arrays.asList("role1"))).anyTimes();
replay(dataAccessRule);
DataAccessRuleDAO dataAccessDAO = createNiceMock(DataAccessRuleDAO.class);
expect(dataAccessDAO.getRulesAssociatedWithRole("role1")).andReturn(
new TreeSet<DataAccessRule>(Arrays.asList(dataAccessRule))).anyTimes();
expect(dataAccessDAO.getRulesAssociatedWithRole("parent1")).andReturn(
new TreeSet<DataAccessRule>()).anyTimes();
expect(secMgr.getDataAccessRuleDAO()).andReturn(dataAccessDAO).anyTimes();
ServiceAccessRuleDAO serviceAccessDAO = createNiceMock(ServiceAccessRuleDAO.class);
expect(serviceAccessDAO.getRulesAssociatedWithRole(
(String)anyObject())).andReturn(new TreeSet<ServiceAccessRule>()).anyTimes();
expect(secMgr.getServiceAccessRuleDAO()).andReturn(serviceAccessDAO).anyTimes();
replay(dataAccessDAO, serviceAccessDAO, roleStore, secMgr);
return secMgr;
}
});
RoleStoreValidationWrapper store = new RoleStoreValidationWrapper(
(GeoServerRoleStore)getSecurityManager().loadRoleService("test"), true);
GeoServerRole role = store.getRoleByName("role1");
GeoServerRole parent = store.getRoleByName("parent1");
store.removeRole(parent);
try {
store.removeRole(role);
fail("used role should throw exception");
}
catch(IOException ex) {
assertSecurityException(ex, ROLE_IN_USE_$2, role.getAuthority(), "foo");
}
}
@Test
public void testRoleStoreWrapperWithUGServices() throws Exception {
setMockCreator(new MockCreator() {
@Override
public GeoServerSecurityManager createSecurityManager(MockTestData testData) throws Exception {
GeoServerSecurityManager secMgr = createNiceMock(GeoServerSecurityManager.class);
GeoServerUserGroupStore ugStore1 = createUserGroupStore("test1", secMgr);
addUsers(ugStore1, "user1", "abc");
addGroups(ugStore1, "group1");
GeoServerUserGroupStore ugStore2 = createUserGroupStore("test2", secMgr);
addUsers(ugStore1, "user2", "abc");
addGroups(ugStore1, "group2");
GeoServerRoleStore roleStore = createRoleStore("test", secMgr, "role1");
expect(roleStore.getGroupNamesForRole(new GeoServerRole("role1"))).andReturn(
new TreeSet<String>(Arrays.asList("group1", "group2"))).anyTimes();
replay(ugStore1, ugStore2, roleStore, secMgr);
return secMgr;
}
});
GeoServerSecurityManager secMgr = getSecurityManager();
GeoServerUserGroupStore ugStore1 = (GeoServerUserGroupStore) secMgr.loadUserGroupService("test1");
GeoServerUserGroupStore ugStore2 = (GeoServerUserGroupStore) secMgr.loadUserGroupService("test2");
RoleStoreValidationWrapper store = new RoleStoreValidationWrapper(
(GeoServerRoleStore)secMgr.loadRoleService("test"), ugStore1, ugStore2);
GeoServerRole role1 = store.getRoleByName("role1");
try {
store.associateRoleToGroup(role1, "group3");
fail("unkown group should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, GROUPNAME_NOT_FOUND_$1 , "group3");
}
try {
store.associateRoleToUser(role1, "user3");
fail("unkown user should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, USERNAME_NOT_FOUND_$1, "user3");
}
try {
store.getRolesForGroup("group3");
fail("unkown group should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, GROUPNAME_NOT_FOUND_$1 , "group3");
}
try {
store.getRolesForUser("user3");
fail("unkown user should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, USERNAME_NOT_FOUND_$1, "user3");
}
store.disAssociateRoleFromGroup(role1, "group1");
store.disAssociateRoleFromGroup(role1, "group2");
try {
store.disAssociateRoleFromGroup(role1, "group3");
fail("unkown group should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, GROUPNAME_NOT_FOUND_$1 , "group3");
}
store.disAssociateRoleFromUser(role1, "user1");
store.disAssociateRoleFromUser(role1, "user1");
try {
store.disAssociateRoleFromUser(role1, "user3");
fail("unkown user should throw exception");
} catch (IOException ex) {
assertSecurityException(ex, USERNAME_NOT_FOUND_$1, "user3");
}
}
@Test
public void testMappedRoles() throws Exception {
setMockCreator(new MockCreator() {
@Override
public GeoServerSecurityManager createSecurityManager(MockTestData testData) throws Exception {
GeoServerSecurityManager secMgr = createNiceMock(GeoServerSecurityManager.class);
GeoServerRoleStore roleStore =
createRoleStore("test", secMgr, "admin", "groupAdmin", "role1");
addRolesToCreate(roleStore, "admin", "groupAdmin");
expect(roleStore.getAdminRole()).andReturn(new GeoServerRole("admin")).anyTimes();
expect(roleStore.getGroupAdminRole()).andReturn(new GeoServerRole("groupAdmin")).anyTimes();
replay(roleStore, secMgr);
return secMgr;
}
});
GeoServerSecurityManager secMgr = getSecurityManager();
RoleStoreValidationWrapper store =
new RoleStoreValidationWrapper((GeoServerRoleStore)secMgr.loadRoleService("test"));
try {
store.removeRole(store.createRoleObject("admin"));
fail("removing admin role should fail");
} catch (IOException ex) {
assertSecurityException(ex,ADMIN_ROLE_NOT_REMOVABLE_$1,"admin" );
}
try {
store.removeRole(store.createRoleObject("groupAdmin"));
fail("removing group admin role should fail");
} catch (IOException ex) {
assertSecurityException(ex,GROUP_ADMIN_ROLE_NOT_REMOVABLE_$1,"groupAdmin" );
}
}
}