Skip to content

Commit

Permalink
Merge pull request #319 from auth0/must-accept-terms
Browse files Browse the repository at this point in the history
Request the user to accept Terms&Policy before Sign Up
  • Loading branch information
hzalaz authored Aug 9, 2016
2 parents 262754e + ff2a19e commit c955cb5
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 162 deletions.
6 changes: 6 additions & 0 deletions lib/src/main/java/com/auth0/android/lock/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public class Configuration {
private boolean allowSignUp;
private boolean allowForgotPassword;
private boolean usernameRequired;
private boolean mustAcceptTerms;
@PasswordStrength
private int passwordPolicy;
private final boolean classicLockAvailable;
Expand Down Expand Up @@ -249,6 +250,7 @@ private void parseLocalOptions(Options options) {
usernameStyle = options.usernameStyle();
socialButtonStyle = options.socialButtonStyle();
loginAfterSignUp = options.loginAfterSignUp();
mustAcceptTerms = options.mustAcceptTerms();

final boolean socialAvailable = !getSocialStrategies().isEmpty();
final boolean dbAvailable = getDefaultDatabaseConnection() != null;
Expand Down Expand Up @@ -413,4 +415,8 @@ public String getTermsURL() {
public String getPrivacyURL() {
return privacyURL;
}

public boolean mustAcceptTerms() {
return mustAcceptTerms;
}
}
25 changes: 14 additions & 11 deletions lib/src/main/java/com/auth0/android/lock/Lock.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.util.Patterns;

import com.auth0.android.Auth0;
import com.auth0.android.authentication.ParameterBuilder;
Expand Down Expand Up @@ -406,11 +405,7 @@ public Builder withSignUpFields(List<CustomField> customFields) {
* @return the current builder instance
*/
public Builder setPrivacyURL(@NonNull String url) {
if (Patterns.WEB_URL.matcher(url).matches()) {
options.setPrivacyURL(url);
} else {
Log.w(TAG, "The given Privacy Policy URL doesn't have a valid URL format. Will default to 'https://auth0.com/privacy'.");
}
options.setPrivacyURL(url);
return this;
}

Expand All @@ -422,11 +417,19 @@ public Builder setPrivacyURL(@NonNull String url) {
* @return the current builder instance
*/
public Builder setTermsURL(@NonNull String url) {
if (Patterns.WEB_URL.matcher(url).matches()) {
options.setTermsURL(url);
} else {
Log.w(TAG, "The given Terms of Service URL doesn't have a valid URL format. Will default to 'https://auth0.com/terms'.");
}
options.setTermsURL(url);
return this;
}

/**
* Prompts the user to accept the Privacy Policy and Terms of Service before signing up.
* The default value is false.
*
* @param mustAcceptTerms whether the user needs to accept the terms before sign up or not.
* @return the current builder instance
*/
public Builder setMustAcceptTerms(boolean mustAcceptTerms) {
options.setMustAcceptTerms(mustAcceptTerms);
return this;
}

Expand Down
25 changes: 19 additions & 6 deletions lib/src/main/java/com/auth0/android/lock/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Options implements Parcelable {
private boolean allowSignUp;
private boolean allowForgotPassword;
private boolean loginAfterSignUp;
private boolean mustAcceptTerms;
private String defaultDatabaseConnection;
private List<String> connections;
private List<String> enterpriseConnectionsUsingWebForm;
Expand Down Expand Up @@ -94,6 +95,7 @@ protected Options(Parcel in) {
allowSignUp = in.readByte() != WITHOUT_DATA;
allowForgotPassword = in.readByte() != WITHOUT_DATA;
loginAfterSignUp = in.readByte() != WITHOUT_DATA;
mustAcceptTerms = in.readByte() != WITHOUT_DATA;
useCodePasswordless = in.readByte() != WITHOUT_DATA;
defaultDatabaseConnection = in.readString();
usernameStyle = in.readInt();
Expand Down Expand Up @@ -144,6 +146,7 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (allowSignUp ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (allowForgotPassword ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (loginAfterSignUp ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (mustAcceptTerms ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (useCodePasswordless ? HAS_DATA : WITHOUT_DATA));
dest.writeString(defaultDatabaseConnection);
dest.writeInt(usernameStyle);
Expand Down Expand Up @@ -353,23 +356,33 @@ public int initialScreen() {
return initialScreen;
}

public void setPrivacyURL(@NonNull String url) {
if (Patterns.WEB_URL.matcher(url).matches()) {
this.privacyURL = url;
public void setPrivacyURL(@NonNull String url) throws IllegalArgumentException {
if (!Patterns.WEB_URL.matcher(url).matches()) {
throw new IllegalArgumentException("The given Policy Privacy URL doesn't have a valid URL format: " + url);
}
this.privacyURL = url;
}

public String getPrivacyURL() {
return privacyURL;
}

public void setTermsURL(@NonNull String url) {
if (Patterns.WEB_URL.matcher(url).matches()) {
this.termsURL = url;
public void setTermsURL(@NonNull String url) throws IllegalArgumentException {
if (!Patterns.WEB_URL.matcher(url).matches()) {
throw new IllegalArgumentException("The given Terms of Service URL doesn't have a valid URL format: " + url);
}
this.termsURL = url;
}

public String getTermsURL() {
return termsURL;
}

public void setMustAcceptTerms(boolean mustAcceptTerms) {
this.mustAcceptTerms = mustAcceptTerms;
}

public boolean mustAcceptTerms() {
return mustAcceptTerms;
}
}
56 changes: 39 additions & 17 deletions lib/src/main/java/com/auth0/android/lock/views/ClassicLockView.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package com.auth0.android.lock.views;

import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
Expand All @@ -51,7 +52,7 @@
import com.auth0.android.lock.views.interfaces.LockWidgetForm;
import com.squareup.otto.Bus;

public class ClassicLockView extends LinearLayout implements View.OnClickListener, LockWidgetForm {
public class ClassicLockView extends LinearLayout implements LockWidgetForm {

private static final String TAG = ClassicLockView.class.getSimpleName();
private static final int FORM_INDEX = 2;
Expand Down Expand Up @@ -114,14 +115,32 @@ private void showContentLayout() {
bottomBanner.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showSignUpTermsDialog();
showSignUpTermsDialog(null);
}
});
bottomBanner.setVisibility(GONE);
addView(bottomBanner, wrapHeightParams);

actionButton = new ActionButton(getContext(), lockTheme);
actionButton.setOnClickListener(this);
actionButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final Object event = subForm != null ? subForm.submitForm() : formLayout.onActionPressed();
if (event == null) {
return;
}
if (!configuration.mustAcceptTerms() || !(event instanceof DatabaseSignUpEvent)) {
bus.post(event);
return;
}
showSignUpTermsDialog(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
bus.post(event);
}
});
}
});
addView(actionButton, wrapHeightParams);

boolean showDatabase = configuration.getDefaultDatabaseConnection() != null;
Expand Down Expand Up @@ -254,15 +273,26 @@ private void showSignUpTerms(boolean show) {
bottomBanner.setVisibility(show ? VISIBLE : GONE);
}

private void showSignUpTermsDialog() {
/**
* Create a dialog to show the Privacy Policy and Terms of Service text.
* If the provided callback it's not null, it will ask for acceptance.
*
* @param acceptCallback the callback to receive the acceptance. Can be null.
*/
private void showSignUpTermsDialog(@Nullable DialogInterface.OnClickListener acceptCallback) {
final String content = String.format(getResources().getString(R.string.com_auth0_lock_sign_up_terms_dialog_message), configuration.getTermsURL(), configuration.getPrivacyURL());
final AlertDialog dialog = new AlertDialog.Builder(getContext())
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
.setTitle(getResources().getString(R.string.com_auth0_lock_sign_up_terms_dialog_title))
.setPositiveButton(android.R.string.ok, null)
.setMessage(Html.fromHtml(content))
.show();
.setPositiveButton(R.string.com_auth0_lock_action_ok, null)
.setMessage(Html.fromHtml(content));
if (acceptCallback != null) {
builder.setNegativeButton(R.string.com_auth0_lock_action_cancel, null)
.setPositiveButton(R.string.com_auth0_lock_action_accept, acceptCallback)
.setCancelable(false);
}

final TextView message = (TextView) dialog.findViewById(android.R.id.message);
//the dialog needs to be shown before we can get it's view.
final TextView message = (TextView) builder.show().findViewById(android.R.id.message);
if (message != null) {
message.setMovementMethod(LinkMovementMethod.getInstance());
}
Expand All @@ -278,14 +308,6 @@ public void onFormSubmit() {
actionButton.callOnClick();
}

@Override
public void onClick(View v) {
Object event = subForm != null ? subForm.submitForm() : formLayout.onActionPressed();
if (event != null) {
bus.post(event);
}
}

@Override
public void showCustomFieldsForm(DatabaseSignUpEvent event) {
addSubForm(new CustomFieldsFormView(this, event.getEmail(), event.getPassword(), event.getUsername()));
Expand Down
3 changes: 3 additions & 0 deletions lib/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@
<string name="com_auth0_lock_action_forgot_password">Don\'t remember your password?</string>
<string name="com_auth0_lock_action_login_with_corporate">Please enter your corporate credentials at %s</string>
<string name="com_auth0_lock_action_retry">Retry</string>
<string name="com_auth0_lock_action_accept">Accept</string>
<string name="com_auth0_lock_action_cancel">Cancel</string>
<string name="com_auth0_lock_action_ok">OK</string>
<string name="com_auth0_lock_single_sign_on_enabled">Single Sign On Enabled</string>
<string name="com_auth0_lock_forms_separator">OR</string>
<string name="com_auth0_lock_passwordless_sms_forms_separator">Otherwise, enter your phone to sign in or create an account</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public void shouldKeepApplicationDefaultsIfOptionsAreNotModified() throws Except
assertThat(configuration.getSocialButtonStyle(), is(equalTo(SocialButtonStyle.UNSPECIFIED)));
assertThat(configuration.hasExtraFields(), is(false));
assertThat(configuration.getPasswordPolicy(), is(PasswordStrength.NONE));
assertThat(configuration.mustAcceptTerms(), is(false));
}

@Test
Expand Down Expand Up @@ -574,6 +575,13 @@ public void shouldHaveCustomTermsOfServiceURL() throws Exception {
assertThat(configuration.getTermsURL(), is(equalTo("https://google.com/terms")));
}

@Test
public void shouldHaveMustAcceptTermsEnabled() throws Exception {
options.setMustAcceptTerms(true);
configuration = new Configuration(application, options);
assertThat(configuration.mustAcceptTerms(), is(true));
}

private Configuration unfilteredConfig() {
return new Configuration(application, options);
}
Expand Down
Loading

0 comments on commit c955cb5

Please sign in to comment.