Skip to content

Commit

Permalink
Merge pull request #10858 from IQSS/10857-add-expiration-date-to-recr…
Browse files Browse the repository at this point in the history
…eate-token-api

Includes new token's expiration date in "users/token/recreate" endpoint
  • Loading branch information
ofahimIQSS authored Oct 1, 2024
2 parents 4c1e069 + 9a7af05 commit 08249f5
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
An optional query parameter called 'returnExpiration' has been added to the 'users/token/recreate' endpoint, which, if set to true, returns the expiration time in the response message.
6 changes: 6 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4412,6 +4412,12 @@ In order to obtain a new token use::
curl -H "X-Dataverse-key:$API_TOKEN" -X POST "$SERVER_URL/api/users/token/recreate"
This endpoint by default will return a response message indicating the user identifier and the new token.
To also include the expiration time in the response message, the query parameter ``returnExpiration`` must be set to true::
curl -H "X-Dataverse-key:$API_TOKEN" -X POST "$SERVER_URL/api/users/token/recreate?returnExpiration=true"
Delete a Token
~~~~~~~~~~~~~~
Expand Down
16 changes: 7 additions & 9 deletions src/main/java/edu/harvard/iq/dataverse/api/Users.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@
import jakarta.ejb.Stateless;
import jakarta.json.JsonArray;
import jakarta.json.JsonObjectBuilder;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.*;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
Expand Down Expand Up @@ -157,7 +151,7 @@ public Response getTokenExpirationDate() {
@Path("token/recreate")
@AuthRequired
@POST
public Response recreateToken(@Context ContainerRequestContext crc) {
public Response recreateToken(@Context ContainerRequestContext crc, @QueryParam("returnExpiration") boolean returnExpiration) {
User u = getRequestUser(crc);

AuthenticatedUser au;
Expand All @@ -174,8 +168,12 @@ public Response recreateToken(@Context ContainerRequestContext crc) {
ApiToken newToken = authSvc.generateApiTokenForUser(au);
authSvc.save(newToken);

return ok("New token for " + au.getUserIdentifier() + " is " + newToken.getTokenString());
String message = "New token for " + au.getUserIdentifier() + " is " + newToken.getTokenString();
if (returnExpiration) {
message += " and expires on " + newToken.getExpireTime();
}

return ok(message);
}

@GET
Expand Down
26 changes: 21 additions & 5 deletions src/test/java/edu/harvard/iq/dataverse/api/UsersIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.contains;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -371,23 +373,33 @@ public void testAPITokenEndpoints() {
.body("data.message", containsString(userApiToken))
.body("data.message", containsString("expires on"));

// Recreate given a bad API token
Response recreateToken = UtilIT.recreateToken("BAD-Token-blah-89234");
recreateToken.prettyPrint();
recreateToken.then().assertThat()
.statusCode(UNAUTHORIZED.getStatusCode());

// Recreate given a valid API token
recreateToken = UtilIT.recreateToken(userApiToken);
recreateToken.prettyPrint();
recreateToken.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.message", containsString("New token for"));
.body("data.message", containsString("New token for"))
.body("data.message", CoreMatchers.not(containsString("and expires on")));

// Recreate given a valid API token and returning expiration
createUser = UtilIT.createRandomUser();
createUser.prettyPrint();
assertEquals(200, createUser.getStatusCode());
assertEquals(OK.getStatusCode(), createUser.getStatusCode());

userApiToken = UtilIT.getApiTokenFromResponse(createUser);

recreateToken = UtilIT.recreateToken(userApiToken, true);
recreateToken.prettyPrint();
recreateToken.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.message", containsString("New token for"))
.body("data.message", containsString("and expires on"));

String userApiTokenForDelete = UtilIT.getApiTokenFromResponse(createUser);

/*
Add tests for Private URL
*/
Expand Down Expand Up @@ -418,6 +430,10 @@ public void testAPITokenEndpoints() {
getExpiration.then().assertThat()
.statusCode(NOT_FOUND.getStatusCode());

createUser = UtilIT.createRandomUser();
assertEquals(OK.getStatusCode(), createUser.getStatusCode());

String userApiTokenForDelete = UtilIT.getApiTokenFromResponse(createUser);

Response deleteToken = UtilIT.deleteToken(userApiTokenForDelete);
deleteToken.prettyPrint();
Expand Down
11 changes: 8 additions & 3 deletions src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -2813,10 +2813,15 @@ static Response getTokenExpiration( String apiToken) {
return response;
}

static Response recreateToken( String apiToken) {
static Response recreateToken(String apiToken) {
return recreateToken(apiToken, false);
}

static Response recreateToken(String apiToken, boolean returnExpiration) {
Response response = given()
.header(API_TOKEN_HTTP_HEADER, apiToken)
.post("api/users/token/recreate");
.header(API_TOKEN_HTTP_HEADER, apiToken)
.queryParam("returnExpiration", returnExpiration)
.post("api/users/token/recreate");
return response;
}

Expand Down

0 comments on commit 08249f5

Please sign in to comment.