/auth/src/main/java/com/firebase/ui/auth/viewmodel/email/WelcomeBackPasswordHandler.java
https://github.com/firebase/FirebaseUI-Android · Java · 155 lines · 118 code · 13 blank · 24 comment · 12 complexity · e7c0134e7328bccd84deb1cc77e9a65f MD5 · raw file
- package com.firebase.ui.auth.viewmodel.email;
- import android.app.Application;
- import com.firebase.ui.auth.AuthUI;
- import com.firebase.ui.auth.IdpResponse;
- import com.firebase.ui.auth.data.model.Resource;
- import com.firebase.ui.auth.data.model.User;
- import com.firebase.ui.auth.data.remote.ProfileMerger;
- import com.firebase.ui.auth.util.FirebaseAuthError;
- import com.firebase.ui.auth.util.data.AuthOperationManager;
- import com.firebase.ui.auth.util.data.TaskFailureLogger;
- import com.firebase.ui.auth.viewmodel.SignInViewModelBase;
- import com.google.android.gms.tasks.Continuation;
- import com.google.android.gms.tasks.OnCompleteListener;
- import com.google.android.gms.tasks.OnFailureListener;
- import com.google.android.gms.tasks.OnSuccessListener;
- import com.google.android.gms.tasks.Task;
- import com.google.android.gms.tasks.Tasks;
- import com.google.firebase.auth.AuthCredential;
- import com.google.firebase.auth.AuthResult;
- import com.google.firebase.auth.EmailAuthProvider;
- import com.google.firebase.auth.FirebaseAuth;
- import com.google.firebase.auth.FirebaseAuthException;
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.annotation.RestrictTo;
- /**
- * Handles the logic for {@link com.firebase.ui.auth.ui.email.WelcomeBackPasswordPrompt} including
- * signing in with email and password, linking other credentials, and saving credentials to
- * SmartLock.
- */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- public class WelcomeBackPasswordHandler extends SignInViewModelBase {
- private static final String TAG = "WBPasswordHandler";
- private String mPendingPassword;
- public WelcomeBackPasswordHandler(Application application) {
- super(application);
- }
- /**
- * Kick off the sign-in process.
- */
- public void startSignIn(@NonNull final String email,
- @NonNull final String password,
- @NonNull final IdpResponse inputResponse,
- @Nullable final AuthCredential credential) {
- setResult(Resource.<IdpResponse>forLoading());
- // Store the password before signing in so it can be used for later credential building
- mPendingPassword = password;
- // Build appropriate IDP response based on inputs
- final IdpResponse outputResponse;
- if (credential == null) {
- // New credential for the email provider
- outputResponse = new IdpResponse.Builder(
- new User.Builder(EmailAuthProvider.PROVIDER_ID, email).build())
- .build();
- } else {
- // New credential for an IDP (Phone or Social)
- outputResponse = new IdpResponse.Builder(inputResponse.getUser())
- .setPendingCredential(inputResponse.getCredentialForLinking())
- .setToken(inputResponse.getIdpToken())
- .setSecret(inputResponse.getIdpSecret())
- .build();
- }
- final AuthOperationManager authOperationManager = AuthOperationManager.getInstance();
- if (authOperationManager.canUpgradeAnonymous(getAuth(), getArguments())) {
- final AuthCredential credToValidate = EmailAuthProvider.getCredential(email, password);
- // Check to see if we need to link (for social providers with the same email)
- if (AuthUI.SOCIAL_PROVIDERS.contains(inputResponse.getProviderType())) {
- // Add the provider to the same account before triggering a merge failure.
- authOperationManager.safeLink(credToValidate, credential, getArguments())
- .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
- @Override
- public void onSuccess(AuthResult result) {
- handleMergeFailure(credToValidate);
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(@NonNull Exception e) {
- setResult(Resource.<IdpResponse>forFailure(e));
- }
- });
- } else {
- // The user has not tried to log in with a federated IDP containing the same email.
- // In this case, we just need to verify that the credential they provided is valid.
- // No linking is done for non-federated IDPs.
- // A merge failure occurs because the account exists and the user is anonymous.
- authOperationManager.validateCredential(credToValidate, getArguments())
- .addOnCompleteListener(
- new OnCompleteListener<AuthResult>() {
- @Override
- public void onComplete(@NonNull Task<AuthResult> task) {
- if (task.isSuccessful()) {
- handleMergeFailure(credToValidate);
- } else {
- setResult(Resource.<IdpResponse>forFailure(task.getException()));
- }
- }
- });
- }
- } else {
- // Kick off the flow including signing in, linking accounts, and saving with SmartLock
- getAuth().signInWithEmailAndPassword(email, password)
- .continueWithTask(new Continuation<AuthResult, Task<AuthResult>>() {
- @Override
- public Task<AuthResult> then(@NonNull Task<AuthResult> task) throws Exception {
- // Forward task failure by asking for result
- AuthResult result = task.getResult(Exception.class);
- // Task succeeded, link user if necessary
- if (credential == null) {
- return Tasks.forResult(result);
- } else {
- return result.getUser()
- .linkWithCredential(credential)
- .continueWithTask(new ProfileMerger(outputResponse))
- .addOnFailureListener(new TaskFailureLogger(TAG,
- "linkWithCredential+merge failed."));
- }
- }
- })
- .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
- @Override
- public void onSuccess(AuthResult result) {
- handleSuccess(outputResponse, result);
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- @Override
- public void onFailure(@NonNull Exception e) {
- setResult(Resource.<IdpResponse>forFailure(e));
- }
- })
- .addOnFailureListener(
- new TaskFailureLogger(TAG, "signInWithEmailAndPassword failed."));
- }
- }
- /**
- * Get the most recent pending password.
- */
- public String getPendingPassword() {
- return mPendingPassword;
- }
- }