Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7307 get user by token #7345

Merged
merged 12 commits into from
Nov 3, 2020
3 changes: 3 additions & 0 deletions doc/release-notes/7307-get-user-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Notes for Tool Developers and Integrators

New API endpoint to retrieve user info so that tools can email users if needed.
9 changes: 8 additions & 1 deletion doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2875,8 +2875,15 @@ Sample output using "dataverseAdmin" as the ``identifier``::
"superuser": true,
"affiliation": "Dataverse.org"
}

Alternatively you may pass a user's api ``token`` to retrieve the same output::

GET http://$SERVER/api/admin/authenticatedUsers/token/$token
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, he admin api is blocked off (rightly so), so external tools would not be able to call this. Do we have other user APIs, if so this should go there. (if not, we should create something like "/api/users/"*)

  • I've never been a fan of the plural, but we should be consistent with "datasets", "dataverses", etc.

Also, we should be getting the token from the header, like we do from other APIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I assumed that since it was getting the same info it should have the same permissions required. I will change/fix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think as it is, the only token you can get info about is the one you already have, and it really functions like a /api/users/me call. Does anyone need to use one apitoken to check other ones? If not, and if this call should allow a header, then perhaps it shouldn't also have a token path parameter (just the header or &key= query param) to avoid scanners.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I left that part out, but by getting the token from the header, it doesn't need to have a token path parameter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For documentation purposes, we already have a "Get All Notifications by User" endpoint and it probably makes sense to put the new docs about getting your user info near these older docs, or vice versa: https://guides.dataverse.org/en/5.1.1/api/native-api.html#get-all-notifications-by-user

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, I moved the endpoint to the api/users path. I also moved the doc as suggested by Phil. that whole native api doc needs some reorganization work especially with respect to user related end points.


Create an Authenticated User
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Create an authenticateUser::
Create an authenticatedUser::

POST http://$SERVER/api/admin/authenticatedUsers

Expand Down
32 changes: 23 additions & 9 deletions src/main/java/edu/harvard/iq/dataverse/api/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,29 @@ public Response deleteAuthenticationProvider(@PathParam("id") String id) {
: ""));
}

@GET
@Path("authenticatedUsers/{identifier}/")
public Response getAuthenticatedUser(@PathParam("identifier") String identifier) {
AuthenticatedUser authenticatedUser = authSvc.getAuthenticatedUser(identifier);
if (authenticatedUser != null) {
return ok(json(authenticatedUser));
}
return error(Response.Status.BAD_REQUEST, "User " + identifier + " not found.");
}
@GET
@Path("authenticatedUsers/{identifier}/")
public Response getAuthenticatedUserByIdentifier(@PathParam("identifier") String identifier) {
AuthenticatedUser authenticatedUser = authSvc.getAuthenticatedUser(identifier);
if (authenticatedUser != null) {
return getAuthenticatedUser(authenticatedUser);
}
return error(Response.Status.BAD_REQUEST, "User " + identifier + " not found.");
}

@GET
@Path("authenticatedUsers/token/{token}/")
public Response getAuthenticatedUserByToken(@PathParam("token") String token) {
AuthenticatedUser authenticatedUser = authSvc.lookupUser(token);
if (authenticatedUser != null) {
return getAuthenticatedUser(authenticatedUser);
}
return error(Response.Status.BAD_REQUEST, "User with token " + token + " not found.");
}

private Response getAuthenticatedUser(AuthenticatedUser authenticatedUser) {
return ok(json(authenticatedUser));
}

@DELETE
@Path("authenticatedUsers/{identifier}/")
Expand Down
26 changes: 26 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/BuiltinUsersIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.stream.Stream;
import javax.json.Json;
import javax.json.JsonObjectBuilder;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static junit.framework.Assert.assertEquals;
Expand Down Expand Up @@ -72,6 +73,31 @@ public void testCreateTimeAndApiLastUse() {
.statusCode(OK.getStatusCode());

}

@Test
public void testFindByToken() {

Response createUser = UtilIT.createRandomUser();
createUser.prettyPrint();
createUser.then().assertThat()
.statusCode(OK.getStatusCode());

String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);

Response getUserAsJsonByToken = UtilIT.getAuthenticatedUserByToken(apiToken);

getUserAsJsonByToken.then().assertThat()
.statusCode(OK.getStatusCode());

getUserAsJsonByToken = UtilIT.getAuthenticatedUserByToken("badcode");
getUserAsJsonByToken.then().assertThat()
.body("status", equalTo("ERROR"))
.body("message", equalTo("User with token badcode not found."))
.statusCode(BAD_REQUEST.getStatusCode());

}


@Test
public void testLastApiUse() {
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,12 @@ static Response getAuthenticatedUser(String userIdentifier, String apiToken) {
.get("/api/admin/authenticatedUsers/" + userIdentifier);
return response;
}

static Response getAuthenticatedUserByToken(String apiToken) {
Response response = given()
.get("/api/admin/authenticatedUsers/token/" + apiToken);
return response;
}

/**
* Used to the test the filter Authenticated Users API endpoint
Expand Down