package org.ovirt.engine.api.restapi.resource.aaa; import java.util.LinkedList; import java.util.List; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.junit.Test; import org.ovirt.engine.api.model.Domain; import org.ovirt.engine.api.model.Fault; import org.ovirt.engine.api.model.Group; import org.ovirt.engine.api.restapi.resource.AbstractBackendCollectionResourceTest; import org.ovirt.engine.api.restapi.utils.DirectoryEntryIdUtils; import org.ovirt.engine.core.aaa.DirectoryGroup; import org.ovirt.engine.core.common.action.AddGroupParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.aaa.DbGroup; import org.ovirt.engine.core.common.interfaces.SearchType; import org.ovirt.engine.core.common.queries.DirectoryIdQueryParameters; import org.ovirt.engine.core.common.queries.IdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryParametersBase; import org.ovirt.engine.core.common.queries.VdcQueryType; public class BackendGroupsResourceTest extends AbstractBackendCollectionResourceTest<Group, DbGroup, BackendGroupsResource> { private static final String NAMESPACE = "*"; /** * This is the query that will be used when the user didn't provide any query explicitly. */ private static final String QUERY = "grpname != \"\""; /** * This is the query that will be used when the user provided a query explicitly in the parameters. */ private static final String SEARCH_QUERY = "name=s* AND id=*0 and grpname != \"\""; /** * These are the names that will be used to build the directory group objects returned by mocked directory group * searches, thus then must have the same format that we generate when searching in directories. */ private static final String[] GROUP_NAMES; private static final String[] GROUP_NAMES_WITH_NO_DOMAIN; static { GROUP_NAMES = new String[NAMES.length]; GROUP_NAMES_WITH_NO_DOMAIN = new String[NAMES.length]; for (int i = 0; i < NAMES.length; i++) { GROUP_NAMES_WITH_NO_DOMAIN[i] = "Groups/" + NAMES[i]; GROUP_NAMES[i] = GROUP_NAMES_WITH_NO_DOMAIN[i] + "@" + DOMAIN; } } public BackendGroupsResourceTest() { super(new BackendGroupsResource(), SearchType.DBGroup, "Groups : "); } @Test public void testList() throws Exception { UriInfo uriInfo = setUpUriExpectations(null); setUpQueryExpectations(QUERY); collection.setUriInfo(uriInfo); verifyCollection(getCollection()); } @Test public void testListFailure() throws Exception { UriInfo uriInfo = setUpUriExpectations(null); setUpQueryExpectations(QUERY, FAILURE); collection.setUriInfo(uriInfo); try { getCollection(); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { assertTrue(wae.getResponse().getEntity() instanceof Fault); assertEquals(mockl10n(FAILURE), ((Fault) wae.getResponse().getEntity()).getDetail()); } } @Test public void testListCrash() throws Exception { UriInfo uriInfo = setUpUriExpectations(null); Throwable t = new RuntimeException(FAILURE); setUpQueryExpectations(QUERY, t); collection.setUriInfo(uriInfo); try { getCollection(); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyFault(wae, BACKEND_FAILED_SERVER_LOCALE, t); } } @Test public void testListCrashClientLocale() throws Exception { UriInfo uriInfo = setUpUriExpectations(null); locales.add(CLIENT_LOCALE); Throwable t = new RuntimeException(FAILURE); setUpQueryExpectations(QUERY, t); collection.setUriInfo(uriInfo); try { getCollection(); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyFault(wae, BACKEND_FAILED_CLIENT_LOCALE, t); } finally { locales.clear(); } } @Test public void testQuery() throws Exception { UriInfo uriInfo = setUpUriExpectations(SEARCH_QUERY); setUpQueryExpectations(SEARCH_QUERY); collection.setUriInfo(uriInfo); verifyCollection(getCollection()); } /** * Test that a group can be added when the user provides explicitly the name of the directory, so there is no need * to extract it from the name of the group. */ @Test public void testAddGroupWithExplicitDirectoryName() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpEntityQueryExpectations(VdcQueryType.GetDomainList, VdcQueryParametersBase.class, new String[] {}, new Object[] {}, setUpDomains()); setUpGetEntityExpectations( "ADGROUP@" + DOMAIN + ":: name=" + GROUP_NAMES_WITH_NO_DOMAIN[0], SearchType.DirectoryGroup, getDirectoryGroup(0) ); DbGroup dbGroup = new DbGroup(getDirectoryGroup(0)); setUpCreationExpectations( VdcActionType.AddGroup, AddGroupParameters.class, new String[] { "GroupToAdd" }, new Object[] { dbGroup }, true, true, dbGroup.getId(), VdcQueryType.GetDbGroupById, IdQueryParameters.class, new String[] { "Id" }, new Object[] { dbGroup.getId()}, getEntity(0) ); Domain domain = new Domain(); domain.setName(DOMAIN); domain.setId(DirectoryEntryIdUtils.encode(domain.getName())); Group model = new Group(); model.setName(GROUP_NAMES_WITH_NO_DOMAIN[0]); model.setDomain(domain); Response response = collection.add(model); assertEquals(201, response.getStatus()); assertTrue(response.getEntity() instanceof Group); verifyModel((Group) response.getEntity(), 0); } private List<String> setUpDomains() { List<String> domains = new LinkedList<>(); domains.add("some.domain"); domains.add(DOMAIN); return domains; } /** * Test that a group can be added when the user doesn't explicitly provide the name of the directory, but provides * it as part of the group name. */ @Test public void testAddGroupWithImplicitDirectoryName() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpEntityQueryExpectations(VdcQueryType.GetDomainList, VdcQueryParametersBase.class, new String[] {}, new Object[] {}, setUpDomains()); setUpGetEntityExpectations( "ADGROUP@" + DOMAIN + ":: name=" + GROUP_NAMES_WITH_NO_DOMAIN[0], SearchType.DirectoryGroup, getDirectoryGroup(0) ); setUpCreationExpectations( VdcActionType.AddGroup, AddGroupParameters.class, new String[] { "GroupToAdd" }, new Object[] { new DbGroup(getDirectoryGroup(0)) }, true, true, GUIDS[0], VdcQueryType.GetDbGroupById, IdQueryParameters.class, new String[] { "Id" }, new Object[] { GUIDS[0] }, getEntity(0) ); Group model = new Group(); model.setName(GROUP_NAMES[0]); Response response = collection.add(model); assertEquals(201, response.getStatus()); assertTrue(response.getEntity() instanceof Group); verifyModel((Group) response.getEntity(), 0); } /** * Test that a group can't be added if the directory name isn't provider explicitly or as part of the group name. */ @Test public void testAddGroupWithoutDirectoryName() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpEntityQueryExpectations(VdcQueryType.GetDomainList, VdcQueryParametersBase.class, new String[] {}, new Object[] {}, setUpDomains()); Group model = new Group(); model.setName(GROUP_NAMES_WITH_NO_DOMAIN[0]); try { collection.add(model); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { assertNotNull(wae.getResponse()); assertEquals(400, wae.getResponse().getStatus()); } } /** * Test that if the group identifier is provided it is used to search in the directory instead of the name. */ @Test public void testAddGroupById() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpEntityQueryExpectations(VdcQueryType.GetDomainList, VdcQueryParametersBase.class, new String[] {}, new Object[] {}, setUpDomains()); setUpGetEntityExpectations( VdcQueryType.GetDirectoryGroupById, DirectoryIdQueryParameters.class, new String[] { "Domain", "Id" }, new Object[] { DOMAIN, DirectoryEntryIdUtils.decode(EXTERNAL_IDS[0]) }, getDirectoryGroup(0) ); setUpCreationExpectations( VdcActionType.AddGroup, AddGroupParameters.class, new String[] { "GroupToAdd" }, new Object[] { new DbGroup(getDirectoryGroup(0)) }, true, true, GUIDS[0], VdcQueryType.GetDbGroupById, IdQueryParameters.class, new String[] { "Id" }, new Object[] { GUIDS[0] }, getEntity(0) ); Group model = new Group(); model.setName(GROUP_NAMES[0]); model.setId(EXTERNAL_IDS[0]); Response response = collection.add(model); assertEquals(201, response.getStatus()); assertTrue(response.getEntity() instanceof Group); verifyModel((Group) response.getEntity(), 0); } /** * Test that if the provided directory identifier doesn't correspond to any existing directory user the user isn't * added. */ @Test public void testAddGroupByIdFailure() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpEntityQueryExpectations(VdcQueryType.GetDomainList, VdcQueryParametersBase.class, new String[] {}, new Object[] {}, setUpDomains()); setUpGetEntityExpectations( VdcQueryType.GetDirectoryGroupById, DirectoryIdQueryParameters.class, new String[] { "Domain", "Id" }, new Object[] { DOMAIN, DirectoryEntryIdUtils.decode(NON_EXISTANT_EXTERNAL_ID) }, null ); Group model = new Group(); model.setName(GROUP_NAMES[0]); model.setId(NON_EXISTANT_EXTERNAL_ID); try { collection.add(model); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { assertNotNull(wae.getResponse()); assertEquals(404, wae.getResponse().getStatus()); } } @Override protected List<Group> getCollection() { return collection.list().getGroups(); } @Override protected DbGroup getEntity(int index) { return new DbGroup(new DirectoryGroup(DOMAIN, NAMESPACE, EXTERNAL_IDS[index], GROUP_NAMES[index], "")); } private DirectoryGroup getDirectoryGroup(int index) { return new DirectoryGroup(DOMAIN, NAMESPACE, EXTERNAL_IDS[index], GROUP_NAMES[index], ""); } @Override protected void verifyModel(Group model, int index) { DbGroup entity = getEntity(index); assertEquals(entity.getId().toString(), model.getId()); assertEquals(entity.getName(), model.getName()); assertNotNull(model.getDomain()); assertEquals(DirectoryEntryIdUtils.encode(entity.getDomain()), model.getDomain().getId()); verifyLinks(model); } }