From 389106f40065229246aace1b3e57a4801cb92ad6 Mon Sep 17 00:00:00 2001 From: pedro romero vargas <76129899+p3dr0rv@users.noreply.github.com> Date: Tue, 16 Jan 2024 22:43:47 -0800 Subject: [PATCH] isQrPinAvailable API (#2219) ## Why? To determine if QR + PIN authorization is available for MDM devices, Teams app will call this API. if the result is true: Teams will show a button to login using QR + PIN, if the result is false: Teams will not show this button. ## How does this API works? The QR + PIN feature will be configured by the administrator through app configuration policies for managed Android Enterprise devices. https://learn.microsoft.com/en-us/mem/intune/apps/app-configuration-policies-use-android Where the administrator can enable/disable this type of authorization for all managed devices, by seating this key "isQrPinAvailable" to true in the Authenticator app. On Android we have 3 apps which can be the broker, Authenticator, CP (Company Portal) and LTW (Link to Windows). which makes things extremely complex. To keep the configuration simple for the tenant's administrator, we propose to use the managed configurations of the Authenticator app to read/set the admin flag. Meaning that authenticator app must be installed on Android devices to use the QR + PIN feature. ![qrpinapi drawio2](https://github.com/AzureAD/microsoft-authentication-library-common-for-android/assets/76129899/fdc414af-b66b-40b8-a03b-a256d0d614ad) [Client design doc](https://microsoft-my.sharepoint-df.com/:w:/p/mipetriu/EWbcvu99HRxEgy-BC9jilKoBnqIr3yCJaNPZMlGSG5c3ow?e=aP0ey1) ## Changes - Add constants for API - Add BaseCommand for isQrPinAvailable, used by BrokerMsal API - Add behavior for LocalMsalController (not supported) BrokerMsalController and (supported, call the broker) ## Related PR https://github.com/AzureAD/ad-accounts-for-android/pull/2587 https://github.com/AzureAD/microsoft-authentication-library-for-android/pull/1931 --- changelog.txt | 1 + .../common/CommandDispatcherTest.java | 4 ++ .../internal/AuthenticationConstants.java | 19 +++++- ...bstractIpcStrategyWithServiceValidation.kt | 1 + .../broker/ipc/BrokerOperationBundle.java | 2 + .../commands/IsQrPinAvailableCommand.kt | 50 ++++++++++++++ .../controllers/BrokerMsalController.java | 68 +++++++++++++++++++ .../controllers/LocalMSALController.java | 20 ++++++ .../result/MsalBrokerResultAdapter.java | 18 +++++ .../controllers/BaseNativeAuthController.kt | 9 +++ .../java/controllers/BaseController.java | 7 ++ .../java/eststelemetry/PublicApiId.java | 1 + .../java/exception/BrokerRequiredException.kt | 46 +++++++++++++ .../java/telemetry/TelemetryEventStrings.java | 1 + 14 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/com/microsoft/identity/common/internal/commands/IsQrPinAvailableCommand.kt create mode 100644 common4j/src/main/com/microsoft/identity/common/java/exception/BrokerRequiredException.kt diff --git a/changelog.txt b/changelog.txt index 4d979cce1a..03422b495c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,6 @@ V.Next --------- +- [MINOR] Add IsQrPinAvailableCommand, controllers behavior and define constants for the isQrAvailable API (#2219) - [MINOR] Add PreferredAuthMethod to interactive token flow (#2245) - [MINOR] Implement updates of the native auth web API (#2261) diff --git a/common/src/androidTest/java/com/microsoft/identity/common/CommandDispatcherTest.java b/common/src/androidTest/java/com/microsoft/identity/common/CommandDispatcherTest.java index 303c5a9785..2d096182cf 100644 --- a/common/src/androidTest/java/com/microsoft/identity/common/CommandDispatcherTest.java +++ b/common/src/androidTest/java/com/microsoft/identity/common/CommandDispatcherTest.java @@ -1063,6 +1063,10 @@ public GenerateShrResult generateSignedHttpRequest(GenerateShrCommandParameters return null; } + @Override + public boolean isQrPinAvailable() throws Exception { + return false; + } } private static CommandParameters getEmptyTestParams() { diff --git a/common/src/main/java/com/microsoft/identity/common/adal/internal/AuthenticationConstants.java b/common/src/main/java/com/microsoft/identity/common/adal/internal/AuthenticationConstants.java index b1146b5a5a..af61300d82 100644 --- a/common/src/main/java/com/microsoft/identity/common/adal/internal/AuthenticationConstants.java +++ b/common/src/main/java/com/microsoft/identity/common/adal/internal/AuthenticationConstants.java @@ -1280,6 +1280,11 @@ public static String computeMaxHostBrokerProtocol() { */ public static final String BROKER_GENERATE_SHR_RESULT = "broker_generate_shr_result"; + /** + * String for QR + PIN result. + */ + public static final String IS_QR_PIN_AVAILABLE = "is_qr_pin_available"; + /** * String to return a true if the request succeeded, false otherwise. */ @@ -1556,7 +1561,9 @@ public enum API { BROKER_DISCOVERY_FROM_SDK(BROKER_DISCOVERY_FROM_SDK_PATH, null, null), BROKER_DISCOVERY_SET_ACTIVE_BROKER(BROKER_DISCOVERY_SET_ACTIVE_BROKER_PATH, null, null), PASSTHROUGH(PASSTHROUGH_PATH, null, null), - BROKER_INDIVIDUAL_LOGS_UPLOAD(BROKER_INDIVIDUAL_LOGS_UPLOAD_PATH, null, null),; + READ_RESTRICTIONS_MANAGER(READ_RESTRICTIONS_MANAGER_PATH, null, null), + IS_QR_PIN_AVAILABLE(IS_QR_PIN_AVAILABLE_PATH, null, null), + BROKER_INDIVIDUAL_LOGS_UPLOAD(BROKER_INDIVIDUAL_LOGS_UPLOAD_PATH, null, null); /** * The content provider path that the API exists behind. @@ -1690,6 +1697,16 @@ public enum API { */ public static final String GET_SSO_TOKEN_PATH = "/ssoToken"; + /** + * ContentProvider path to check if QR + PIN should de available. + */ + public static final String IS_QR_PIN_AVAILABLE_PATH = "/isQrPinAvailable"; + + /** + * ContentProvider path to read the restrictions manager. + */ + public static final String READ_RESTRICTIONS_MANAGER_PATH = "/readRestrictionsManager"; + /** * Broker api path constant for execute device registration protocols. * Note: The path was updated because in release 9.0.1 a part of the NEW WPJ API was exposed diff --git a/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/AbstractIpcStrategyWithServiceValidation.kt b/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/AbstractIpcStrategyWithServiceValidation.kt index f9dbcfaa83..39b2963183 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/AbstractIpcStrategyWithServiceValidation.kt +++ b/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/AbstractIpcStrategyWithServiceValidation.kt @@ -54,6 +54,7 @@ abstract class AbstractIpcStrategyWithServiceValidation( */ abstract fun isSupportedByTargetedBroker(targetedBrokerPackageName: String): Boolean + @Throws(BrokerCommunicationException::class) override fun communicateToBroker(bundle: BrokerOperationBundle): Bundle? { val methodTag = "$TAG:communicateToBroker" if (!shouldBypassSupportValidation && !isSupportedByTargetedBroker(bundle.targetBrokerAppPackageName)) { diff --git a/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/BrokerOperationBundle.java b/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/BrokerOperationBundle.java index cf8828d298..253599fe57 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/BrokerOperationBundle.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/broker/ipc/BrokerOperationBundle.java @@ -74,6 +74,8 @@ public enum Operation { BROKER_DISCOVERY_FROM_SDK(API.BROKER_DISCOVERY_FROM_SDK, null), BROKER_DISCOVERY_SET_ACTIVE_BROKER(API.BROKER_DISCOVERY_SET_ACTIVE_BROKER, null), PASSTHROUGH(API.PASSTHROUGH, null), + BROKER_READ_RESTRICTIONS_MANAGER(API.READ_RESTRICTIONS_MANAGER, null), + MSAL_IS_QR_PIN_AVAILABLE(API.IS_QR_PIN_AVAILABLE, null), BROKER_INDIVIDUAL_LOGS_UPLOAD(API.BROKER_INDIVIDUAL_LOGS_UPLOAD, null); final API mContentApi; diff --git a/common/src/main/java/com/microsoft/identity/common/internal/commands/IsQrPinAvailableCommand.kt b/common/src/main/java/com/microsoft/identity/common/internal/commands/IsQrPinAvailableCommand.kt new file mode 100644 index 0000000000..dcca1e8502 --- /dev/null +++ b/common/src/main/java/com/microsoft/identity/common/internal/commands/IsQrPinAvailableCommand.kt @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +package com.microsoft.identity.common.internal.commands + +import com.microsoft.identity.common.java.commands.BaseCommand +import com.microsoft.identity.common.java.commands.CommandCallback +import com.microsoft.identity.common.java.commands.parameters.CommandParameters +import com.microsoft.identity.common.java.controllers.BaseController +import lombok.EqualsAndHashCode + +/** + * Command class to call controllers to check if QR code + PIN authorization is available. + * {@see com.microsoft.identity.common.java.controllers.CommandDispatcher}. + */ +@EqualsAndHashCode(callSuper = true) +class IsQrPinAvailableCommand( + parameters: CommandParameters, + controller: BaseController, + callback: CommandCallback<*, *>, + publicApiId: String +) : BaseCommand(parameters, controller, callback, publicApiId) { + + override fun execute(): Boolean { + return defaultController.isQrPinAvailable + } + + override fun isEligibleForEstsTelemetry(): Boolean { + return false + } +} diff --git a/common/src/main/java/com/microsoft/identity/common/internal/controllers/BrokerMsalController.java b/common/src/main/java/com/microsoft/identity/common/internal/controllers/BrokerMsalController.java index fc4084f2a2..51f216d0d5 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/controllers/BrokerMsalController.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/controllers/BrokerMsalController.java @@ -35,6 +35,7 @@ import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_GET_CURRENT_ACCOUNT_IN_SHARED_DEVICE; import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_GET_DEVICE_MODE; import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_GET_INTENT_FOR_INTERACTIVE_REQUEST; +import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_IS_QR_PIN_AVAILABLE; import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_REMOVE_ACCOUNT; import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_SIGN_OUT_FROM_SHARED_DEVICE; import static com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle.Operation.MSAL_SSO_TOKEN; @@ -55,6 +56,7 @@ import com.microsoft.identity.common.PropertyBagUtil; import com.microsoft.identity.common.adal.internal.AuthenticationConstants; +import com.microsoft.identity.common.exception.BrokerCommunicationException; import com.microsoft.identity.common.internal.broker.BrokerActivity; import com.microsoft.identity.common.internal.broker.BrokerResult; import com.microsoft.identity.common.internal.broker.MicrosoftAuthClient; @@ -114,6 +116,7 @@ import com.microsoft.identity.common.logging.Logger; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -800,6 +803,71 @@ public void putValueInSuccessEvent(final @NonNull ApiEndEvent event, final @NonN }); } + + /** + * Checks if QR + PIN authorization is available. + * + * @return true if if QR + PIN authorization is available. False otherwise. + */ + @Override + public boolean isQrPinAvailable() throws BaseException { + final String methodTag = TAG + ":isQrPinAvailable"; + return mBrokerOperationExecutor.execute( + null, + new BrokerOperation() { + + @Override + public void performPrerequisites(final @NonNull IIpcStrategy strategy) throws BrokerCommunicationException { + // AccountManagerAddAccountStrategy and BoundServiceStrategy are not supported for this operation. + // We are failing fast here to avoid unnecessary IPC calls. + // IPC calls through BoundServiceStrategy takes approximate 25s to timeout. + if (strategy instanceof BoundServiceStrategy || strategy instanceof AccountManagerAddAccountStrategy) { + final String errorMessage = strategy + " is not supported for isQrPinAvailable operation"; + Logger.warn(methodTag, errorMessage); + throw new BrokerCommunicationException( + BrokerCommunicationException.Category.OPERATION_NOT_SUPPORTED_ON_SERVER_SIDE, + strategy.getType(), + errorMessage, + null + ); + } + } + + @Override + @NonNull + public BrokerOperationBundle getBundle() { + return new BrokerOperationBundle( + MSAL_IS_QR_PIN_AVAILABLE, + mActiveBrokerPackageName, + null + ); + } + + @Override + @NonNull + public Boolean extractResultBundle(final @Nullable Bundle resultBundle) throws BaseException { + return mResultAdapter.getIfQrPinIsAvailableFromResultBundle(resultBundle); + } + + @Override + @NonNull + public String getMethodName() { + return ":isQrPinAvailable"; + } + + @Override + @NonNull + public String getTelemetryApiId() { + return TelemetryEventStrings.Api.IS_QR_PIN_AVAILABLE; + } + + @Override + public void putValueInSuccessEvent(final @NonNull ApiEndEvent event, final @NonNull Boolean result) { + // Deprecated telemetry. + } + }); + } + /** * Get device mode from broker. * diff --git a/common/src/main/java/com/microsoft/identity/common/internal/controllers/LocalMSALController.java b/common/src/main/java/com/microsoft/identity/common/internal/controllers/LocalMSALController.java index 271fd2a775..809acf5570 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/controllers/LocalMSALController.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/controllers/LocalMSALController.java @@ -27,10 +27,12 @@ import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; +import com.microsoft.identity.common.internal.broker.BrokerData; import com.microsoft.identity.common.java.configuration.LibraryConfiguration; import com.microsoft.identity.common.java.controllers.CommandDispatcher; import com.microsoft.identity.common.java.eststelemetry.PublicApiId; import com.microsoft.identity.common.java.exception.ArgumentException; +import com.microsoft.identity.common.java.exception.BrokerRequiredException; import com.microsoft.identity.common.java.exception.ClientException; import com.microsoft.identity.common.java.exception.ErrorStrings; import com.microsoft.identity.common.java.exception.ServiceException; @@ -509,6 +511,24 @@ public boolean removeAccount( return localRemoveAccountSuccess; } + /** + * Checks if QR + PIN auth is available. + * LocalMSALController is not eligible to use the broker. + * Do not check if QR + PIN is available and return false immediately. + * + * @return true false + */ + @Override + public boolean isQrPinAvailable() throws BrokerRequiredException { + final String methodTag = TAG + ":isQrPinAvailable"; + final BrokerRequiredException exception = new BrokerRequiredException( + BrokerData.getProdMicrosoftAuthenticator().getPackageName(), + null + ); + Logger.error(methodTag, "QR + PIN not available. Requires broker.", exception); + throw exception; + } + @Override public boolean getDeviceMode(CommandParameters parameters) throws Exception { final String methodTag = TAG + ":getDeviceMode"; diff --git a/common/src/main/java/com/microsoft/identity/common/internal/result/MsalBrokerResultAdapter.java b/common/src/main/java/com/microsoft/identity/common/internal/result/MsalBrokerResultAdapter.java index 7c972e2e0f..43cbc65789 100644 --- a/common/src/main/java/com/microsoft/identity/common/internal/result/MsalBrokerResultAdapter.java +++ b/common/src/main/java/com/microsoft/identity/common/internal/result/MsalBrokerResultAdapter.java @@ -32,6 +32,7 @@ import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.BROKER_RESULT_V2_COMPRESSED; import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.HELLO_ERROR_CODE; import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.HELLO_ERROR_MESSAGE; +import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.IS_QR_PIN_AVAILABLE; import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.NEGOTIATED_BP_VERSION_KEY; import static com.microsoft.identity.common.internal.util.GzipUtil.compressString; import static com.microsoft.identity.common.java.exception.ClientException.INVALID_BROKER_BUNDLE; @@ -816,4 +817,21 @@ public GenerateShrResult getGenerateShrResultFromResultBundle(@NonNull final Bun return shrResult; } + + /** + * Checks if the provided {@link Bundle} contains a key indicating that the broker is capable of QR code + PIN auth. + * + * @param bundle The {@link Bundle} to check. + * @return True if the broker is capable of QR code + PIN auth, false otherwise. + * @throws BaseException If the bundle does not contain the key. + */ + public boolean getIfQrPinIsAvailableFromResultBundle(@Nullable final Bundle bundle) throws BaseException { + if (bundle == null) { + throw getExceptionForEmptyResultBundle(); + } + if (!bundle.containsKey(IS_QR_PIN_AVAILABLE)) { + throw new MsalBrokerResultAdapter().getBaseExceptionFromBundle(bundle); + } + return bundle.getBoolean(IS_QR_PIN_AVAILABLE); + } } diff --git a/common/src/main/java/com/microsoft/identity/common/nativeauth/internal/controllers/BaseNativeAuthController.kt b/common/src/main/java/com/microsoft/identity/common/nativeauth/internal/controllers/BaseNativeAuthController.kt index a9c149cdc8..77a124aed0 100644 --- a/common/src/main/java/com/microsoft/identity/common/nativeauth/internal/controllers/BaseNativeAuthController.kt +++ b/common/src/main/java/com/microsoft/identity/common/nativeauth/internal/controllers/BaseNativeAuthController.kt @@ -246,4 +246,13 @@ abstract class BaseNativeAuthController : BaseController() { override fun getCachedAccountRecordFromAllCaches(parameters: SilentTokenCommandParameters): AccountRecord? { throw ClientException("getCachedAccountRecordFromAllCaches() not supported in NativeAuthController") } + + @Throws(ClientException::class) + @Deprecated( + level = DeprecationLevel.HIDDEN, + message = "isQrPinAvailable() not supported in NativeAuthController" + ) + override fun isQrPinAvailable(): Boolean { + throw ClientException("isQrPinAvailable() not supported in NativeAuthController") + } } diff --git a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java index 1a9da4b2b4..a1fe4d9786 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java +++ b/common4j/src/main/com/microsoft/identity/common/java/controllers/BaseController.java @@ -144,6 +144,13 @@ public abstract boolean removeAccount( public abstract boolean getDeviceMode(final CommandParameters parameters) throws Exception; + /** + * This method is used to determine if the QR + PIN auth flow is available on the device. + * + * @return true if if QR + PIN authorization is available. False otherwise. + */ + public abstract boolean isQrPinAvailable() throws Exception; + public abstract List getCurrentAccount(final CommandParameters parameters) throws Exception; diff --git a/common4j/src/main/com/microsoft/identity/common/java/eststelemetry/PublicApiId.java b/common4j/src/main/com/microsoft/identity/common/java/eststelemetry/PublicApiId.java index 07140a10b6..3ee605634c 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/eststelemetry/PublicApiId.java +++ b/common4j/src/main/com/microsoft/identity/common/java/eststelemetry/PublicApiId.java @@ -136,6 +136,7 @@ public final class PublicApiId { public static final String PCA_GET_DEVICE_MODE = "1200"; + public static final String PCA_IS_QR_PIN_AVAILABLE = "1300"; //region NativeAuthPublicClientApplication //============================================================================================== public static final String NATIVE_AUTH_SIGN_IN_WITH_EMAIL = "210"; diff --git a/common4j/src/main/com/microsoft/identity/common/java/exception/BrokerRequiredException.kt b/common4j/src/main/com/microsoft/identity/common/java/exception/BrokerRequiredException.kt new file mode 100644 index 0000000000..ddce2d7dfa --- /dev/null +++ b/common4j/src/main/com/microsoft/identity/common/java/exception/BrokerRequiredException.kt @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +package com.microsoft.identity.common.java.exception + + +/** + * Representing exceptions that occur when broker is required but not installed. + */ +class BrokerRequiredException( + brokerPackageName: String? = null, + cause: Throwable? = null, +) : BaseException(ERROR_CODE, getErrorMessage(brokerPackageName), cause) { + + companion object { + public const val ERROR_CODE = "broker_required" + private const val DEFAULT_ERROR_MESSAGE = "Broker is required but not installed." + + private fun getErrorMessage(brokerPackageName: String?): String { + return if (brokerPackageName != null) { + "$DEFAULT_ERROR_MESSAGE Please install $brokerPackageName." + } else { + DEFAULT_ERROR_MESSAGE + } + } + } +} diff --git a/common4j/src/main/com/microsoft/identity/common/java/telemetry/TelemetryEventStrings.java b/common4j/src/main/com/microsoft/identity/common/java/telemetry/TelemetryEventStrings.java index 3e35850e95..6b93289bc4 100644 --- a/common4j/src/main/com/microsoft/identity/common/java/telemetry/TelemetryEventStrings.java +++ b/common4j/src/main/com/microsoft/identity/common/java/telemetry/TelemetryEventStrings.java @@ -224,6 +224,7 @@ public static final class Api { public static final String BROKER_GET_ACCOUNTS = "206"; public static final String BROKER_REMOVE_ACCOUNT = "207"; public static final String BROKER_REMOVE_ACCOUNT_FROM_SHARED_DEVICE = "208"; + public static final String IS_QR_PIN_AVAILABLE = "209"; public static final String LOCAL_ACQUIRE_TOKEN_INTERACTIVE = "101"; public static final String LOCAL_COMPLETE_ACQUIRE_TOKEN_INTERACTIVE = "1032";