Search in sources :

Example 11 with FirebaseUiException

use of com.firebase.ui.auth.FirebaseUiException in project FirebaseUI-Android by firebase.

the class EmailLinkSignInHandler method startSignIn.

public void startSignIn() {
    setResult(Resource.forLoading());
    String link = getArguments().emailLink;
    if (!getAuth().isSignInWithEmailLink(link)) {
        setResult(Resource.forFailure(new FirebaseUiException(ErrorCodes.INVALID_EMAIL_LINK_ERROR)));
        return;
    }
    final EmailLinkPersistenceManager persistenceManager = EmailLinkPersistenceManager.getInstance();
    SessionRecord sessionRecord = persistenceManager.retrieveSessionRecord(getApplication());
    EmailLinkParser parser = new EmailLinkParser(link);
    String sessionIdFromLink = parser.getSessionId();
    String anonymousUserIdFromLink = parser.getAnonymousUserId();
    String oobCodeFromLink = parser.getOobCode();
    String providerIdFromLink = parser.getProviderId();
    boolean forceSameDevice = parser.getForceSameDeviceBit();
    if (isDifferentDeviceFlow(sessionRecord, sessionIdFromLink)) {
        if (TextUtils.isEmpty(sessionIdFromLink)) {
            // There should always be a valid session ID in the link
            setResult(Resource.forFailure(new FirebaseUiException(ErrorCodes.INVALID_EMAIL_LINK_ERROR)));
            return;
        }
        if (forceSameDevice || !TextUtils.isEmpty(anonymousUserIdFromLink)) {
            // In both cases, the link was meant to be completed on the same device.
            // For anonymous user upgrade, we don't support the cross device flow.
            setResult(Resource.forFailure(new FirebaseUiException(ErrorCodes.EMAIL_LINK_WRONG_DEVICE_ERROR)));
            return;
        }
        // If we have no SessionRecord/there is a session ID mismatch, this means that we were
        // not the ones to send the link. The only way forward is to prompt the user for their
        // email before continuing the flow. We should only do that after validating the link.
        determineDifferentDeviceErrorFlowAndFinish(oobCodeFromLink, providerIdFromLink);
        return;
    }
    if (anonymousUserIdFromLink != null) {
        // Same device flow, need to ensure uids match
        if (getAuth().getCurrentUser() == null || (getAuth().getCurrentUser().isAnonymous() && !anonymousUserIdFromLink.equals(getAuth().getCurrentUser().getUid()))) {
            setResult(Resource.forFailure(new FirebaseUiException(ErrorCodes.EMAIL_LINK_DIFFERENT_ANONYMOUS_USER_ERROR)));
            return;
        }
    }
    finishSignIn(sessionRecord);
}
Also used : EmailLinkPersistenceManager(com.firebase.ui.auth.util.data.EmailLinkPersistenceManager) FirebaseUiException(com.firebase.ui.auth.FirebaseUiException) EmailLinkParser(com.firebase.ui.auth.util.data.EmailLinkParser) SessionRecord(com.firebase.ui.auth.util.data.EmailLinkPersistenceManager.SessionRecord)

Example 12 with FirebaseUiException

use of com.firebase.ui.auth.FirebaseUiException in project FirebaseUI-Android by firebase.

the class EmailLinkSignInHandler method finishSignIn.

private void finishSignIn(@NonNull String email, @Nullable IdpResponse response) {
    if (TextUtils.isEmpty(email)) {
        setResult(Resource.forFailure(new FirebaseUiException(ErrorCodes.EMAIL_MISMATCH_ERROR)));
        return;
    }
    final AuthOperationManager authOperationManager = AuthOperationManager.getInstance();
    final EmailLinkPersistenceManager persistenceManager = EmailLinkPersistenceManager.getInstance();
    String link = getArguments().emailLink;
    if (response == null) {
        handleNormalFlow(authOperationManager, persistenceManager, email, link);
    } else {
        handleLinkingFlow(authOperationManager, persistenceManager, response, link);
    }
}
Also used : AuthOperationManager(com.firebase.ui.auth.util.data.AuthOperationManager) EmailLinkPersistenceManager(com.firebase.ui.auth.util.data.EmailLinkPersistenceManager) FirebaseUiException(com.firebase.ui.auth.FirebaseUiException)

Example 13 with FirebaseUiException

use of com.firebase.ui.auth.FirebaseUiException in project FirebaseUI-Android by firebase.

the class LinkingSocialProviderResponseHandler method startSignIn.

public void startSignIn(@NonNull final IdpResponse response) {
    if (!response.isSuccessful()) {
        setResult(Resource.forFailure(response.getError()));
        return;
    }
    if (isInvalidProvider(response.getProviderType())) {
        throw new IllegalStateException("This handler cannot be used to link email or phone providers.");
    }
    if (mEmail != null && !mEmail.equals(response.getEmail())) {
        setResult(Resource.forFailure(new FirebaseUiException(ErrorCodes.EMAIL_MISMATCH_ERROR)));
        return;
    }
    setResult(Resource.forLoading());
    // return a credential.
    if (isGenericIdpLinkingFlow(response.getProviderType())) {
        getAuth().getCurrentUser().linkWithCredential(mRequestedSignInCredential).addOnSuccessListener(authResult -> handleSuccess(response, authResult)).addOnFailureListener(e -> Resource.<IdpResponse>forFailure(e));
        return;
    }
    final AuthOperationManager authOperationManager = AuthOperationManager.getInstance();
    final AuthCredential credential = ProviderUtils.getAuthCredential(response);
    if (authOperationManager.canUpgradeAnonymous(getAuth(), getArguments())) {
        if (mRequestedSignInCredential == null) {
            // The user has provided a valid credential by signing in with a federated
            // idp. linkWithCredential will fail because the user is anonymous and the account
            // exists (we're in the welcome back flow).
            // We know that they are signing in with the same IDP because requestSignInCredential
            // is null.
            // We just need to have the developer handle the merge failure.
            handleMergeFailure(credential);
        } else {
            // The user has logged in with an IDP that has the same email with another IDP
            // present on the account.
            // These IDPs belong to the same account - they must be linked, but we can't lose
            // our anonymous user session
            authOperationManager.safeLink(credential, mRequestedSignInCredential, getArguments()).addOnSuccessListener(result -> handleMergeFailure(credential)).addOnFailureListener(e -> setResult(Resource.forFailure(e)));
        }
    } else {
        getAuth().signInWithCredential(credential).continueWithTask(task -> {
            final AuthResult result = task.getResult();
            if (mRequestedSignInCredential == null) {
                return Tasks.forResult(result);
            } else {
                return result.getUser().linkWithCredential(mRequestedSignInCredential).continueWith(task1 -> {
                    if (task1.isSuccessful()) {
                        return task1.getResult();
                    } else {
                        // to backtrack so we just ignore any errors.
                        return result;
                    }
                });
            }
        }).addOnCompleteListener(task -> {
            if (task.isSuccessful()) {
                handleSuccess(response, task.getResult());
            } else {
                setResult(Resource.forFailure(task.getException()));
            }
        });
    }
}
Also used : ProviderUtils(com.firebase.ui.auth.util.data.ProviderUtils) NonNull(androidx.annotation.NonNull) SignInViewModelBase(com.firebase.ui.auth.viewmodel.SignInViewModelBase) TextUtils(android.text.TextUtils) Resource(com.firebase.ui.auth.data.model.Resource) AuthOperationManager(com.firebase.ui.auth.util.data.AuthOperationManager) OnCompleteListener(com.google.android.gms.tasks.OnCompleteListener) PhoneAuthProvider(com.google.firebase.auth.PhoneAuthProvider) Task(com.google.android.gms.tasks.Task) AuthCredential(com.google.firebase.auth.AuthCredential) Tasks(com.google.android.gms.tasks.Tasks) Nullable(androidx.annotation.Nullable) RestrictTo(androidx.annotation.RestrictTo) EmailAuthProvider(com.google.firebase.auth.EmailAuthProvider) Application(android.app.Application) OnFailureListener(com.google.android.gms.tasks.OnFailureListener) FirebaseUiException(com.firebase.ui.auth.FirebaseUiException) OnSuccessListener(com.google.android.gms.tasks.OnSuccessListener) AuthUI(com.firebase.ui.auth.AuthUI) Continuation(com.google.android.gms.tasks.Continuation) AuthResult(com.google.firebase.auth.AuthResult) ErrorCodes(com.firebase.ui.auth.ErrorCodes) IdpResponse(com.firebase.ui.auth.IdpResponse) AuthCredential(com.google.firebase.auth.AuthCredential) AuthOperationManager(com.firebase.ui.auth.util.data.AuthOperationManager) AuthResult(com.google.firebase.auth.AuthResult) FirebaseUiException(com.firebase.ui.auth.FirebaseUiException)

Example 14 with FirebaseUiException

use of com.firebase.ui.auth.FirebaseUiException in project FirebaseUI-Android by firebase.

the class EmailLinkSignInHandlerTest method testStartSignIn_differentDeviceLinkWithForceSameDeviceTrue_expectWrongDeviceError.

@Test
@SuppressWarnings("all")
public void testStartSignIn_differentDeviceLinkWithForceSameDeviceTrue_expectWrongDeviceError() {
    String differentSessionId = SessionUtils.generateRandomAlphaNumericString(10);
    initializeHandlerWithSessionInfo(differentSessionId, null, null, true);
    mHandler.getOperation().observeForever(mResponseObserver);
    when(mMockAuth.isSignInWithEmailLink(any(String.class))).thenReturn(true);
    mHandler.startSignIn();
    verify(mMockAuth).isSignInWithEmailLink(any(String.class));
    ArgumentCaptor<Resource<IdpResponse>> captor = ArgumentCaptor.forClass(Resource.class);
    InOrder inOrder = inOrder(mResponseObserver);
    inOrder.verify(mResponseObserver).onChanged(argThat(ResourceMatchers.<IdpResponse>isLoading()));
    inOrder.verify(mResponseObserver).onChanged(captor.capture());
    FirebaseUiException exception = (FirebaseUiException) captor.getValue().getException();
    assertThat(exception).isNotNull();
    assertThat(exception.getErrorCode()).isEqualTo(ErrorCodes.EMAIL_LINK_WRONG_DEVICE_ERROR);
}
Also used : InOrder(org.mockito.InOrder) Resource(com.firebase.ui.auth.data.model.Resource) FirebaseUiException(com.firebase.ui.auth.FirebaseUiException) IdpResponse(com.firebase.ui.auth.IdpResponse) Test(org.junit.Test)

Example 15 with FirebaseUiException

use of com.firebase.ui.auth.FirebaseUiException in project FirebaseUI-Android by firebase.

the class EmailLinkSignInHandlerTest method testStartSignIn_differentDeviceLinkWithValidSessionInfo_expectPromptForEmailError.

@Test
@SuppressWarnings("all")
public void testStartSignIn_differentDeviceLinkWithValidSessionInfo_expectPromptForEmailError() {
    String differentSessionId = SessionUtils.generateRandomAlphaNumericString(10);
    initializeHandlerWithSessionInfo(differentSessionId, null, null, false);
    mHandler.getOperation().observeForever(mResponseObserver);
    when(mMockAuth.isSignInWithEmailLink(any(String.class))).thenReturn(true);
    when(mMockAuth.checkActionCode(any(String.class))).thenReturn(AutoCompleteTask.forSuccess(mMockActionCodeResult));
    mHandler.startSignIn();
    verify(mMockAuth).isSignInWithEmailLink(any(String.class));
    verify(mMockAuth).checkActionCode(any(String.class));
    ArgumentCaptor<Resource<IdpResponse>> captor = ArgumentCaptor.forClass(Resource.class);
    InOrder inOrder = inOrder(mResponseObserver);
    inOrder.verify(mResponseObserver).onChanged(argThat(ResourceMatchers.<IdpResponse>isLoading()));
    inOrder.verify(mResponseObserver).onChanged(captor.capture());
    FirebaseUiException exception = (FirebaseUiException) captor.getValue().getException();
    assertThat(exception).isNotNull();
    assertThat(exception.getErrorCode()).isEqualTo(ErrorCodes.EMAIL_LINK_PROMPT_FOR_EMAIL_ERROR);
}
Also used : InOrder(org.mockito.InOrder) Resource(com.firebase.ui.auth.data.model.Resource) FirebaseUiException(com.firebase.ui.auth.FirebaseUiException) IdpResponse(com.firebase.ui.auth.IdpResponse) Test(org.junit.Test)

Aggregations

FirebaseUiException (com.firebase.ui.auth.FirebaseUiException)22 IdpResponse (com.firebase.ui.auth.IdpResponse)16 Resource (com.firebase.ui.auth.data.model.Resource)9 FirebaseAuthAnonymousUpgradeException (com.firebase.ui.auth.FirebaseAuthAnonymousUpgradeException)8 ViewModelProvider (androidx.lifecycle.ViewModelProvider)6 Test (org.junit.Test)6 InOrder (org.mockito.InOrder)6 User (com.firebase.ui.auth.data.model.User)5 Intent (android.content.Intent)4 AuthUI (com.firebase.ui.auth.AuthUI)4 UserCancellationException (com.firebase.ui.auth.data.model.UserCancellationException)4 FirebaseAuthError (com.firebase.ui.auth.util.FirebaseAuthError)4 AuthOperationManager (com.firebase.ui.auth.util.data.AuthOperationManager)4 FirebaseAuthException (com.google.firebase.auth.FirebaseAuthException)4 FirebaseAuthUserCollisionException (com.google.firebase.auth.FirebaseAuthUserCollisionException)4 Application (android.app.Application)3 TextView (android.widget.TextView)3 NonNull (androidx.annotation.NonNull)3 Nullable (androidx.annotation.Nullable)3 RestrictTo (androidx.annotation.RestrictTo)3