Skip to content

Commit

Permalink
Remove unnecessary isBrowserRequired in errors (#2009)
Browse files Browse the repository at this point in the history
The existing native auth logic returns BrowserRequired error in more
cases, compared to where the API can actually return it.
This PR removes the unnecessary isBrowserRequired from errors for
certain scenarios (sign in after sign up, resend code)

Partner PR in common repo:
AzureAD/microsoft-authentication-library-common-for-android#2298
  • Loading branch information
GBakolas authored Jan 25, 2024
1 parent 3e6354a commit 1747b16
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -79,7 +85,14 @@ open class Error(
open var exception: Exception? = null,
open val errorCodes: List<Int>? = 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
}

/**
Expand All @@ -105,7 +118,7 @@ class SubmitCodeError(
override val errorCodes: List<Int>? = 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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ResetPasswordError(
override val correlationId: String,
override val errorCodes: List<Int>? = 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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ open class SignInError(
override val correlationId: String,
override val errorCodes: List<Int>? = 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
Expand All @@ -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<Int>? = null,
override var exception: Exception? = null
): SignInResult, Error(errorType = null, error = error, errorMessage= errorMessage, correlationId = correlationId, errorCodes = errorCodes, exception = exception)
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ open class SignUpError (
override val correlationId: String,
override val errorCodes: List<Int>? = 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

Expand Down Expand Up @@ -109,7 +109,7 @@ class SignUpSubmitPasswordError (
override val errorCodes: List<Int>? = 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
}
Expand All @@ -132,7 +132,7 @@ class SignUpSubmitAttributesError (
override val correlationId: String,
override val errorCodes: List<Int>? = 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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
)
}
}
Expand Down Expand Up @@ -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
)
}
}
Expand Down Expand Up @@ -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",
Expand All @@ -497,27 +481,6 @@ class SignInContinuationState(
val rawCommandResult = CommandDispatcher.submitSilentReturningFuture(command).get()

return@withContext when (val result = rawCommandResult.checkAndWrapCommandResultType<SignInWithContinuationTokenCommandResult>()) {
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)
Expand All @@ -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
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

/**
Expand Down
Loading

0 comments on commit 1747b16

Please sign in to comment.