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

Merge login lib changes from Woo and implement new interface methods #10787

Merged
merged 9 commits into from
Nov 25, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,12 @@ public void newUserCreatedButErrored(String email, String password) {
// LoginListener implementation methods

@Override
public void gotWpcomEmail(String email) {
public void gotWpcomEmail(String email, boolean verifyEmail) {
initSmartLockIfNotFinished(false);
if (getLoginMode() != LoginMode.WPCOM_LOGIN_DEEPLINK && getLoginMode() != LoginMode.SHARE_INTENT) {
LoginMagicLinkRequestFragment loginMagicLinkRequestFragment = LoginMagicLinkRequestFragment.newInstance(
email, AuthEmailPayloadScheme.WORDPRESS, mIsJetpackConnect,
mJetpackConnectSource != null ? mJetpackConnectSource.toString() : null);
mJetpackConnectSource != null ? mJetpackConnectSource.toString() : null, verifyEmail);
slideInFragment(loginMagicLinkRequestFragment, true, LoginMagicLinkRequestFragment.TAG);
} else {
LoginEmailPasswordFragment loginEmailPasswordFragment =
Expand Down Expand Up @@ -836,4 +836,28 @@ public AndroidInjector<Fragment> supportFragmentInjector() {
boolean hasJetpack) {
// Not used in WordPress app
}

@Override public void helpHandleDiscoveryError(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the annotations should be on separate lines

String siteAddress,
String endpointAddress,
String username,
String password,
String userAvatarUrl,
int errorMessage) {
// Not used in WordPress app
}

@Override public void helpNoJetpackScreen(
String siteAddress,
String endpointAddress,
String username,
String password,
String userAvatarUrl,
Boolean checkJetpackAvailability) {
// Not used in WordPress app
}

@Override public void loginViaSiteCredentials(String inputSiteAddress) {
// Not used in WordPress app
}
}
8 changes: 8 additions & 0 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2270,6 +2270,14 @@
<string name="enter_wpcom_or_jetpack_site">Please enter a WordPress.com or Jetpack-connected self-hosted WordPress site</string>
<string name="enter_wordpress_site">The website at this address is not a WordPress site. For us to connect to it, the site must have WordPress installed.</string>
<string name="login_need_help_finding_connected_email">Need help finding the email you connected with?</string>
<string name="send_verification_email">Send verification email</string>
<string name="enter_credentials_for_site">Log in with your %1$s site credentials</string>
<string name="enter_site_credentials_instead">Log in with site credentials</string>
<string name="login_site_credentials_magic_link_label">Almost there! We just need to verify your Jetpack connected email address &lt;b>%1$s&lt;/b></string>
<string name="login_discovery_error_xmlrpc">We were unable to access the &lt;b>XMLRPC file&lt;/b> on your site. You will need to reach out to your host to resolve this.</string>
<string name="login_discovery_error_http_auth">We were unable to access your site because it requires &lt;b>HTTP Authentication&lt;/b>. You will need to reach out to your host to resolve this.</string>
<string name="login_discovery_error_ssl">We were unable to access your site because of a problem with the &lt;b>SSL Certificate&lt;/b>. You will need to reach out to your host to resolve this.</string>
<string name="login_discovery_error_generic">We were unable to access your site. You will need to reach out to your host to resolve this.</string>
<!-- Screen titles -->
<string name="email_address_login_title">Email address login</string>
<string name="site_address_login_title">Site address login</string>
Expand Down
2 changes: 1 addition & 1 deletion libs/login/WordPressLoginFlow/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ dependencies {
exclude group: "org.wordpress", module: "utils"
}
} else {
implementation("com.github.wordpress-mobile.WordPress-FluxC-Android:fluxc:9f07b031646dd3e6021d4b8e0a35647c9109ff27") {
implementation("com.github.wordpress-mobile.WordPress-FluxC-Android:fluxc:1.5.1-beta-4") {
exclude group: "com.android.support"
exclude group: "org.wordpress", module: "utils"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.wordpress.android.login;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.wordpress.android.fluxc.generated.AuthenticationActionBuilder;
import org.wordpress.android.fluxc.network.discovery.SelfHostedEndpointFinder.DiscoveryError;
import org.wordpress.android.fluxc.store.AccountStore.OnDiscoveryResponse;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.NetworkUtils;

public abstract class LoginBaseDiscoveryFragment extends LoginBaseFormFragment<LoginListener> {
LoginBaseDiscoveryListener mLoginBaseDiscoveryListener;

public interface LoginBaseDiscoveryListener {
String getRequestedSiteAddress();
void handleWpComDiscoveryError(String failedEndpoint);
void handleDiscoverySuccess(String endpointAddress);
void handleDiscoveryError(DiscoveryError error, String failedEndpoint);
}

@Override
public void onDetach() {
super.onDetach();
mLoginBaseDiscoveryListener = null;
}

void initiateDiscovery() {
if (!NetworkUtils.checkConnection(getActivity())) {
return;
}

// Start the discovery process
mDispatcher.dispatch(AuthenticationActionBuilder.newDiscoverEndpointAction(
mLoginBaseDiscoveryListener.getRequestedSiteAddress()));
}

@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDiscoverySucceeded(OnDiscoveryResponse event) {
// hold the URL in a variable to use below otherwise it gets cleared up by endProgress
// bail if user canceled
String mRequestedSiteAddress = mLoginBaseDiscoveryListener.getRequestedSiteAddress();
if (mRequestedSiteAddress == null) {
return;
}

if (!isAdded()) {
return;
}

if (event.isError()) {
if (isInProgress()) {
endProgress();
}

mAnalyticsListener.trackLoginFailed(event.getClass().getSimpleName(),
event.error.name(), event.error.toString());

AppLog.e(T.API, "onDiscoveryResponse has error: " + event.error.name()
+ " - " + event.error.toString());
handleDiscoveryError(event.error, event.failedEndpoint);
return;
}

AppLog.i(T.NUX, "Discovery succeeded, endpoint: " + event.xmlRpcEndpoint);
mLoginBaseDiscoveryListener.handleDiscoverySuccess(event.xmlRpcEndpoint);
}

private void handleDiscoveryError(DiscoveryError error, final String failedEndpoint) {
if (error == DiscoveryError.WORDPRESS_COM_SITE) {
mLoginBaseDiscoveryListener.handleWpComDiscoveryError(failedEndpoint);
} else {
mLoginBaseDiscoveryListener.handleDiscoveryError(error, failedEndpoint);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ protected void endProgress() {

if (mProgressDialog != null) {
mProgressDialog.cancel();
mProgressDialog.setOnCancelListener(null);
mProgressDialog = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public class LoginEmailFragment extends LoginBaseFormFragment<LoginListener> imp
private static final int GOOGLE_API_CLIENT_ID = 1002;
private static final int EMAIL_CREDENTIALS_REQUEST_CODE = 25100;

private static final String ARG_HIDE_LOGIN_BY_SITE_OPTION = "ARG_HIDE_LOGIN_BY_SITE_OPTION";
private static final String ARG_LOGIN_SITE_URL = "ARG_LOGIN_SITE_URL";

public static final String TAG = "login_email_fragment_tag";
Expand All @@ -83,13 +82,11 @@ public class LoginEmailFragment extends LoginBaseFormFragment<LoginListener> imp
protected WPLoginInputRow mEmailInput;
protected boolean mHasDismissedEmailHints;
protected boolean mIsDisplayingEmailHints;
protected boolean mHideLoginWithSiteOption;
protected String mLoginSiteUrl;

public static LoginEmailFragment newInstance(Boolean hideLoginWithSiteOption, String url) {
public static LoginEmailFragment newInstance(String url) {
LoginEmailFragment fragment = new LoginEmailFragment();
Bundle args = new Bundle();
args.putBoolean(ARG_HIDE_LOGIN_BY_SITE_OPTION, hideLoginWithSiteOption);
args.putString(ARG_LOGIN_SITE_URL, url);
fragment.setArguments(args);
return fragment;
Expand Down Expand Up @@ -180,30 +177,32 @@ public void onClick(View view) {
});

LinearLayout siteLoginButton = rootView.findViewById(R.id.login_site_button);
if (mHideLoginWithSiteOption) {
siteLoginButton.setVisibility(View.GONE);
} else {
siteLoginButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (mLoginListener != null) {
if (mLoginListener.getLoginMode() == LoginMode.JETPACK_STATS) {
mLoginListener.loginViaWpcomUsernameInstead();
} else {
mLoginListener.loginViaSiteAddress();
}
siteLoginButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (mLoginListener != null) {
LoginMode loginMode = mLoginListener.getLoginMode();
if (loginMode == LoginMode.JETPACK_STATS) {
mLoginListener.loginViaWpcomUsernameInstead();
} else if (loginMode == LoginMode.WOO_LOGIN_MODE) {
mLoginListener.loginViaSiteCredentials(mLoginSiteUrl);
} else {
mLoginListener.loginViaSiteAddress();
}
}
});
}
}
});

ImageView siteLoginButtonIcon = rootView.findViewById(R.id.login_site_button_icon);
TextView siteLoginButtonText = rootView.findViewById(R.id.login_site_button_text);

switch (mLoginListener.getLoginMode()) {
case WOO_LOGIN_MODE:
siteLoginButtonIcon.setImageResource(R.drawable.ic_domains_grey_24dp);
siteLoginButtonText.setText(R.string.enter_site_credentials_instead);
break;
case FULL:
case WPCOM_LOGIN_ONLY:
case WOO_LOGIN_MODE:
case SHARE_INTENT:
siteLoginButtonIcon.setImageResource(R.drawable.ic_domains_grey_24dp);
siteLoginButtonText.setText(R.string.enter_site_address_instead);
Expand Down Expand Up @@ -277,7 +276,6 @@ public void onCreate(Bundle savedInstanceState) {

Bundle args = getArguments();
if (args != null) {
mHideLoginWithSiteOption = args.getBoolean(ARG_HIDE_LOGIN_BY_SITE_OPTION, false);
mLoginSiteUrl = args.getString(ARG_LOGIN_SITE_URL, "");
}
}
Expand Down Expand Up @@ -434,7 +432,7 @@ public void onAvailabilityChecked(OnAvailabilityChecked event) {
showEmailError(R.string.email_not_registered_wpcom);
} else if (mLoginListener != null) {
ActivityUtils.hideKeyboardForced(mEmailInput);
mLoginListener.gotWpcomEmail(event.value);
mLoginListener.gotWpcomEmail(event.value, false);
}
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ interface SelfSignedSSLCallback {
LoginMode getLoginMode();

// Login Email input callbacks
void gotWpcomEmail(String email);
void gotWpcomEmail(String email, boolean verifyEmail);
void loginViaSiteAddress();
void loginViaSocialAccount(String email, String idToken, String service, boolean isPasswordRequired);
void loggedInViaSocialAccount(ArrayList<Integer> oldSiteIds, boolean doLoginUpdate);
void loginViaWpcomUsernameInstead();
void loginViaSiteCredentials(String inputSiteAddress);
void helpEmailScreen(String email);
void helpSocialEmailScreen(String email);
void addGoogleLoginFragment();
Expand Down Expand Up @@ -59,6 +60,10 @@ void saveCredentialsInSmartLock(@Nullable String username, @Nullable String pass
@NonNull String displayName, @Nullable Uri profilePicture);
void loggedInViaUsernamePassword(ArrayList<Integer> oldSitesIds);
void helpUsernamePassword(String url, String username, boolean isWpcom);
void helpNoJetpackScreen(String siteAddress, String endpointAddress, String username,
String password, String userAvatarUrl, Boolean checkJetpackAvailability);
void helpHandleDiscoveryError(String siteAddress, String endpointAddress, String username,
String password, String userAvatarUrl, int errorMessage);

// Login 2FA screen callbacks
void help2FaScreen(String email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
Expand Down Expand Up @@ -56,6 +59,7 @@ public class LoginMagicLinkRequestFragment extends Fragment {
private static final String ARG_MAGIC_LINK_SCHEME = "ARG_MAGIC_LINK_SCHEME";
private static final String ARG_IS_JETPACK_CONNECT = "ARG_IS_JETPACK_CONNECT";
private static final String ARG_JETPACK_CONNECT_SOURCE = "ARG_JETPACK_CONNECT_SOURCE";
private static final String ARG_VERIFY_MAGIC_LINK_EMAIL = "ARG_VERIFY_MAGIC_LINK_EMAIL";

private static final String ERROR_KEY = "error";

Expand All @@ -71,18 +75,21 @@ public class LoginMagicLinkRequestFragment extends Fragment {

private boolean mInProgress;
private boolean mIsJetpackConnect;
private boolean mVerifyMagicLinkEmail;

@Inject protected Dispatcher mDispatcher;

@Inject protected LoginAnalyticsListener mAnalyticsListener;
public static LoginMagicLinkRequestFragment newInstance(String email, AuthEmailPayloadScheme scheme,
boolean isJetpackConnect, String jetpackConnectSource) {
boolean isJetpackConnect, String jetpackConnectSource,
boolean verifyEmail) {
LoginMagicLinkRequestFragment fragment = new LoginMagicLinkRequestFragment();
Bundle args = new Bundle();
args.putString(ARG_EMAIL_ADDRESS, email);
args.putSerializable(ARG_MAGIC_LINK_SCHEME, scheme);
args.putBoolean(ARG_IS_JETPACK_CONNECT, isJetpackConnect);
args.putString(ARG_JETPACK_CONNECT_SOURCE, jetpackConnectSource);
args.putBoolean(ARG_VERIFY_MAGIC_LINK_EMAIL, verifyEmail);
fragment.setArguments(args);
return fragment;
}
Expand All @@ -107,6 +114,7 @@ public void onCreate(Bundle savedInstanceState) {
mMagicLinkScheme = (AuthEmailPayloadScheme) getArguments().getSerializable(ARG_MAGIC_LINK_SCHEME);
mIsJetpackConnect = getArguments().getBoolean(ARG_IS_JETPACK_CONNECT);
mJetpackConnectSource = getArguments().getString(ARG_JETPACK_CONNECT_SOURCE);
mVerifyMagicLinkEmail = getArguments().getBoolean(ARG_VERIFY_MAGIC_LINK_EMAIL);
}

setHasOptionsMenu(true);
Expand Down Expand Up @@ -143,28 +151,49 @@ public void onClick(View v) {

mAvatarProgressBar = view.findViewById(R.id.avatar_progress);
ImageView avatarView = view.findViewById(R.id.gravatar);
Glide.with(this)
.load(GravatarUtils.gravatarFromEmail(mEmail,
getContext().getResources().getDimensionPixelSize(R.dimen.avatar_sz_login)))
.apply(RequestOptions.circleCropTransform())
.apply(RequestOptions.placeholderOf(R.drawable.ic_gridicons_user_circle_100dp))
.apply(RequestOptions.errorOf(R.drawable.ic_gridicons_user_circle_100dp))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object o, Target<Drawable> target,
boolean b) {
mAvatarProgressBar.setVisibility(View.GONE);
return false;
}

@Override
public boolean onResourceReady(Drawable drawable, Object o, Target<Drawable> target,
DataSource dataSource, boolean b) {
mAvatarProgressBar.setVisibility(View.GONE);
return false;
}
})
.into(avatarView);
// Design changes added to the Woo Magic link sign-in
if (mVerifyMagicLinkEmail) {
View avatarContainerView = view.findViewById(R.id.avatar_container);

LayoutParams lp = avatarContainerView.getLayoutParams();
lp.width = getContext().getResources().getDimensionPixelSize(R.dimen.magic_link_sent_illustration_sz);
lp.height = getContext().getResources().getDimensionPixelSize(R.dimen.magic_link_sent_illustration_sz);
avatarContainerView.setLayoutParams(lp);

mAvatarProgressBar.setVisibility(View.GONE);
avatarView.setImageResource(R.drawable.login_email_alert);

TextView labelTextView = view.findViewById(R.id.label);
labelTextView.setText(Html.fromHtml(String.format(getResources().getString(
R.string.login_site_credentials_magic_link_label), mEmail)));

mRequestMagicLinkButton.setText(getString(R.string.send_verification_email));
} else {
Glide.with(this)
.load(GravatarUtils.gravatarFromEmail(mEmail,
getContext().getResources().getDimensionPixelSize(R.dimen.avatar_sz_login)))
.apply(RequestOptions.circleCropTransform())
.apply(RequestOptions.placeholderOf(R.drawable.ic_gridicons_user_circle_100dp))
.apply(RequestOptions.errorOf(R.drawable.ic_gridicons_user_circle_100dp))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object o, Target<Drawable> target,
boolean b) {
mAvatarProgressBar.setVisibility(View.GONE);
return false;
}

@Override
public boolean onResourceReady(Drawable drawable, Object o, Target<Drawable> target,
DataSource dataSource, boolean b) {
mAvatarProgressBar.setVisibility(View.GONE);
return false;
}
})
.into(avatarView);
}

return view;
}

Expand Down
Loading