Skip to content

Commit

Permalink
Merge pull request #44 from auth0/feat-userinfo
Browse files Browse the repository at this point in the history
Add userInfo method
  • Loading branch information
hzalaz committed Nov 30, 2016
2 parents 1feaf0e + 4233e67 commit 8323003
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ authentication

```java
authentication
.tokenInfo("user token")
.userInfo("user access_token")
.start(new BaseCallback<Credentials>() {
@Override
public void onSuccess(UserProfile payload) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

import static com.auth0.android.authentication.ParameterBuilder.GRANT_TYPE_AUTHORIZATION_CODE;
import static com.auth0.android.authentication.ParameterBuilder.GRANT_TYPE_PASSWORD;
import static com.auth0.android.authentication.ParameterBuilder.ID_TOKEN_KEY;

/**
* API client for Auth0 Authentication API.
Expand Down Expand Up @@ -83,8 +84,10 @@ public class AuthenticationAPIClient {
private static final String TOKEN_PATH = "token";
private static final String RESOURCE_OWNER_PATH = "ro";
private static final String TOKEN_INFO_PATH = "tokeninfo";
private static final String USER_INFO_PATH = "userinfo";
private static final String OAUTH_CODE_KEY = "code";
private static final String REDIRECT_URI_KEY = "redirect_uri";
private static final String HEADER_AUTHORIZATION = "Authorization";

private final Auth0 auth0;
private final OkHttpClient client;
Expand Down Expand Up @@ -355,6 +358,29 @@ public AuthenticationRequest loginWithEmail(@NonNull String email, @NonNull Stri
return loginWithEmail(email, verificationCode, EMAIL_CONNECTION);
}

/**
* Returns the information of the user associated with the given access_token.
* Example usage:
* <pre><code>
* client.userInfo("{access_token}")
* .start(new BaseCallback<UserProfile>() {
* {@literal}Override
* public void onSuccess(UserProfile payload) { }
*
* {@literal}@Override
* public void onFailure(AuthenticationException error) { }
* });
* </code></pre>
*
* @param accessToken used to fetch it's information
* @return a request to start
*/
@SuppressWarnings("WeakerAccess")
public Request<UserProfile, AuthenticationException> userInfo(@NonNull String accessToken) {
return profileRequest()
.addHeader(HEADER_AUTHORIZATION, "Bearer " + accessToken);
}

/**
* Fetch the token information from Auth0
* Example usage:
Expand All @@ -374,8 +400,12 @@ public AuthenticationRequest loginWithEmail(@NonNull String email, @NonNull Stri
*/
@SuppressWarnings("WeakerAccess")
public Request<UserProfile, AuthenticationException> tokenInfo(@NonNull String idToken) {
return profileRequest()
.addParameter(ParameterBuilder.ID_TOKEN_KEY, idToken);
HttpUrl url = HttpUrl.parse(auth0.getDomainUrl()).newBuilder()
.addPathSegment(TOKEN_INFO_PATH)
.build();

return factory.POST(url, client, gson, UserProfile.class, authErrorBuilder)
.addParameter(ID_TOKEN_KEY, idToken);
}

/**
Expand Down Expand Up @@ -911,10 +941,10 @@ private AuthenticationRequest loginWithResourceOwner(Map<String, Object> paramet

private ParameterizableRequest<UserProfile, AuthenticationException> profileRequest() {
HttpUrl url = HttpUrl.parse(auth0.getDomainUrl()).newBuilder()
.addPathSegment(TOKEN_INFO_PATH)
.addPathSegment(USER_INFO_PATH)
.build();

return factory.POST(url, client, gson, UserProfile.class, authErrorBuilder);
return factory.GET(url, client, gson, UserProfile.class, authErrorBuilder);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@
*/
public class ProfileRequest implements Request<Authentication, AuthenticationException> {

private static final String ID_TOKEN_KEY = "id_token";
private static final String ACCESS_TOKEN_KEY = "access_token";
private static final String HEADER_AUTHORIZATION = "Authorization";

private final AuthenticationRequest credentialsRequest;
private final ParameterizableRequest<UserProfile, AuthenticationException> tokenInfoRequest;
private final ParameterizableRequest<UserProfile, AuthenticationException> userInfoRequest;

public ProfileRequest(AuthenticationRequest credentialsRequest, ParameterizableRequest<UserProfile, AuthenticationException> tokenInfoRequest) {
public ProfileRequest(AuthenticationRequest credentialsRequest, ParameterizableRequest<UserProfile, AuthenticationException> userInfoRequest) {
this.credentialsRequest = credentialsRequest;
this.tokenInfoRequest = tokenInfoRequest;
this.userInfoRequest = userInfoRequest;
}

/**
Expand Down Expand Up @@ -94,8 +95,8 @@ public void start(final BaseCallback<Authentication, AuthenticationException> ca
credentialsRequest.start(new BaseCallback<Credentials, AuthenticationException>() {
@Override
public void onSuccess(final Credentials credentials) {
tokenInfoRequest
.addParameter(ID_TOKEN_KEY, credentials.getIdToken())
userInfoRequest
.addHeader(HEADER_AUTHORIZATION, "Bearer " + credentials.getAccessToken())
.start(new BaseCallback<UserProfile, AuthenticationException>() {
@Override
public void onSuccess(UserProfile profile) {
Expand Down Expand Up @@ -125,8 +126,8 @@ public void onFailure(AuthenticationException error) {
@Override
public Authentication execute() throws Auth0Exception {
Credentials credentials = credentialsRequest.execute();
UserProfile profile = tokenInfoRequest
.addParameter(ID_TOKEN_KEY, credentials.getIdToken())
UserProfile profile = userInfoRequest
.addHeader(HEADER_AUTHORIZATION, "Bearer " + credentials.getAccessToken())
.execute();
return new Authentication(profile, credentials);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ public <T, U extends Auth0Exception> ParameterizableRequest<T, U> DELETE(HttpUrl
return request;
}

public <T, U extends Auth0Exception> ParameterizableRequest<T, U> GET(HttpUrl url, OkHttpClient client, Gson gson, Class<T> clazz, ErrorBuilder<U> errorBuilder) {
final ParameterizableRequest<T, U> request = createSimpleRequest(url, client, gson, "GET", clazz, errorBuilder);
addMetrics(request);
return request;
}

private <T, U extends Auth0Exception> void addMetrics(ParameterizableRequest<T, U> request) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
request.addHeader(entry.getKey(), entry.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.IOException;
Expand Down Expand Up @@ -79,9 +78,9 @@ public void onResponse(Response response) throws IOException {

@Override
protected Request doBuildRequest() throws RequestBodyBuildException {
RequestBody body = buildBody();
boolean sendBody = method.equals("HEAD") || method.equals("GET");
return newBuilder()
.method(method, body)
.method(method, sendBody ? null : buildBody())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ public void shouldFetchTokenInfo() throws Exception {
final RecordedRequest request = mockAPI.takeRequest();
assertThat(request.getHeader("Accept-Language"), is(getDefaultLocale()));
assertThat(request.getPath(), equalTo("/tokeninfo"));

Map<String, String> body = bodyFromRequest(request);
assertThat(body, hasEntry("id_token", "ID_TOKEN"));
}

@Test
Expand All @@ -269,6 +272,41 @@ public void shouldFetchTokenInfoSync() throws Exception {
final RecordedRequest request = mockAPI.takeRequest();
assertThat(request.getHeader("Accept-Language"), is(getDefaultLocale()));
assertThat(request.getPath(), equalTo("/tokeninfo"));

Map<String, String> body = bodyFromRequest(request);
assertThat(body, hasEntry("id_token", "ID_TOKEN"));
}

@Test
public void shouldFetchUserInfo() throws Exception {
mockAPI.willReturnTokenInfo();
final MockAuthenticationCallback<UserProfile> callback = new MockAuthenticationCallback<>();

client.userInfo("ACCESS_TOKEN")
.start(callback);

assertThat(callback, hasPayloadOfType(UserProfile.class));

final RecordedRequest request = mockAPI.takeRequest();
assertThat(request.getHeader("Accept-Language"), is(getDefaultLocale()));
assertThat(request.getHeader("Authorization"), is("Bearer ACCESS_TOKEN"));
assertThat(request.getPath(), equalTo("/userinfo"));
}

@Test
public void shouldFetchUserInfoSync() throws Exception {
mockAPI.willReturnTokenInfo();

final UserProfile profile = client
.userInfo("ACCESS_TOKEN")
.execute();

assertThat(profile, is(notNullValue()));

final RecordedRequest request = mockAPI.takeRequest();
assertThat(request.getHeader("Accept-Language"), is(getDefaultLocale()));
assertThat(request.getHeader("Authorization"), is("Bearer ACCESS_TOKEN"));
assertThat(request.getPath(), equalTo("/userinfo"));
}

@Test
Expand Down Expand Up @@ -1334,7 +1372,8 @@ public void shouldFetchProfileAfterLoginRequest() throws Exception {
assertThat(body, hasEntry("connection", MY_CONNECTION));

final RecordedRequest secondRequest = mockAPI.takeRequest();
assertThat(secondRequest.getPath(), equalTo("/tokeninfo"));
assertThat(secondRequest.getHeader("Authorization"), is("Bearer " + AuthenticationAPI.ACCESS_TOKEN));
assertThat(secondRequest.getPath(), equalTo("/userinfo"));

assertThat(callback, hasPayloadOfType(Authentication.class));
}
Expand Down Expand Up @@ -1378,6 +1417,29 @@ public void shouldRenewAuthSync() throws Exception {
assertThat(credentials, is(notNullValue()));
}

@Test
public void shouldFetchProfileSyncAfterLoginRequest() throws Exception {
mockAPI.willReturnSuccessfulLogin()
.willReturnTokenInfo();

Authentication authentication = client.getProfileAfter(client.login(SUPPORT_AUTH0_COM, "voidpassword", MY_CONNECTION))
.execute();

final RecordedRequest firstRequest = mockAPI.takeRequest();
assertThat(firstRequest.getPath(), equalTo("/oauth/ro"));

Map<String, String> body = bodyFromRequest(firstRequest);
assertThat(body, hasEntry("username", SUPPORT_AUTH0_COM));
assertThat(body, hasEntry("password", "voidpassword"));
assertThat(body, hasEntry("connection", MY_CONNECTION));

final RecordedRequest secondRequest = mockAPI.takeRequest();
assertThat(secondRequest.getHeader("Authorization"), is("Bearer " + AuthenticationAPI.ACCESS_TOKEN));
assertThat(secondRequest.getPath(), equalTo("/userinfo"));

assertThat(authentication, is(notNullValue()));
}

@Test
public void shouldGetOAuthTokensUsingCodeVerifier() throws Exception {
mockAPI.willReturnTokens()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
public class ProfileRequestTest {

private AuthenticationRequest credentialsMockRequest;
private ParameterizableRequest tokenInfoMockRequest;
private ParameterizableRequest userInfoMockRequest;
private ProfileRequest profileRequest;

@Before
public void setUp() throws Exception {
credentialsMockRequest = mock(AuthenticationRequest.class);
tokenInfoMockRequest = mock(ParameterizableRequest.class);
profileRequest = new ProfileRequest(credentialsMockRequest, tokenInfoMockRequest);
userInfoMockRequest = mock(ParameterizableRequest.class);
profileRequest = new ProfileRequest(credentialsMockRequest, userInfoMockRequest);
}

@Test
Expand Down Expand Up @@ -145,8 +145,9 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
}
});
final UserProfile userProfile = mock(UserProfile.class);
when(tokenInfoMockRequest.addParameter(anyString(), anyObject())).thenReturn(tokenInfoMockRequest);
when(tokenInfoMockRequest.execute()).thenAnswer(new Answer<Object>() {
when(userInfoMockRequest.addParameter(anyString(), anyObject())).thenReturn(userInfoMockRequest);
when(userInfoMockRequest.addHeader(anyString(), anyString())).thenReturn(userInfoMockRequest);
when(userInfoMockRequest.execute()).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return userProfile;
Expand All @@ -155,7 +156,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
final Authentication executeResult = profileRequest.execute();

verify(credentialsMockRequest).execute();
verify(tokenInfoMockRequest).execute();
verify(userInfoMockRequest).execute();
assertThat(executeResult, is(notNullValue()));
assertThat(executeResult, is(instanceOf(Authentication.class)));
assertThat(executeResult.getCredentials(), is(notNullValue()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class AuthenticationAPI {

public static final String REFRESH_TOKEN = "REFRESH_TOKEN";
public static final String ID_TOKEN = "ID_TOKEN";
private static final String ACCESS_TOKEN = "ACCESS_TOKEN";
public static final String ACCESS_TOKEN = "ACCESS_TOKEN";
private static final String BEARER = "BEARER";
public static final String GENERIC_TOKEN = "GENERIC_TOKEN";
private static final String NEW_ID_TOKEN = "NEW_ID_TOKEN";
Expand Down

0 comments on commit 8323003

Please sign in to comment.