KEYCLOAK-10393 Fix permission ticket pagination in Authz Client

KEYCLOAK-10393 Ensure idempotency of find method of permission ticket store
This commit is contained in:
skyfalke 2019-05-27 10:54:04 +02:00 committed by Pedro Igor
parent 40ec46b79b
commit 0007bad6f3
3 changed files with 38 additions and 3 deletions

View file

@ -213,8 +213,8 @@ public class PermissionResource {
.param("requester", requester)
.param("granted", granted == null ? null : granted.toString())
.param("returnNames", returnNames == null ? null : returnNames.toString())
.param("firstResult", firstResult == null ? null : firstResult.toString())
.param("maxResult", maxResult == null ? null : maxResult.toString())
.param("first", firstResult == null ? null : firstResult.toString())
.param("max", maxResult == null ? null : maxResult.toString())
.response().json(new TypeReference<List<PermissionTicketRepresentation>>(){}).execute();
}
};

View file

@ -215,7 +215,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore {
}
});
querybuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get("resource").get("id")));
querybuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get("id")));
Query query = entityManager.createQuery(querybuilder);

View file

@ -24,6 +24,7 @@ import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
@ -379,4 +380,38 @@ public class PermissionManagementTest extends AbstractResourceServerTest {
assertTrue(new String((HttpResponseException.class.cast(cause.getCause()).getBytes())).contains("invalid_scope"));
}
}
@Test
public void testGetPermissionTicketWithPagination() throws Exception {
String[] scopes = {"ScopeA", "ScopeB", "ScopeC", "ScopeD"};
ResourceRepresentation resource = addResource("Resource A", "kolo", true, scopes);
AuthzClient authzClient = getAuthzClient();
PermissionResponse response = authzClient.protection("marta", "password").permission().create(new PermissionRequest(resource.getId(), scopes));
AuthorizationRequest request = new AuthorizationRequest();
request.setTicket(response.getTicket());
request.setClaimToken(authzClient.obtainAccessToken("marta", "password").getToken());
try {
authzClient.authorization().authorize(request);
} catch (Exception e) {
}
// start with fetching the second half of all permission tickets
Collection<String> expectedScopes = new ArrayList(Arrays.asList(scopes));
List<PermissionTicketRepresentation> tickets = getAuthzClient().protection().permission().find(resource.getId(), null, null, null, null, true, 2, 2);
assertEquals("Returned number of permissions tickets must match the specified page size (i.e., 'maxResult').", 2, tickets.size());
boolean foundScope = expectedScopes.remove(tickets.get(0).getScopeName());
assertTrue("Returned set of permission tickets must be only a sub-set as per pagination offset and specified page size.", foundScope);
foundScope = expectedScopes.remove(tickets.get(1).getScopeName());
assertTrue("Returned set of permission tickets must be only a sub-set as per pagination offset and specified page size.", foundScope);
// fetch the first half of all permission tickets
tickets = getAuthzClient().protection().permission().find(resource.getId(), null, null, null, null, true, 0, 2);
assertEquals("Returned number of permissions tickets must match the specified page size (i.e., 'maxResult').", 2, tickets.size());
foundScope = expectedScopes.remove(tickets.get(0).getScopeName());
assertTrue("Returned set of permission tickets must be only a sub-set as per pagination offset and specified page size.", foundScope);
foundScope = expectedScopes.remove(tickets.get(1).getScopeName());
assertTrue("Returned set of permission tickets must be only a sub-set as per pagination offset and specified page size.", foundScope);
}
}