mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-28 04:13:22 -04:00
Fix clients-initial-access returning 200 instead of 201
The POST /clients-initial-access endpoint was returning 200 OK instead of 201 Created. The server-side create() method has been updated to return a proper JAX-RS Response with status 201 and a Location header pointing to the created resource. A doCreate() method is added to the ClientInitialAccessResource Java client interface returning the raw JAX-RS Response, allowing callers to access HTTP-level details such as the status code and Location header that the existing create() method hides. A test is added using doCreate() to verify the 201 status and Location header without modifying the existing typed create() interface. Closes #49185 Signed-off-by: Vinit Kumar <30852363+ThreeMangoTrees@users.noreply.github.com>
This commit is contained in:
parent
94dcc24a8d
commit
e17ce150e3
3 changed files with 35 additions and 10 deletions
|
|
@ -27,6 +27,7 @@ import jakarta.ws.rs.Path;
|
|||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessPresentation;
|
||||
|
|
@ -40,7 +41,12 @@ public interface ClientInitialAccessResource {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
ClientInitialAccessPresentation create(ClientInitialAccessCreatePresentation rep);
|
||||
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Response doCreate(ClientInitialAccessCreatePresentation rep);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
List<ClientInitialAccessPresentation> list();
|
||||
|
|
|
|||
|
|
@ -26,13 +26,11 @@ import jakarta.ws.rs.POST;
|
|||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.http.HttpResponse;
|
||||
import org.keycloak.models.ClientInitialAccessModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
|
@ -83,7 +81,7 @@ public class ClientInitialAccessResource {
|
|||
@Tag(name = KeycloakOpenAPI.Admin.Tags.CLIENT_INITIAL_ACCESS)
|
||||
@Operation( summary = "Create a new initial access token.")
|
||||
@APIResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = ClientInitialAccessCreatePresentation.class)))
|
||||
public Object create(ClientInitialAccessCreatePresentation config) {
|
||||
public Response create(ClientInitialAccessCreatePresentation config) {
|
||||
auth.clients().requireManage();
|
||||
|
||||
int expiration = config.getExpiration() != null ? config.getExpiration() : 0;
|
||||
|
|
@ -106,12 +104,10 @@ public class ClientInitialAccessResource {
|
|||
String token = ClientRegistrationTokenUtils.createInitialAccessToken(session, realm, clientInitialAccessModel, config.getWebOrigins());
|
||||
rep.setToken(token);
|
||||
|
||||
HttpResponse response = session.getContext().getHttpResponse();
|
||||
|
||||
response.setStatus(Response.Status.CREATED.getStatusCode());
|
||||
response.addHeader(HttpHeaders.LOCATION, session.getContext().getUri().getAbsolutePathBuilder().path(clientInitialAccessModel.getId()).build().toString());
|
||||
|
||||
return rep;
|
||||
return Response.status(Response.Status.CREATED)
|
||||
.entity(rep)
|
||||
.location(session.getContext().getUri().getAbsolutePathBuilder().path(clientInitialAccessModel.getId()).build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientInitialAccessResource;
|
||||
import org.keycloak.common.util.Time;
|
||||
|
|
@ -154,6 +155,28 @@ public class InitialAccessTokenResourceTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateReturns201WithLocationHeader() {
|
||||
ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation();
|
||||
rep.setCount(1);
|
||||
rep.setExpiration(100);
|
||||
|
||||
String id;
|
||||
try (Response response = resource.doCreate(rep)) {
|
||||
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
|
||||
|
||||
String location = response.getHeaderString("Location");
|
||||
assertNotNull(location, "Location header must be present on 201 Created");
|
||||
|
||||
ClientInitialAccessPresentation entity = response.readEntity(ClientInitialAccessPresentation.class);
|
||||
id = entity.getId();
|
||||
assertNotNull(id);
|
||||
assertNotNull(entity.getToken());
|
||||
assertThat(location, org.hamcrest.Matchers.endsWith("/clients-initial-access/" + id));
|
||||
}
|
||||
resource.delete(id);
|
||||
}
|
||||
|
||||
private void removeExpired(String realmUuid) {
|
||||
runOnServer.run(session -> {
|
||||
RealmModel realm = session.realms().getRealm(realmUuid);
|
||||
|
|
|
|||
Loading…
Reference in a new issue