diff --git a/common b/common index aabddb9d7e..d40040d7c8 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit aabddb9d7e6319a31c2f58979bd85127f09217ed +Subproject commit d40040d7c8fb6f2a73f4825ca2e9893b68ea28b2 diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/Error.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/Error.kt index dd3131ccbc..a6ae3aec2e 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/Error.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/Error.kt @@ -24,11 +24,17 @@ package com.microsoft.identity.nativeauth.statemachine.errors import com.microsoft.identity.nativeauth.statemachine.results.ResetPasswordResendCodeResult +import com.microsoft.identity.nativeauth.statemachine.results.ResetPasswordResult +import com.microsoft.identity.nativeauth.statemachine.results.ResetPasswordStartResult import com.microsoft.identity.nativeauth.statemachine.results.ResetPasswordSubmitCodeResult import com.microsoft.identity.nativeauth.statemachine.results.SignInResendCodeResult +import com.microsoft.identity.nativeauth.statemachine.results.SignInResult import com.microsoft.identity.nativeauth.statemachine.results.SignInSubmitCodeResult import com.microsoft.identity.nativeauth.statemachine.results.SignUpResendCodeResult +import com.microsoft.identity.nativeauth.statemachine.results.SignUpResult +import com.microsoft.identity.nativeauth.statemachine.results.SignUpSubmitAttributesResult import com.microsoft.identity.nativeauth.statemachine.results.SignUpSubmitCodeResult +import com.microsoft.identity.nativeauth.statemachine.results.SignUpSubmitPasswordResult /** * ErrorTypes class holds the possible error type values that are shared between the errors @@ -79,7 +85,14 @@ open class Error( open var exception: Exception? = null, open val errorCodes: List? = null ) { - fun isBrowserRequired(): Boolean = this.errorType == ErrorTypes.BROWSER_REQUIRED +} + +/** + * BrowserRequiredError error is an interface for all errors that could require a browser redirection in Native Auth. + * All error classes that can potentially return a browser redirection must implement this interface. + */ +interface BrowserRequiredError { + fun isBrowserRequired(): Boolean = (this as Error).errorType == ErrorTypes.BROWSER_REQUIRED } /** @@ -105,7 +118,7 @@ class SubmitCodeError( override val errorCodes: List? = null, val subError: String? = null, override var exception: Exception? = null -): SignInSubmitCodeResult, SignUpSubmitCodeResult, ResetPasswordSubmitCodeResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) +): BrowserRequiredError, SignInSubmitCodeResult, SignUpSubmitCodeResult, ResetPasswordSubmitCodeResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isInvalidCode(): Boolean = this.errorType == ErrorTypes.INVALID_CODE } diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/ResetPasswordErrors.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/ResetPasswordErrors.kt index 43f3c1fbea..65deb50a4c 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/ResetPasswordErrors.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/ResetPasswordErrors.kt @@ -58,7 +58,7 @@ class ResetPasswordError( override val correlationId: String, override val errorCodes: List? = null, override var exception: Exception? = null -): ResetPasswordResult, ResetPasswordStartResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { +): ResetPasswordResult, ResetPasswordStartResult, BrowserRequiredError, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isUserNotFound() : Boolean = this.errorType == ErrorTypes.USER_NOT_FOUND } diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignInErrors.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignInErrors.kt index 8c9b2d8bea..be7b26d9f9 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignInErrors.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignInErrors.kt @@ -35,7 +35,7 @@ open class SignInError( override val correlationId: String, override val errorCodes: List? = null, override var exception: Exception? = null -): SignInResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { +): SignInResult, BrowserRequiredError, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isUserNotFound(): Boolean = this.errorType == ErrorTypes.USER_NOT_FOUND fun isInvalidCredentials(): Boolean = this.errorType == SignInErrorTypes.INVALID_CREDENTIALS @@ -62,3 +62,23 @@ class SignInSubmitPasswordError( ): SignInSubmitPasswordResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isInvalidCredentials(): Boolean = this.errorType == SignInErrorTypes.INVALID_CREDENTIALS } + +/** + * Sign in continuation error. The error has no utility methods + * and must be treated as unexpected. This error is produced by + * [com.microsoft.identity.nativeauth.INativeAuthPublicClientApplication.signIn] + * @param errorType the error type value of the error that occurred + * @param error the error returned by the authentication server. + * @param errorMessage the error message returned by the authentication server. + * @param correlationId a unique identifier for the request that can help in diagnostics. + * @param errorCodes a list of specific error codes returned by the authentication server. + * @param exception an internal unexpected exception that happened. + */ +open class SignInContinuationError( + override val error: String? = null, + override val errorMessage: String?, + // TODO: The parameter type of correlationId should be changed to String? after PBI https://identitydivision.visualstudio.com/Engineering/_workitems/edit/2774018 is completed + override val correlationId: String, + override val errorCodes: List? = null, + override var exception: Exception? = null +): SignInResult, Error(errorType = null, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignUpErrors.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignUpErrors.kt index 344acd45c7..a70da0c387 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignUpErrors.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/errors/SignUpErrors.kt @@ -76,7 +76,7 @@ open class SignUpError ( override val correlationId: String, override val errorCodes: List? = null, override var exception: Exception? = null -): SignUpResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { +): SignUpResult, BrowserRequiredError, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isUserAlreadyExists(): Boolean = this.errorType == SignUpErrorTypes.USER_ALREADY_EXISTS @@ -109,7 +109,7 @@ class SignUpSubmitPasswordError ( override val errorCodes: List? = null, val subError: String? = null, override var exception: Exception? = null -): SignUpSubmitPasswordResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { +): SignUpSubmitPasswordResult, BrowserRequiredError, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isInvalidPassword(): Boolean = this.errorType == ErrorTypes.INVALID_PASSWORD } @@ -132,7 +132,7 @@ class SignUpSubmitAttributesError ( override val correlationId: String, override val errorCodes: List? = null, override var exception: Exception? = null -): SignUpSubmitAttributesResult, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { +): SignUpSubmitAttributesResult, BrowserRequiredError, Error(errorType = errorType, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception) { fun isInvalidAttributes(): Boolean = this.errorType == SignUpErrorTypes.INVALID_ATTRIBUTES } diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/ResetPasswordStates.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/ResetPasswordStates.kt index 382f666ddb..3babd1fe6f 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/ResetPasswordStates.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/ResetPasswordStates.kt @@ -233,25 +233,17 @@ class ResetPasswordCodeRequiredState internal constructor( ) } - is INativeAuthCommandResult.Redirect -> { - ResendCodeError( - errorType = ErrorTypes.BROWSER_REQUIRED, - error = result.error, - errorMessage = result.errorDescription, - correlationId = result.correlationId - ) - } - + is INativeAuthCommandResult.Redirect, is INativeAuthCommandResult.UnknownError -> { Logger.warn( TAG, "Resend code received unexpected result: $result" ) ResendCodeError( - errorMessage = result.errorDescription, - error = result.error, - correlationId = result.correlationId, - exception = result.exception + errorMessage = (result as INativeAuthCommandResult.Error).errorDescription, + error = (result as INativeAuthCommandResult.Error).error, + correlationId = (result as INativeAuthCommandResult.Error).correlationId, + exception = (result as INativeAuthCommandResult.UnknownError).exception ) } } diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignInStates.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignInStates.kt index af8ce5abce..18a034572e 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignInStates.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignInStates.kt @@ -53,6 +53,7 @@ import com.microsoft.identity.common.java.util.StringUtil import com.microsoft.identity.common.java.nativeauth.util.checkAndWrapCommandResultType import com.microsoft.identity.nativeauth.statemachine.errors.ErrorTypes import com.microsoft.identity.nativeauth.statemachine.errors.ResendCodeError +import com.microsoft.identity.nativeauth.statemachine.errors.SignInContinuationError import com.microsoft.identity.nativeauth.statemachine.errors.SignInError import com.microsoft.identity.nativeauth.statemachine.errors.SignInErrorTypes import com.microsoft.identity.nativeauth.statemachine.errors.SignInSubmitPasswordError @@ -244,26 +245,17 @@ class SignInCodeRequiredState internal constructor( ) } - is INativeAuthCommandResult.Redirect -> { - ResendCodeError( - errorType = ErrorTypes.BROWSER_REQUIRED, - error = result.error, - errorMessage = result.errorDescription, - correlationId = result.correlationId - ) - } - - is INativeAuthCommandResult.UnknownError -> { + is INativeAuthCommandResult.Redirect, is INativeAuthCommandResult.UnknownError -> { Logger.warn( TAG, "Resend code received unexpected result: $result" ) ResendCodeError( - errorMessage = result.errorDescription, - error = result.error, - correlationId = result.correlationId, - errorCodes = result.errorCodes, - exception = result.exception + errorMessage = (result as INativeAuthCommandResult.Error).errorDescription, + error = (result as INativeAuthCommandResult.Error).error, + correlationId = (result as INativeAuthCommandResult.Error).correlationId, + errorCodes = (result as INativeAuthCommandResult.Error).errorCodes, + exception = (result as INativeAuthCommandResult.UnknownError).exception ) } } @@ -379,25 +371,17 @@ class SignInPasswordRequiredState( ) ) } - is INativeAuthCommandResult.Redirect -> { - SignInSubmitPasswordError( - errorType = ErrorTypes.BROWSER_REQUIRED, - error = result.error, - errorMessage = result.errorDescription, - correlationId = result.correlationId - ) - } - is INativeAuthCommandResult.UnknownError -> { + is INativeAuthCommandResult.Redirect, is INativeAuthCommandResult.UnknownError -> { Logger.warn( TAG, "Submit password received unexpected result: $result" ) SignInSubmitPasswordError( - errorMessage = result.errorDescription, - error = result.error, - correlationId = result.correlationId, - errorCodes = result.errorCodes, - exception = result.exception + errorMessage = (result as INativeAuthCommandResult.Error).errorDescription, + error = (result as INativeAuthCommandResult.Error).error, + correlationId = (result as INativeAuthCommandResult.Error).correlationId, + errorCodes = (result as INativeAuthCommandResult.Error).errorCodes, + exception = (result as INativeAuthCommandResult.UnknownError).exception ) } } @@ -473,7 +457,7 @@ class SignInContinuationState( TAG, "Sign in after sign up received unexpected result: continuationToken was null" ) - return@withContext SignInError( + return@withContext SignInContinuationError( errorMessage = "Sign In is not available through this state, please use the standalone sign in methods (signInWithCode or signInWithPassword).", error = "invalid_state", correlationId = "UNSET", @@ -497,27 +481,6 @@ class SignInContinuationState( val rawCommandResult = CommandDispatcher.submitSilentReturningFuture(command).get() return@withContext when (val result = rawCommandResult.checkAndWrapCommandResultType()) { - is SignInCommandResult.CodeRequired -> { - SignInResult.CodeRequired( - nextState = SignInCodeRequiredState( - continuationToken = result.continuationToken, - scopes = scopes, - config = config - ), - codeLength = result.codeLength, - sentTo = result.challengeTargetLabel, - channel = result.challengeChannel - ) - } - is SignInCommandResult.PasswordRequired -> { - SignInResult.PasswordRequired( - nextState = SignInPasswordRequiredState( - continuationToken = result.continuationToken, - scopes = scopes, - config = config - ) - ) - } is SignInCommandResult.Complete -> { val authenticationResult = AuthenticationResultAdapter.adapt(result.authenticationResult) @@ -528,25 +491,18 @@ class SignInContinuationState( ) ) } - is INativeAuthCommandResult.Redirect -> { - SignInError( - errorType = ErrorTypes.BROWSER_REQUIRED, - error = result.error, - errorMessage = result.errorDescription, - correlationId = result.correlationId - ) - } + is INativeAuthCommandResult.Redirect, is INativeAuthCommandResult.UnknownError -> { Logger.warn( TAG, "Sign in after sign up received unexpected result: $result" ) - SignInError( - errorMessage = result.errorDescription, - error = result.error, - correlationId = result.correlationId, - errorCodes = result.errorCodes, - exception = result.exception + SignInContinuationError( + errorMessage = (result as INativeAuthCommandResult.Error).errorDescription, + error = (result as INativeAuthCommandResult.Error).error, + correlationId = (result as INativeAuthCommandResult.Error).correlationId, + errorCodes = (result as INativeAuthCommandResult.Error).errorCodes, + exception = (result as INativeAuthCommandResult.UnknownError).exception ) } } diff --git a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignUpStates.kt b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignUpStates.kt index bafd6069b8..ff6e232cf6 100644 --- a/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignUpStates.kt +++ b/msal/src/main/java/com/microsoft/identity/nativeauth/statemachine/states/SignUpStates.kt @@ -273,25 +273,16 @@ class SignUpCodeRequiredState internal constructor( ) } - is INativeAuthCommandResult.Redirect -> { - ResendCodeError( - errorType = ErrorTypes.BROWSER_REQUIRED, - error = result.error, - errorMessage = result.errorDescription, - correlationId = result.correlationId - ) - } - - is INativeAuthCommandResult.UnknownError -> { + is INativeAuthCommandResult.Redirect, is INativeAuthCommandResult.UnknownError -> { Logger.warn( TAG, "Resend code received unexpected result: $result" ) ResendCodeError( - errorMessage = result.errorDescription, - error = result.error, - correlationId = result.correlationId, - exception = result.exception + errorMessage = (result as INativeAuthCommandResult.Error).errorDescription, + error = (result as INativeAuthCommandResult.Error).error, + correlationId = (result as INativeAuthCommandResult.Error).correlationId, + exception = (result as INativeAuthCommandResult.UnknownError).exception ) } } diff --git a/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationJavaTest.java b/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationJavaTest.java index 8493da8cdb..c385b28d02 100644 --- a/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationJavaTest.java +++ b/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationJavaTest.java @@ -37,6 +37,7 @@ import com.microsoft.identity.nativeauth.statemachine.errors.GetAccessTokenError; import com.microsoft.identity.nativeauth.statemachine.errors.ResetPasswordError; import com.microsoft.identity.nativeauth.statemachine.errors.ResetPasswordSubmitPasswordError; +import com.microsoft.identity.nativeauth.statemachine.errors.SignInContinuationError; import com.microsoft.identity.nativeauth.statemachine.errors.SignInError; import com.microsoft.identity.nativeauth.statemachine.errors.SignUpError; import com.microsoft.identity.nativeauth.statemachine.errors.SignUpSubmitAttributesError; @@ -1065,12 +1066,7 @@ public void onError(@NonNull BaseException exception) { state.signIn(null, callback); SignInResult result = resultFuture.get(10, TimeUnit.SECONDS); - assertTrue(result instanceof SignInError); - - SignInError error = (SignInError)result; - - assertFalse(error.isUserNotFound()); - assertFalse(error.isBrowserRequired()); + assertTrue(result instanceof SignInContinuationError); } /** diff --git a/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationKotlinTest.kt b/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationKotlinTest.kt index d5e623fd5d..0a280ac3cd 100644 --- a/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationKotlinTest.kt +++ b/msal/src/test/java/com/microsoft/identity/nativeauth/NativeAuthPublicClientApplicationKotlinTest.kt @@ -59,6 +59,7 @@ import com.microsoft.identity.common.java.nativeauth.BuildValues import com.microsoft.identity.common.java.util.ResultFuture import com.microsoft.identity.internal.testutils.TestUtils import com.microsoft.identity.nativeauth.statemachine.states.SignInContinuationState +import com.microsoft.identity.nativeauth.statemachine.errors.SignInContinuationError import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest @@ -412,8 +413,7 @@ class NativeAuthPublicClientApplicationKotlinTest : PublicClientApplicationAbstr val config = mock() val continuationTokenState = SignInContinuationState(continuationToken = null, username = username, config = config) val result = continuationTokenState.signIn(scopes = null) - assertTrue(result is SignInError) - assertTrue((result as SignInError).errorType == null) + assertTrue(result is SignInContinuationError) } /**