Skip to content

Commit

Permalink
Merge pull request #387 from auth0/send-custom-audience
Browse files Browse the repository at this point in the history
Send custom audience on login/signIn if is OIDC conformant
  • Loading branch information
hzalaz authored Jan 2, 2017
2 parents 72b921f + 56cd2c4 commit f3533a2
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 22 deletions.
2 changes: 1 addition & 1 deletion lib/src/main/java/com/auth0/android/lock/Lock.java
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ public Builder withScope(@NonNull String scope) {
}

/**
* Sets the Audience or API Identifier to request access to when performing the Authentication.
* Sets the Audience or API Identifier to request access to when performing the Authentication. This only applies if {@link com.auth0.android.Auth0#isOIDCConformant} is true.
*
* @param audience to use in the Authentication.
* @return the current builder instance
Expand Down
29 changes: 20 additions & 9 deletions lib/src/main/java/com/auth0/android/lock/LockActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

import com.auth0.android.authentication.AuthenticationAPIClient;
import com.auth0.android.authentication.AuthenticationException;
import com.auth0.android.authentication.request.SignUpRequest;
import com.auth0.android.callback.AuthenticationCallback;
import com.auth0.android.lock.errors.AuthenticationError;
import com.auth0.android.lock.errors.LoginErrorMessageBuilder;
Expand All @@ -67,6 +68,7 @@
import com.auth0.android.provider.AuthCallback;
import com.auth0.android.provider.AuthProvider;
import com.auth0.android.provider.WebAuthProvider;
import com.auth0.android.request.AuthenticationRequest;
import com.auth0.android.result.Credentials;
import com.auth0.android.result.DatabaseUser;
import com.squareup.okhttp.OkHttpClient;
Expand Down Expand Up @@ -314,10 +316,13 @@ public void onOAuthAuthenticationRequest(OAuthLoginEvent event) {
if (event.useActiveFlow()) {
lockView.showProgress(true);
Log.d(TAG, "Using the /ro endpoint for this OAuth Login Request");
options.getAuthenticationAPIClient()
AuthenticationRequest request = options.getAuthenticationAPIClient()
.login(event.getUsername(), event.getPassword(), connection)
.addAuthenticationParameters(options.getAuthenticationParameters())
.start(authCallback);
.addAuthenticationParameters(options.getAuthenticationParameters());
if (options.getAudience() != null && options.getAccount().isOIDCConformant()) {
request.setAudience(options.getAudience());
}
request.start(authCallback);
return;
}

Expand Down Expand Up @@ -349,9 +354,12 @@ public void onDatabaseAuthenticationRequest(DatabaseLoginEvent event) {
parameters.put(KEY_VERIFICATION_CODE, event.getVerificationCode());
}
final String connection = configuration.getDatabaseConnection().getName();
apiClient.login(event.getUsernameOrEmail(), event.getPassword(), connection)
.addAuthenticationParameters(parameters)
.start(authCallback);
AuthenticationRequest request = apiClient.login(event.getUsernameOrEmail(), event.getPassword(), connection)
.addAuthenticationParameters(parameters);
if (options.getAudience() != null && options.getAccount().isOIDCConformant()) {
request.setAudience(options.getAudience());
}
request.start(authCallback);
}

@SuppressWarnings("unused")
Expand All @@ -368,9 +376,12 @@ public void onDatabaseAuthenticationRequest(DatabaseSignUpEvent event) {

if (configuration.loginAfterSignUp()) {
Map<String, Object> authParameters = new HashMap<>(options.getAuthenticationParameters());
event.getSignUpRequest(apiClient, connection)
.addAuthenticationParameters(authParameters)
.start(authCallback);
SignUpRequest request = event.getSignUpRequest(apiClient, connection)
.addAuthenticationParameters(authParameters);
if (options.getAudience() != null && options.getAccount().isOIDCConformant()) {
request.setAudience(options.getAudience());
}
request.start(authCallback);
} else {
event.getCreateUserRequest(apiClient, connection)
.start(createCallback);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/main/java/com/auth0/android/lock/WebProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void start(Activity activity, String connection, AuthCallback callback, i
builder.withScope(scope);
}
final String audience = options.getAudience();
if (audience != null) {
if (audience != null && options.getAccount().isOIDCConformant()) {
builder.withAudience(audience);
}
final String scheme = options.getScheme();
Expand Down
75 changes: 68 additions & 7 deletions lib/src/test/java/com/auth0/android/lock/LockActivityTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
Expand Down Expand Up @@ -74,14 +75,18 @@ public class LockActivityTest {
Configuration configuration;
@Mock
ClassicLockView lockView;
@Captor
ArgumentCaptor<Map> mapCaptor;
LockActivity activity;
HashMap basicParameters;

@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
HashMap<String, Object> basicParameters = new HashMap<>(Collections.singletonMap("extra", "value"));
basicParameters = new HashMap<>(Collections.singletonMap("extra", "value"));
when(options.getAccount()).thenReturn(new Auth0("cliendId", "domain"));
when(options.getAuthenticationAPIClient()).thenReturn(client);
when(options.getAudience()).thenReturn("aud");

when(options.getAuthenticationParameters()).thenReturn(basicParameters);
when(client.login(anyString(), anyString(), anyString())).thenReturn(authRequest);
Expand Down Expand Up @@ -120,13 +125,13 @@ public void shouldCallDatabaseLogin() throws Exception {
DatabaseLoginEvent event = new DatabaseLoginEvent("username", "password");
activity.onDatabaseAuthenticationRequest(event);

ArgumentCaptor<Map> mapCaptor = ArgumentCaptor.forClass(Map.class);

verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(client).login(eq("username"), eq("password"), eq("connection"));
verify(authRequest).addAuthenticationParameters(mapCaptor.capture());
verify(authRequest).start(any(BaseCallback.class));
verify(authRequest, never()).setAudience("aud");
verify(configuration, atLeastOnce()).getDatabaseConnection();

Map<String, String> reqParams = mapCaptor.getValue();
Expand All @@ -140,13 +145,13 @@ public void shouldCallDatabaseLoginWithVerificationCode() throws Exception {
event.setVerificationCode("123456");
activity.onDatabaseAuthenticationRequest(event);

ArgumentCaptor<Map> mapCaptor = ArgumentCaptor.forClass(Map.class);

verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(client).login(eq("username"), eq("password"), eq("connection"));
verify(authRequest).addAuthenticationParameters(mapCaptor.capture());
verify(authRequest).start(any(BaseCallback.class));
verify(authRequest, never()).setAudience("aud");
verify(configuration, atLeastOnce()).getDatabaseConnection();

Map<String, String> reqParams = mapCaptor.getValue();
Expand All @@ -155,6 +160,33 @@ public void shouldCallDatabaseLoginWithVerificationCode() throws Exception {
assertThat(reqParams, hasEntry("mfa_code", "123456"));
}

@Test
public void shouldCallDatabaseLoginWithCustomAudience() throws Exception {
Auth0 account = new Auth0("cliendId", "domain");
account.setOIDCConformant(true);
Options options = mock(Options.class);
when(options.getAccount()).thenReturn(account);
when(options.getAuthenticationAPIClient()).thenReturn(client);
when(options.getAudience()).thenReturn("aud");
when(options.getAuthenticationParameters()).thenReturn(basicParameters);
LockActivity activity = new LockActivity(configuration, options, lockView, webProvider);

DatabaseLoginEvent event = new DatabaseLoginEvent("username", "password");
activity.onDatabaseAuthenticationRequest(event);

verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(client).login(eq("username"), eq("password"), eq("connection"));
verify(authRequest).addAuthenticationParameters(mapCaptor.capture());
verify(authRequest).setAudience("aud");
verify(authRequest).start(any(BaseCallback.class));
verify(configuration, atLeastOnce()).getDatabaseConnection();

Map<String, String> reqParams = mapCaptor.getValue();
assertThat(reqParams, is(notNullValue()));
assertThat(reqParams, hasEntry("extra", "value"));
}


@Test
public void shouldFailDatabaseSignUpOnNullConnection() throws Exception {
Expand Down Expand Up @@ -198,19 +230,49 @@ public void shouldCallDatabaseSignUp() throws Exception {
verify(configuration, atLeastOnce()).getDatabaseConnection();
}

@Test
public void shouldCallDatabaseSignInWithCustomAudience() throws Exception {
Auth0 account = new Auth0("cliendId", "domain");
account.setOIDCConformant(true);
Options options = mock(Options.class);
when(options.getAccount()).thenReturn(account);
when(options.getAuthenticationAPIClient()).thenReturn(client);
when(options.getAudience()).thenReturn("aud");
when(options.getAuthenticationParameters()).thenReturn(basicParameters);
LockActivity activity = new LockActivity(configuration, options, lockView, webProvider);

when(configuration.loginAfterSignUp()).thenReturn(true);

DatabaseSignUpEvent event = new DatabaseSignUpEvent("email@domain.com", "password", "username");
activity.onDatabaseAuthenticationRequest(event);


verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(signUpRequest).addAuthenticationParameters(mapCaptor.capture());
verify(signUpRequest).start(any(BaseCallback.class));
verify(signUpRequest).setAudience("aud");
verify(client).signUp(eq("email@domain.com"), eq("password"), eq("username"), eq("connection"));
verify(configuration, atLeastOnce()).getDatabaseConnection();

Map<String, String> reqParams = mapCaptor.getValue();
assertThat(reqParams, is(notNullValue()));
assertThat(reqParams, hasEntry("extra", "value"));
}

@Test
public void shouldCallDatabaseSignInWithUsername() throws Exception {
when(configuration.loginAfterSignUp()).thenReturn(true);

DatabaseSignUpEvent event = new DatabaseSignUpEvent("email@domain.com", "password", "username");
activity.onDatabaseAuthenticationRequest(event);

ArgumentCaptor<Map> mapCaptor = ArgumentCaptor.forClass(Map.class);

verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(signUpRequest).addAuthenticationParameters(mapCaptor.capture());
verify(signUpRequest).start(any(BaseCallback.class));
verify(signUpRequest, never()).setAudience("aud");
verify(client).signUp(eq("email@domain.com"), eq("password"), eq("username"), eq("connection"));
verify(configuration, atLeastOnce()).getDatabaseConnection();

Expand All @@ -226,12 +288,12 @@ public void shouldCallDatabaseSignIn() throws Exception {
DatabaseSignUpEvent event = new DatabaseSignUpEvent("email", "password", null);
activity.onDatabaseAuthenticationRequest(event);

ArgumentCaptor<Map> mapCaptor = ArgumentCaptor.forClass(Map.class);

verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(signUpRequest).addAuthenticationParameters(mapCaptor.capture());
verify(signUpRequest).start(any(BaseCallback.class));
verify(signUpRequest, never()).setAudience("aud");
verify(client).signUp(eq("email"), eq("password"), eq("connection"));
verify(configuration, atLeastOnce()).getDatabaseConnection();

Expand Down Expand Up @@ -274,12 +336,12 @@ public void shouldCallOAuthAuthenticationWithActiveFlow() throws Exception {
OAuthLoginEvent event = new OAuthLoginEvent(connection, "email@domain.com", "password");
activity.onOAuthAuthenticationRequest(event);

ArgumentCaptor<Map> mapCaptor = ArgumentCaptor.forClass(Map.class);

verify(lockView).showProgress(true);
verify(options).getAuthenticationAPIClient();
verify(authRequest).addAuthenticationParameters(mapCaptor.capture());
verify(authRequest).start(any(BaseCallback.class));
verify(authRequest, never()).setAudience("aud");
verify(client).login(eq("email@domain.com"), eq("password"), eq("my-connection"));

Map<String, String> reqParams = mapCaptor.getValue();
Expand All @@ -299,7 +361,6 @@ public void shouldCallOAuthAuthenticationWithCustomProvider() throws Exception {
OAuthLoginEvent event = new OAuthLoginEvent(connection);
activity.onOAuthAuthenticationRequest(event);

ArgumentCaptor<Map> mapCaptor = ArgumentCaptor.forClass(Map.class);

verify(lockView, never()).showProgress(true);
verify(customProvider).setParameters(mapCaptor.capture());
Expand Down
35 changes: 31 additions & 4 deletions lib/src/test/java/com/auth0/android/lock/WebProviderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,37 @@ public void shouldStart() throws Exception {
webProvider.start(activity, "my-connection", callback, 123);
}

@Test
public void shouldStartWithCustomAudience() throws Exception {
Auth0 account = new Auth0("clientId", "domain.auth0.com");
account.setOIDCConformant(true);
Options options = new Options();
options.setAccount(account);

options.setUseBrowser(true);
options.withAudience("https://me.auth0.com/myapi");

AuthCallback callback = mock(AuthCallback.class);
WebProvider webProvider = new WebProvider(options);
Activity activity = spy(Robolectric.buildActivity(Activity.class)
.create()
.start()
.resume()
.get());

webProvider.start(activity, "my-connection", callback, 123);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(activity).startActivity(intentCaptor.capture());

Intent intent = intentCaptor.getValue();
assertThat(intent, is(notNullValue()));
assertThat(intent.getData(), hasHost("domain.auth0.com"));
assertThat(intent.getData(), hasParamWithValue("client_id", "clientId"));
assertThat(intent.getData(), hasParamWithValue("connection", "my-connection"));
assertThat(intent.getData(), hasParamWithValue("audience", "https://me.auth0.com/myapi"));
assertThat(intent, hasAction(Intent.ACTION_VIEW));
}

@Test
public void shouldStartBrowserWithOptions() throws Exception {
Auth0 account = new Auth0("clientId", "domain.auth0.com");
Expand All @@ -68,7 +99,6 @@ public void shouldStartBrowserWithOptions() throws Exception {
options.withScope("email profile photos");
options.withConnectionScope("my-connection", "the connection scope");
options.setUseBrowser(true);
options.withAudience("https://me.auth0.com/myapi");
options.withScheme("auth0");

AuthCallback callback = mock(AuthCallback.class);
Expand All @@ -95,7 +125,6 @@ public void shouldStartBrowserWithOptions() throws Exception {
assertThat(intent.getData(), hasParamWithValue("custom-param-2", "value-2"));
assertThat(intent.getData(), hasParamWithValue("scope", "email profile photos"));
assertThat(intent.getData(), hasParamWithValue("connection_scope", "the connection scope"));
assertThat(intent.getData(), hasParamWithValue("audience", "https://me.auth0.com/myapi"));
assertThat(intent, hasAction(Intent.ACTION_VIEW));
}

Expand All @@ -112,7 +141,6 @@ public void shouldStartWebViewWithOptions() throws Exception {
options.withScope("email profile photos");
options.withConnectionScope("my-connection", "the connection scope");
options.setUseBrowser(false);
options.withAudience("https://me.auth0.com/myapi");
options.withScheme("auth0");

AuthCallback callback = mock(AuthCallback.class);
Expand All @@ -139,7 +167,6 @@ public void shouldStartWebViewWithOptions() throws Exception {
assertThat(intent.getData(), hasParamWithValue("custom-param-2", "value-2"));
assertThat(intent.getData(), hasParamWithValue("scope", "email profile photos"));
assertThat(intent.getData(), hasParamWithValue("connection_scope", "the connection scope"));
assertThat(intent.getData(), hasParamWithValue("audience", "https://me.auth0.com/myapi"));
assertThat(intent, hasComponent(WebAuthActivity.class.getName()));
}

Expand Down

0 comments on commit f3533a2

Please sign in to comment.