Added a check in ClientInitialAccessResource (#29353)

closes #29311

Signed-off-by: Kaustubh Bawankar <kbawanka@redhat.com>
This commit is contained in:
kaustubh-rh 2024-05-13 16:30:36 +05:30 committed by GitHub
parent fbdaf03972
commit 8a82b6b587
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 44 additions and 1 deletions

View file

@ -31,6 +31,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
import org.keycloak.representations.idm.ClientInitialAccessPresentation; import org.keycloak.representations.idm.ClientInitialAccessPresentation;
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
import org.keycloak.services.clientregistration.ClientRegistrationTokenUtils; import org.keycloak.services.clientregistration.ClientRegistrationTokenUtils;
import org.keycloak.services.resources.KeycloakOpenAPI; import org.keycloak.services.resources.KeycloakOpenAPI;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator; import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
@ -45,6 +46,9 @@ import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -80,11 +84,19 @@ public class ClientInitialAccessResource {
@Tag(name = KeycloakOpenAPI.Admin.Tags.CLIENT_INITIAL_ACCESS) @Tag(name = KeycloakOpenAPI.Admin.Tags.CLIENT_INITIAL_ACCESS)
@Operation( summary = "Create a new initial access token.") @Operation( summary = "Create a new initial access token.")
@APIResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = ClientInitialAccessCreatePresentation.class))) @APIResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = ClientInitialAccessCreatePresentation.class)))
public ClientInitialAccessPresentation create(ClientInitialAccessCreatePresentation config) { public Object create(ClientInitialAccessCreatePresentation config) {
auth.clients().requireManage(); auth.clients().requireManage();
int expiration = config.getExpiration() != null ? config.getExpiration() : 0; int expiration = config.getExpiration() != null ? config.getExpiration() : 0;
int count = config.getCount() != null ? config.getCount() : 1; int count = config.getCount() != null ? config.getCount() : 1;
if (expiration < 0) {
OAuth2ErrorRepresentation error = new OAuth2ErrorRepresentation("Invalid value for expiration", "The expiration time interval cannot be less than 0");
return Response.status(400).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build();
}
if (count < 0) {
OAuth2ErrorRepresentation error = new OAuth2ErrorRepresentation("Invalid value for count", "The count cannot be less than 0");
return Response.status(400).entity(error).type(MediaType.APPLICATION_JSON_TYPE).build();
}
ClientInitialAccessModel clientInitialAccessModel = session.realms().createClientInitialAccessModel(realm, expiration, count); ClientInitialAccessModel clientInitialAccessModel = session.realms().createClientInitialAccessModel(realm, expiration, count);

View file

@ -17,6 +17,7 @@
package org.keycloak.testsuite.admin; package org.keycloak.testsuite.admin;
import jakarta.ws.rs.BadRequestException;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.keycloak.admin.client.resource.ClientInitialAccessResource; import org.keycloak.admin.client.resource.ClientInitialAccessResource;
@ -26,6 +27,7 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
import org.keycloak.representations.idm.ClientInitialAccessPresentation; import org.keycloak.representations.idm.ClientInitialAccessPresentation;
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.AdminEventPaths;
@ -94,6 +96,35 @@ public class InitialAccessTokenResourceTest extends AbstractAdminTest {
assertEquals(5, list.get(0).getCount() + list.get(1).getCount()); assertEquals(5, list.get(0).getCount() + list.get(1).getCount());
} }
@Test
public void testInvalidParametersWhileCreatingInitialAccessTokens() {
// Set Count as -1
ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation();
rep.setCount(-1);
rep.setExpiration(100);
try {
resource.create(rep);
Assert.fail("Invalid value for count");
}catch (BadRequestException e){
OAuth2ErrorRepresentation error = e.getResponse().readEntity(OAuth2ErrorRepresentation.class);
Assert.assertEquals("Invalid value for count", error.getError());
Assert.assertEquals("The count cannot be less than 0", error.getErrorDescription());
}
// Set Expiration as -10
rep = new ClientInitialAccessCreatePresentation();
rep.setCount(100);
rep.setExpiration(-10);
try {
resource.create(rep);
Assert.fail("Invalid value for expiration");
}catch (BadRequestException e){
OAuth2ErrorRepresentation error = e.getResponse().readEntity(OAuth2ErrorRepresentation.class);
Assert.assertEquals("Invalid value for expiration", error.getError());
Assert.assertEquals("The expiration time interval cannot be less than 0", error.getErrorDescription());
}
}
@Test @Test
public void testPeriodicExpiration() throws ClientRegistrationException, InterruptedException { public void testPeriodicExpiration() throws ClientRegistrationException, InterruptedException {