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

Send custom audience on login/signIn if is OIDC conformant #387

Merged
merged 3 commits into from
Jan 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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