From 7cde5a1fae9e9d1bf2b035b738a446b58f027f70 Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Thu, 13 Oct 2016 17:37:04 -0300 Subject: [PATCH 1/2] allow to specify a custom connection scope for each connection in the builder --- .../java/com/auth0/android/lock/Lock.java | 19 +++++++++++ .../com/auth0/android/lock/LockActivity.java | 1 + .../auth0/android/lock/PasswordlessLock.java | 19 +++++++++++ .../lock/PasswordlessLockActivity.java | 2 ++ .../lock/internal/configuration/Options.java | 28 ++++++++++++++++ .../internal/configuration/OptionsTest.java | 33 +++++++++++++++---- 6 files changed, 96 insertions(+), 6 deletions(-) diff --git a/lib/src/main/java/com/auth0/android/lock/Lock.java b/lib/src/main/java/com/auth0/android/lock/Lock.java index 3856ce5ab..314e145cd 100644 --- a/lib/src/main/java/com/auth0/android/lock/Lock.java +++ b/lib/src/main/java/com/auth0/android/lock/Lock.java @@ -479,6 +479,25 @@ public Builder setMustAcceptTerms(boolean mustAcceptTerms) { return this; } + /** + * Sets the Connection Scope to request when performing an Authentication with the given Connection. + * + * @param connectionName to which specify the scopes. + * @param scope recognized by this specific authentication provider. + * @return the current builder instance + */ + public Builder withConnectionScope(@NonNull String connectionName, @NonNull String... scope) { + StringBuilder sb = new StringBuilder(); + for (String s : scope) { + sb.append(s.trim()).append(","); + } + if (sb.length() > 0) { + sb.deleteCharAt(sb.length() - 1); + options.withConnectionScope(connectionName, sb.toString()); + } + return this; + } + private List removeDuplicatedKeys(List customFields) { int originalSize = customFields.size(); final List withoutDuplicates = new ArrayList<>(); diff --git a/lib/src/main/java/com/auth0/android/lock/LockActivity.java b/lib/src/main/java/com/auth0/android/lock/LockActivity.java index ed5060a0f..9a02033c7 100644 --- a/lib/src/main/java/com/auth0/android/lock/LockActivity.java +++ b/lib/src/main/java/com/auth0/android/lock/LockActivity.java @@ -332,6 +332,7 @@ public void onOAuthAuthenticationRequest(OAuthLoginEvent event) { Log.d(TAG, "Couldn't find an specific provider, using the default: " + WebAuthProvider.class.getSimpleName()); WebAuthProvider.init(options.getAccount()) .useBrowser(options.useBrowser()) + .withConnectionScope(options.getConnectionsScope().get(connection)) .withParameters(options.getAuthenticationParameters()) .withConnection(connection) .start(this, authProviderCallback, WEB_AUTH_REQUEST_CODE); diff --git a/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java b/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java index d98dc40b1..fefe8ca28 100644 --- a/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java +++ b/lib/src/main/java/com/auth0/android/lock/PasswordlessLock.java @@ -340,5 +340,24 @@ public Builder withAuthHandlers(@NonNull AuthHandler... handlers) { AuthResolver.setAuthHandlers(Arrays.asList(handlers)); return this; } + + /** + * Sets the Connection Scope to request when performing an Authentication with the given Connection. + * + * @param connectionName to which specify the scopes. + * @param scope recognized by this specific authentication provider. + * @return the current builder instance + */ + public Builder withConnectionScope(@NonNull String connectionName, @NonNull String... scope) { + StringBuilder sb = new StringBuilder(); + for (String s : scope) { + sb.append(s.trim()).append(","); + } + if (sb.length() > 0) { + sb.deleteCharAt(sb.length() - 1); + options.withConnectionScope(connectionName, sb.toString()); + } + return this; + } } } diff --git a/lib/src/main/java/com/auth0/android/lock/PasswordlessLockActivity.java b/lib/src/main/java/com/auth0/android/lock/PasswordlessLockActivity.java index f700916ef..b336bb678 100644 --- a/lib/src/main/java/com/auth0/android/lock/PasswordlessLockActivity.java +++ b/lib/src/main/java/com/auth0/android/lock/PasswordlessLockActivity.java @@ -73,6 +73,7 @@ import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; +import java.util.HashMap; import java.util.List; public class PasswordlessLockActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback { @@ -480,6 +481,7 @@ public void onOAuthAuthenticationRequest(OAuthLoginEvent event) { Log.d(TAG, "Couldn't find an specific provider, using the default: " + WebAuthProvider.class.getSimpleName()); WebAuthProvider.init(options.getAccount()) .useBrowser(options.useBrowser()) + .withConnectionScope(options.getConnectionsScope().get(event.getConnection())) .withParameters(options.getAuthenticationParameters()) .withConnection(event.getConnection()) .start(this, authProviderCallback, WEB_AUTH_REQUEST_CODE); diff --git a/lib/src/main/java/com/auth0/android/lock/internal/configuration/Options.java b/lib/src/main/java/com/auth0/android/lock/internal/configuration/Options.java index 21e10ec90..2b7c5bd5b 100644 --- a/lib/src/main/java/com/auth0/android/lock/internal/configuration/Options.java +++ b/lib/src/main/java/com/auth0/android/lock/internal/configuration/Options.java @@ -54,6 +54,7 @@ public class Options implements Parcelable { private static final int WITHOUT_DATA = 0x00; private static final int HAS_DATA = 0x01; private static final String KEY_AUTHENTICATION_PARAMETERS = "authenticationParameters"; + private static final String KEY_CONNECTIONS_SCOPE = "connectionsScope"; private static final String SCOPE_KEY = "scope"; private static final String DEVICE_KEY = "device"; private static final String SCOPE_OFFLINE_ACCESS = "offline_access"; @@ -76,6 +77,7 @@ public class Options implements Parcelable { private List enterpriseConnectionsUsingWebForm; private HashMap authStyles; private HashMap authenticationParameters; + private HashMap connectionsScope; private List customFields; private int initialScreen; private Theme theme; @@ -94,6 +96,7 @@ public Options() { usePKCE = true; authenticationParameters = new HashMap<>(); authStyles = new HashMap<>(); + connectionsScope = new HashMap<>(); customFields = new ArrayList<>(); theme = Theme.newBuilder().build(); } @@ -149,6 +152,13 @@ protected Options(Parcel in) { } else { authStyles = null; } + if (in.readByte() == HAS_DATA) { + // FIXME this is something to improve + Bundle mapBundle = in.readBundle(); + connectionsScope = (HashMap) mapBundle.getSerializable(KEY_CONNECTIONS_SCOPE); + } else { + connectionsScope = null; + } if (in.readByte() == HAS_DATA) { customFields = new ArrayList<>(); in.readList(customFields, CustomField.class.getClassLoader()); @@ -210,6 +220,15 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeList(new ArrayList<>(authStyles.keySet())); dest.writeList(new ArrayList<>(authStyles.values())); } + if (connectionsScope == null) { + dest.writeByte((byte) (WITHOUT_DATA)); + } else { + dest.writeByte((byte) (HAS_DATA)); + // FIXME this is something to improve + Bundle mapBundle = new Bundle(); + mapBundle.putSerializable(KEY_CONNECTIONS_SCOPE, connectionsScope); + dest.writeBundle(mapBundle); + } if (customFields == null) { dest.writeByte((byte) (WITHOUT_DATA)); } else { @@ -438,4 +457,13 @@ public void setUseLabeledSubmitButton(boolean useLabeledSubmitButton) { public boolean useLabeledSubmitButton() { return useLabeledSubmitButton; } + + public void withConnectionScope(@NonNull String connectionName, @NonNull String scope) { + connectionsScope.put(connectionName, scope); + } + + @NonNull + public Map getConnectionsScope() { + return connectionsScope; + } } \ No newline at end of file diff --git a/lib/src/test/java/com/auth0/android/lock/internal/configuration/OptionsTest.java b/lib/src/test/java/com/auth0/android/lock/internal/configuration/OptionsTest.java index 985d1058b..2b610848f 100644 --- a/lib/src/test/java/com/auth0/android/lock/internal/configuration/OptionsTest.java +++ b/lib/src/test/java/com/auth0/android/lock/internal/configuration/OptionsTest.java @@ -12,6 +12,7 @@ import com.auth0.android.lock.utils.CustomField; import com.auth0.android.lock.utils.CustomField.FieldType; +import org.hamcrest.collection.IsCollectionWithSize; import org.hamcrest.collection.IsMapContaining; import org.junit.Before; import org.junit.Rule; @@ -32,6 +33,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.collection.IsMapContaining.hasEntry; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -476,6 +478,25 @@ public void shouldSetAuthenticationParameters() throws Exception { assertThat(options.getAuthenticationParameters(), is(equalTo(parceledOptions.getAuthenticationParameters()))); } + @Test + public void shouldSetConnectionScope() throws Exception { + options.withConnectionScope("some_connection", "scope for some connection"); + options.withConnectionScope("other_connection", "scope for other connection"); + + Parcel parcel = Parcel.obtain(); + options.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + Options parceledOptions = Options.CREATOR.createFromParcel(parcel); + assertThat(options.getConnectionsScope(), is(equalTo(parceledOptions.getConnectionsScope()))); + assertThat(options.getConnectionsScope().size(), is(2)); + assertThat(options.getConnectionsScope(), hasEntry("some_connection", "scope for some connection")); + assertThat(options.getConnectionsScope(), hasEntry("other_connection", "scope for other connection")); + assertThat(parceledOptions.getConnectionsScope().size(), is(2)); + assertThat(parceledOptions.getConnectionsScope(), hasEntry("some_connection", "scope for some connection")); + assertThat(parceledOptions.getConnectionsScope(), hasEntry("other_connection", "scope for other connection")); + } + @SuppressWarnings("ResourceType") @Test public void shouldAddAuthStyles() throws Exception { @@ -489,13 +510,13 @@ public void shouldAddAuthStyles() throws Exception { Options parceledOptions = Options.CREATOR.createFromParcel(parcel); assertThat(options.getAuthStyles().size(), is(3)); - assertThat(options.getAuthStyles(), is(IsMapContaining.hasEntry("firstConnection", 1))); - assertThat(options.getAuthStyles(), is(IsMapContaining.hasEntry("secondConnection", 2))); - assertThat(options.getAuthStyles(), is(IsMapContaining.hasEntry("thirdConnection", 3))); + assertThat(options.getAuthStyles(), is(hasEntry("firstConnection", 1))); + assertThat(options.getAuthStyles(), is(hasEntry("secondConnection", 2))); + assertThat(options.getAuthStyles(), is(hasEntry("thirdConnection", 3))); assertThat(parceledOptions.getAuthStyles().size(), is(3)); - assertThat(parceledOptions.getAuthStyles(), is(IsMapContaining.hasEntry("firstConnection", 1))); - assertThat(parceledOptions.getAuthStyles(), is(IsMapContaining.hasEntry("secondConnection", 2))); - assertThat(parceledOptions.getAuthStyles(), is(IsMapContaining.hasEntry("thirdConnection", 3))); + assertThat(parceledOptions.getAuthStyles(), is(hasEntry("firstConnection", 1))); + assertThat(parceledOptions.getAuthStyles(), is(hasEntry("secondConnection", 2))); + assertThat(parceledOptions.getAuthStyles(), is(hasEntry("thirdConnection", 3))); } @Test From 9d2201a3d44202f6a97404960014d2820764d64d Mon Sep 17 00:00:00 2001 From: Luciano Balmaceda Date: Fri, 14 Oct 2016 18:36:07 -0300 Subject: [PATCH 2/2] use latest auth0.android library --- lib/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.gradle b/lib/build.gradle index 9ce487f27..e8fe6b691 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -31,7 +31,7 @@ dependencies { compile 'com.android.support:design:24.2.1' compile 'com.google.code.gson:gson:2.6.2' compile 'com.squareup:otto:1.3.8' - compile 'com.auth0.android:auth0:1.0.0' + compile 'com.auth0.android:auth0:1.1.0' testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-library:1.3' testCompile 'org.robolectric:robolectric:3.1.2'