From 76a4db5d547195f060e23ea3fe30680df6057557 Mon Sep 17 00:00:00 2001 From: Marko Strukelj Date: Thu, 24 Mar 2016 17:07:20 +0100 Subject: [PATCH] KEYCLOAK-2597 Invalid children group location header response --- .../resources/admin/GroupResource.java | 2 +- .../testsuite/admin/group/GroupTest.java | 21 ++++- .../keycloak/testsuite/util/URLAssert.java | 78 ++++++++++++++++++- 3 files changed, 96 insertions(+), 5 deletions(-) diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java index e82198517a..0563112fd9 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java @@ -129,7 +129,7 @@ public class GroupResource { child = realm.createGroup(rep.getName()); updateGroup(rep, child); URI uri = uriInfo.getBaseUriBuilder() - .path(uriInfo.getMatchedURIs().get(1)) + .path(uriInfo.getMatchedURIs().get(2)) .path(child.getId()).build(); builder.status(201).location(uri); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java index 81d8e6103b..e36985936a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java @@ -27,12 +27,16 @@ import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.util.URLAssert; +import org.keycloak.util.JsonSerialization; import javax.ws.rs.NotFoundException; import javax.ws.rs.core.Response; +import java.io.IOException; +import java.net.URI; import java.util.LinkedList; import java.util.List; -import java.util.UUID; /** @@ -107,6 +111,21 @@ public class GroupTest extends AbstractGroupTest { level2Group.setName("level2"); response = realm.groups().group(topGroup.getId()).subGroup(level2Group); response.close(); + + URI location = response.getLocation(); + final String level2Id = ApiUtil.getCreatedId(response); + final GroupRepresentation level2GroupById = realm.groups().group(level2Id).toRepresentation(); + Assert.assertEquals(level2Id, level2GroupById.getId()); + Assert.assertEquals(level2Group.getName(), level2GroupById.getName()); + + URLAssert.assertGetURL(location, adminClient.tokenManager().getAccessTokenString(), new URLAssert.AssertJSONResponseHandler() { + @Override + protected void assertResponseBody(String body) throws IOException { + GroupRepresentation level2 = JsonSerialization.readValue(body, GroupRepresentation.class); + Assert.assertEquals(level2Id, level2.getId()); + } + }); + level2Group = realm.getGroupByPath("/top/level2"); Assert.assertNotNull(level2Group); roles.clear(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java index c66fd70f66..6ef0bbe321 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/URLAssert.java @@ -18,14 +18,27 @@ package org.keycloak.testsuite.util; import javax.ws.rs.core.UriBuilder; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.junit.Assert; import org.keycloak.testsuite.page.AbstractPage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.keycloak.testsuite.auth.page.login.PageWithLoginUrl; import org.openqa.selenium.WebDriver; -import org.openqa.selenium.support.ui.ExpectedCondition; -import org.openqa.selenium.support.ui.WebDriverWait; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; +import java.net.URI; +import java.nio.charset.Charset; /** * @@ -104,9 +117,68 @@ public class URLAssert { public static void assertCurrentUrlStartsWithLoginUrlOf(PageWithLoginUrl page) { assertCurrentUrlStartsWithLoginUrlOf(page.getDriver(), page); } - + public static void assertCurrentUrlStartsWithLoginUrlOf(WebDriver driver, PageWithLoginUrl page) { assertCurrentUrlStartsWith(driver, page.getOIDCLoginUrl().toString()); } + public static void assertGetURL(URI url, String accessToken, AssertResponseHandler handler) { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + HttpGet get = new HttpGet(url); + get.setHeader("Authorization", "Bearer " + accessToken); + + CloseableHttpResponse response = httpclient.execute(get); + + if (response.getStatusLine().getStatusCode() != 200) { + throw new RuntimeException("Response status error: " + response.getStatusLine().getStatusCode() + ": " + url); + } + + handler.assertResponse(response); + + } catch (Exception e) { + throw new RuntimeException(e); + } + finally { + try { + httpclient.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public interface AssertResponseHandler { + void assertResponse(CloseableHttpResponse response) throws IOException; + } + + public static abstract class AssertJSONResponseHandler implements AssertResponseHandler { + + @Override + public void assertResponse(CloseableHttpResponse response) throws IOException { + HttpEntity entity = response.getEntity(); + Header contentType = entity.getContentType(); + Assert.assertEquals("application/json", contentType.getValue()); + + char [] buf = new char[8192]; + StringWriter out = new StringWriter(); + Reader in = new InputStreamReader(entity.getContent(), Charset.forName("utf-8")); + int rc = 0; + try { + while ((rc = in.read(buf)) != -1) { + out.write(buf, 0, rc); + } + } finally { + try { + in.close(); + } catch (Exception ignored) {} + + out.close(); + } + + assertResponseBody(out.toString()); + } + + protected abstract void assertResponseBody(String body) throws IOException; + } }