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

Request the user to accept Terms&Policy before Sign Up #319

Merged
merged 2 commits into from
Aug 9, 2016
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
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