Skip to content

Commit

Permalink
Merge branch 'trunk' into maxime/use-gravatar-sdk-dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
maxme committed Feb 28, 2024
2 parents eba47d8 + 0e9b52c commit 26604ab
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 152 deletions.
12 changes: 11 additions & 1 deletion WordPressLoginFlow/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ repositories {
}

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlin {
jvmToolchain(17)
}

namespace "org.wordpress.android.login"

kotlinOptions {
Expand Down Expand Up @@ -72,7 +81,8 @@ dependencies {
implementation "com.github.bumptech.glide:glide:$glideVersion"
kapt "com.github.bumptech.glide:compiler:$glideVersion"

implementation "com.google.android.gms:play-services-fido:$fidoVersion"
implementation "androidx.credentials:credentials:$credentialManagerVersion"
implementation "androidx.credentials:credentials-play-services-auth:$credentialManagerVersion"

// Dagger
implementation "com.google.dagger:dagger:$daggerVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
Expand All @@ -15,9 +14,6 @@
import android.widget.EditText;
import android.widget.TextView;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.IntentSenderRequest;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All @@ -26,8 +22,6 @@
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;

import com.google.android.gms.fido.Fido;
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import org.greenrobot.eventbus.Subscribe;
Expand All @@ -36,7 +30,6 @@
import org.wordpress.android.fluxc.generated.AuthenticationActionBuilder;
import org.wordpress.android.fluxc.store.AccountStore.AuthenticateTwoFactorPayload;
import org.wordpress.android.fluxc.store.AccountStore.AuthenticationErrorType;
import org.wordpress.android.fluxc.store.AccountStore.FinishWebauthnChallengePayload;
import org.wordpress.android.fluxc.store.AccountStore.OnAuthenticationChanged;
import org.wordpress.android.fluxc.store.AccountStore.OnSocialChanged;
import org.wordpress.android.fluxc.store.AccountStore.PushSocialAuthPayload;
Expand All @@ -46,7 +39,8 @@
import org.wordpress.android.fluxc.store.AccountStore.WebauthnChallengeReceived;
import org.wordpress.android.fluxc.store.AccountStore.WebauthnPasskeyAuthenticated;
import org.wordpress.android.login.util.SiteUtils;
import org.wordpress.android.login.webauthn.PasskeyCredentialsHandler;
import org.wordpress.android.login.webauthn.PasskeyRequest;
import org.wordpress.android.login.webauthn.PasskeyRequest.PasskeyRequestData;
import org.wordpress.android.login.widgets.WPLoginInputRow;
import org.wordpress.android.login.widgets.WPLoginInputRow.OnEditorCommitListener;
import org.wordpress.android.util.AppLog;
Expand All @@ -59,7 +53,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static android.app.Activity.RESULT_OK;
import static android.content.Context.CLIPBOARD_SERVICE;

import dagger.android.support.AndroidSupportInjection;
Expand Down Expand Up @@ -125,8 +118,6 @@ public class Login2FaFragment extends LoginBaseFormFragment<LoginListener> imple
private boolean mIsSocialLoginConnect;
private boolean mSentSmsCode;
private List<SupportedAuthTypes> mSupportedAuthTypes;
@Nullable private PasskeyCredentialsHandler mPasskeyCredentialsHandler = null;
@Nullable private ActivityResultLauncher<IntentSenderRequest> mResultLauncher = null;

public static Login2FaFragment newInstance(String emailAddress, String password) {
Login2FaFragment fragment = new Login2FaFragment();
Expand Down Expand Up @@ -297,16 +288,6 @@ public void onCreate(Bundle savedInstanceState) {
mPhoneNumber = savedInstanceState.getString(KEY_SMS_NUMBER);
mSentSmsCode = savedInstanceState.getBoolean(KEY_SMS_SENT);
}

mResultLauncher =
registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(),
result -> {
if (result.getResultCode() == RESULT_OK && result.getData() != null) {
onCredentialsResultAvailable(result.getData());
} else {
handleWebauthnError();
}
});
}

@Override
Expand Down Expand Up @@ -620,60 +601,49 @@ private void doAuthWithSecurityKeyAction() {
.newStartSecurityKeyChallengeAction(payload));
}

@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onWebauthnChallengeReceived(WebauthnChallengeReceived event) {
if (event.isError()) {
endProgress();
handleAuthError(event.error.type, getString(R.string.login_error_security_key));
handleWebauthnError(event.error.type, getString(R.string.login_error_security_key));
return;
}
mPasskeyCredentialsHandler = new PasskeyCredentialsHandler(

PasskeyRequestData passkeyRequestData = new PasskeyRequestData(
event.mUserId,
event.mChallengeInfo
event.getWebauthnNonce(),
event.mJsonResponse.toString()
);
mPasskeyCredentialsHandler.createIntentSender(
requireContext(),
intent -> {
if (mResultLauncher != null) {
mResultLauncher.launch(intent);
}
});
}

private void onCredentialsResultAvailable(@NonNull Intent resultData) {
if (resultData.hasExtra(Fido.FIDO2_KEY_CREDENTIAL_EXTRA)) {
byte[] credentialBytes = resultData.getByteArrayExtra(Fido.FIDO2_KEY_CREDENTIAL_EXTRA);
if (credentialBytes == null || mPasskeyCredentialsHandler == null) {
handleWebauthnError();
return;
}

PublicKeyCredential credentials =
PublicKeyCredential.deserializeFromBytes(credentialBytes);
FinishWebauthnChallengePayload payload =
mPasskeyCredentialsHandler.onCredentialsAvailable(credentials);
mDispatcher.dispatch(
AuthenticationActionBuilder.newFinishSecurityKeyChallengeAction(payload));
}
PasskeyRequest.create(
requireContext(),
passkeyRequestData,
result -> {
mDispatcher.dispatch(result);
return null;
},
error -> {
String errorMessage = getString(R.string.login_error_security_key);
handleWebauthnError(AuthenticationErrorType.WEBAUTHN_FAILED, errorMessage);
return null;
}
);
}

@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSecurityKeyCheckFinished(WebauthnPasskeyAuthenticated event) {
if (event.isError()) {
endProgress();
handleAuthError(event.error.type, getString(R.string.login_error_security_key));
handleWebauthnError(event.error.type, getString(R.string.login_error_security_key));
return;
}
mAnalyticsListener.trackLoginSecurityKeySuccess();
doFinishLogin();
}

private void handleWebauthnError() {
String errorMessage = getString(R.string.login_error_security_key);
private void handleWebauthnError(AuthenticationErrorType errorType, String errorMessage) {
endProgress();
handleAuthError(AuthenticationErrorType.WEBAUTHN_FAILED, errorMessage);
handleAuthError(errorType, errorMessage);
getParentFragmentManager().popBackStack();
}

@NonNull private ArrayList<SupportedAuthTypes> handleSupportedAuthTypesParameter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.wordpress.android.fluxc.store.AccountStore.AuthenticatePayload;
import org.wordpress.android.fluxc.store.AccountStore.AuthenticationErrorType;
import org.wordpress.android.fluxc.store.AccountStore.OnAuthenticationChanged;
import org.wordpress.android.fluxc.store.AccountStore.OnTwoFactorAuthStarted;
import org.wordpress.android.fluxc.store.SiteStore.OnProfileFetched;
import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged;
import org.wordpress.android.fluxc.store.SiteStore.RefreshSitesXMLRPCPayload;
Expand Down Expand Up @@ -504,13 +505,7 @@ private void handleAuthError(AuthenticationErrorType error, XmlRpcErrorType xmlR
case INVALID_TOKEN:
case AUTHORIZATION_REQUIRED:
case NEEDS_2FA:
if (mIsWpcom) {
if (mLoginListener != null) {
mLoginListener.needs2fa(mRequestedUsername, mRequestedPassword);
}
} else {
showError("2FA not supported for self-hosted sites. Please use an app-password.");
}
handle2fa();
break;
default:
AppLog.e(T.NUX, "Server response: " + errorMessage);
Expand All @@ -521,8 +516,26 @@ private void handleAuthError(AuthenticationErrorType error, XmlRpcErrorType xmlR
}
}

private void handle2fa() {
if (mIsWpcom) {
if (mLoginListener != null) {
mLoginListener.needs2fa(mRequestedUsername, mRequestedPassword);
}
} else {
showError("2FA not supported for self-hosted sites. Please use an app-password.");
}
}

// OnChanged events

@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onTwoFactorAuthStarted(OnTwoFactorAuthStarted event) {
mLoginStarted = false;
handle2fa();
endProgress();
}

@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAuthenticationChanged(OnAuthenticationChanged event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.Toolbar
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import dagger.android.support.AndroidSupportInjection
import org.wordpress.android.login.util.AvatarHelper.AvatarRequestListener
import org.wordpress.android.login.util.AvatarHelper.loadAvatarFromUrl
import javax.inject.Inject

class SignupConfirmationFragment : Fragment() {
class SignupConfirmationFragment : Fragment(), MenuProvider {
private var mLoginListener: LoginListener? = null

private var mEmail: String? = null
Expand Down Expand Up @@ -76,8 +78,6 @@ class SignupConfirmationFragment : Fragment() {
mPhotoUrl = it.getString(ARG_SOCIAL_PHOTO_URL)
mService = it.getString(ARG_SOCIAL_SERVICE)
}
@Suppress("DEPRECATION")
setHasOptionsMenu(true)
}

override fun onCreateView(
Expand Down Expand Up @@ -116,6 +116,8 @@ class SignupConfirmationFragment : Fragment() {
if (savedInstanceState == null) {
mAnalyticsListener.trackSocialSignupConfirmationViewed()
}

requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
}

@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
Expand All @@ -130,11 +132,11 @@ class SignupConfirmationFragment : Fragment() {
mLoginListener = null
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_login, menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
override fun onMenuItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.help) {
mAnalyticsListener.trackShowHelpClick()
if (mLoginListener != null) {
Expand Down

This file was deleted.

Loading

0 comments on commit 26604ab

Please sign in to comment.