Properly encode id in URL

Closes: #19816
This commit is contained in:
Hynek Mlnarik 2023-04-03 17:33:49 +02:00 committed by Pedro Igor
parent 687c3868c1
commit 0ddc71d987
3 changed files with 28 additions and 24 deletions

View file

@ -26,6 +26,7 @@ import org.keycloak.authorization.client.util.Throwables;
import org.keycloak.authorization.client.util.TokenCallable;
import org.keycloak.representations.idm.authorization.UmaPermissionRepresentation;
import org.keycloak.util.JsonSerialization;
import static org.keycloak.common.util.Encode.encodePathAsIs;
/**
* An entry point for managing user-managed permissions for a particular resource
@ -60,7 +61,7 @@ public class PolicyResource {
Callable<UmaPermissionRepresentation> callable = new Callable<UmaPermissionRepresentation>() {
@Override
public UmaPermissionRepresentation call() throws Exception {
return http.<UmaPermissionRepresentation>post(serverConfiguration.getPolicyEndpoint() + "/" + resourceId)
return http.<UmaPermissionRepresentation>post(serverConfiguration.getPolicyEndpoint() + "/" + encodePathAsIs(resourceId))
.authorizationBearer(pat.call())
.json(JsonSerialization.writeValueAsBytes(permission))
.response().json(UmaPermissionRepresentation.class).execute();
@ -90,7 +91,7 @@ public class PolicyResource {
Callable<Void> callable = new Callable<Void>() {
@Override
public Void call() throws Exception {
http.<Void>put(serverConfiguration.getPolicyEndpoint() + "/"+ permission.getId())
http.<Void>put(serverConfiguration.getPolicyEndpoint() + "/"+ encodePathAsIs(permission.getId()))
.authorizationBearer(pat.call())
.json(JsonSerialization.writeValueAsBytes(permission)).execute();
return null;
@ -112,7 +113,7 @@ public class PolicyResource {
Callable<Void> callable = new Callable<Void>() {
@Override
public Void call() {
http.<UmaPermissionRepresentation>delete(serverConfiguration.getPolicyEndpoint() + "/" + id)
http.<UmaPermissionRepresentation>delete(serverConfiguration.getPolicyEndpoint() + "/" + encodePathAsIs(id))
.authorizationBearer(pat.call())
.response().execute();
return null;
@ -173,7 +174,7 @@ public class PolicyResource {
Callable<UmaPermissionRepresentation> callable = new Callable<UmaPermissionRepresentation>() {
@Override
public UmaPermissionRepresentation call() {
return http.<UmaPermissionRepresentation>get(serverConfiguration.getPolicyEndpoint() + "/" + id)
return http.<UmaPermissionRepresentation>get(serverConfiguration.getPolicyEndpoint() + "/" + encodePathAsIs(id))
.authorizationBearer(pat.call())
.response().json(UmaPermissionRepresentation.class).execute();
}

View file

@ -29,6 +29,7 @@ import org.keycloak.authorization.client.util.Throwables;
import org.keycloak.authorization.client.util.TokenCallable;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.util.JsonSerialization;
import static org.keycloak.common.util.Encode.encodePathAsIs;
/**
* An entry point for managing resources using the Protection API.
@ -86,7 +87,7 @@ public class ProtectedResource {
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
http.<ResourceRepresentation>put(serverConfiguration.getResourceRegistrationEndpoint() + "/" + resource.getId())
http.<ResourceRepresentation>put(serverConfiguration.getResourceRegistrationEndpoint() + "/" + encodePathAsIs(resource.getId()))
.authorizationBearer(pat.call())
.json(JsonSerialization.writeValueAsBytes(resource)).execute();
return null;
@ -109,7 +110,7 @@ public class ProtectedResource {
Callable<ResourceRepresentation> callable = new Callable<ResourceRepresentation>() {
@Override
public ResourceRepresentation call() throws Exception {
return http.<ResourceRepresentation>get(serverConfiguration.getResourceRegistrationEndpoint() + "/" + id)
return http.<ResourceRepresentation>get(serverConfiguration.getResourceRegistrationEndpoint() + "/" + encodePathAsIs(id))
.authorizationBearer(pat.call())
.response().json(ResourceRepresentation.class).execute();
}
@ -258,7 +259,7 @@ public class ProtectedResource {
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
http.delete(serverConfiguration.getResourceRegistrationEndpoint() + "/" + id)
http.delete(serverConfiguration.getResourceRegistrationEndpoint() + "/" + encodePathAsIs(id))
.authorizationBearer(pat.call())
.execute();
return null;

View file

@ -59,12 +59,14 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.keycloak.common.util.Encode.encodePathAsIs;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@ -302,7 +304,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
@Test
public void testGetResource() {
Resource resource = doGet("/" + getMyResources().get(0).getId(), Resource.class);
Resource resource = doGet("/" + encodePathAsIs(getMyResources().get(0).getId()), Resource.class);
String uri = resource.getUri();
int id = Integer.parseInt(uri.substring(uri.lastIndexOf('/') + 1));
@ -318,14 +320,14 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
OAuth2ErrorRepresentation response = doGet("/invalid_resource", OAuth2ErrorRepresentation.class);
assertEquals("resource_not_found", response.getError());
response = doGet("/" + getMyResources().get(0).getId(), authzClient.obtainAccessToken("jdoe", "password").getToken(), OAuth2ErrorRepresentation.class);
response = doGet("/" + encodePathAsIs(getMyResources().get(0).getId()), authzClient.obtainAccessToken("jdoe", "password").getToken(), OAuth2ErrorRepresentation.class);
assertEquals("invalid_resource", response.getError());
}
@Test
public void testGetPermissions() throws Exception {
Resource resource = getMyResources().get(0);
List<Permission> shares = doGet("/" + resource.getId() + "/permissions", new TypeReference<List<Permission>>() {});
List<Permission> shares = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions", new TypeReference<List<Permission>>() {});
assertEquals(1, shares.size());
@ -348,11 +350,11 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
permissions.add(permission);
}
SimpleHttp.doPut(getAccountUrl("resources/" + resource.getId() + "/permissions"), httpClient)
SimpleHttp.doPut(getAccountUrl("resources/" + encodePathAsIs(resource.getId()) + "/permissions"), httpClient)
.auth(tokenUtil.getToken())
.json(permissions).asResponse();
shares = doGet("/" + resource.getId() + "/permissions", new TypeReference<List<Permission>>() {});
shares = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions", new TypeReference<List<Permission>>() {});
assertEquals(3, shares.size());
@ -384,7 +386,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
permissions.add(new Permission(users.get(users.size() - 1), "Scope A", "Scope B", "Scope C", "Scope D"));
String resourceId = sharedResource.getId();
SimpleHttp.Response response = SimpleHttp.doPut(getAccountUrl("resources/" + resourceId + "/permissions"), httpClient)
SimpleHttp.Response response = SimpleHttp.doPut(getAccountUrl("resources/" + encodePathAsIs(resourceId) + "/permissions"), httpClient)
.auth(tokenUtil.getToken())
.json(permissions).asResponse();
@ -408,7 +410,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
public void failShareResourceInvalidPermissions() throws Exception {
List<Permission> permissions = new ArrayList<>();
SimpleHttp.Response response = SimpleHttp.doPut(getAccountUrl("resources/" + getMyResources().get(0).getId() + "/permissions"), httpClient)
SimpleHttp.Response response = SimpleHttp.doPut(getAccountUrl("resources/" + encodePathAsIs(getMyResources().get(0).getId()) + "/permissions"), httpClient)
.auth(tokenUtil.getToken())
.json(permissions).asResponse();
@ -434,7 +436,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
final String resourcesUrl = getAccountUrl("resources");
final String sharedWithOthersUrl = resourcesUrl + "/shared-with-others";
final String sharedWithMeUrl = resourcesUrl + "/shared-with-me";
final String resourceUrl = resourcesUrl + "/" + resourceId;
final String resourceUrl = resourcesUrl + "/" + encodePathAsIs(resourceId);
final String permissionsUrl = resourceUrl + "/permissions";
final String requestsUrl = resourceUrl + "/permissions/requests";
@ -473,7 +475,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
permissions.add(new Permission(users.get(users.size() - 1), "Scope B", "Scope D"));
String resourceId = sharedResource.getId();
SimpleHttp.Response response = SimpleHttp.doPut(getAccountUrl("resources/" + resourceId + "/permissions"), httpClient)
SimpleHttp.Response response = SimpleHttp.doPut(getAccountUrl("resources/" + encodePathAsIs(resourceId) + "/permissions"), httpClient)
.auth(tokenUtil.getToken())
.json(permissions).asResponse();
@ -496,7 +498,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
@Test
public void testGetPermissionRequests() {
Resource resource = getMyResources().get(0);
List<Permission> requests = doGet("/" + resource.getId() + "/permissions/requests",
List<Permission> requests = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions/requests",
new TypeReference<List<Permission>>() {});
assertTrue(requests.isEmpty());
@ -526,7 +528,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
}
}
requests = doGet("/" + resource.getId() + "/permissions/requests",
requests = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions/requests",
new TypeReference<List<Permission>>() {});
assertEquals(3, requests.size());
@ -560,7 +562,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
@Test
public void testApprovePermissionRequest() throws IOException {
Resource resource = getMyResources().get(0);
List<Permission> requests = doGet("/" + resource.getId() + "/permissions/requests",
List<Permission> requests = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions/requests",
new TypeReference<List<Permission>>() {});
assertTrue(requests.isEmpty());
@ -590,7 +592,7 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
}
}
requests = doGet("/" + resource.getId() + "/permissions/requests",
requests = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions/requests",
new TypeReference<List<Permission>>() {});
assertEquals(3, requests.size());
@ -609,14 +611,14 @@ public class ResourcesRestServiceTest extends AbstractRestServiceTest {
}
}
SimpleHttp.doPut(getAccountUrl("resources/" + resource.getId() + "/permissions"), httpClient)
SimpleHttp.doPut(getAccountUrl("resources/" + encodePathAsIs(resource.getId()) + "/permissions"), httpClient)
.auth(tokenUtil.getToken())
.json(requests).asResponse();
requests = doGet("/" + resource.getId() + "/permissions/requests",
requests = doGet("/" + encodePathAsIs(resource.getId()) + "/permissions/requests",
new TypeReference<List<Permission>>() {});
assertTrue(requests.isEmpty());
assertThat(requests, empty());
for (String user : Arrays.asList("alice", "jdoe")) {
AbstractResourceService.ResourcePermission sharedResource = getSharedWithMe(user).stream()