|
22 | 22 | // THE SOFTWARE. |
23 | 23 | package com.microsoft.identity.common.internal.controllers; |
24 | 24 |
|
| 25 | +import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.BROKER_WEB_APPS_INTERACTIVE_INTENT; |
25 | 26 | import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.CLIENT_ADVERTISED_MAXIMUM_BP_VERSION_KEY; |
26 | 27 | import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.CLIENT_CONFIGURED_MINIMUM_BP_VERSION_KEY; |
27 | 28 | import static com.microsoft.identity.common.adal.internal.AuthenticationConstants.Broker.CLIENT_MAX_PROTOCOL_VERSION; |
|
66 | 67 | import com.microsoft.identity.common.internal.broker.ipc.BrokerOperationBundle; |
67 | 68 | import com.microsoft.identity.common.internal.broker.ipc.IIpcStrategy; |
68 | 69 | import com.microsoft.identity.common.internal.broker.ipc.WebAppsAdditionalRequiredParameters; |
| 70 | +import com.microsoft.identity.common.internal.util.WebAppsUtil; |
69 | 71 | import com.microsoft.identity.common.internal.cache.ActiveBrokerCacheUpdater; |
70 | 72 | import com.microsoft.identity.common.internal.cache.ClientActiveBrokerCache; |
71 | 73 | import com.microsoft.identity.common.internal.cache.HelloCache; |
|
113 | 115 | import com.microsoft.identity.common.java.result.GenerateShrResult; |
114 | 116 | import com.microsoft.identity.common.java.ui.PreferredAuthMethod; |
115 | 117 | import com.microsoft.identity.common.java.util.BrokerProtocolVersionUtil; |
| 118 | +import com.microsoft.identity.common.java.util.ObjectMapper; |
116 | 119 | import com.microsoft.identity.common.java.util.ResultFuture; |
117 | 120 | import com.microsoft.identity.common.java.util.StringUtil; |
118 | 121 | import com.microsoft.identity.common.java.util.ThreadUtils; |
|
121 | 124 | import com.microsoft.identity.common.logging.Logger; |
122 | 125 | import com.microsoft.identity.common.sharedwithoneauth.OneAuthSharedFunctions; |
123 | 126 |
|
124 | | -import java.util.ArrayList; |
125 | | -import java.util.Collections; |
126 | 127 | import java.util.List; |
127 | 128 | import java.util.concurrent.ExecutionException; |
128 | 129 | import java.util.concurrent.TimeUnit; |
@@ -350,22 +351,53 @@ private String tryGetNegotiatedProtocolVersionFromHelloCache( |
350 | 351 | @Override |
351 | 352 | public AcquireTokenResult acquireToken(final @NonNull InteractiveTokenCommandParameters parameters) |
352 | 353 | throws BaseException, InterruptedException, ExecutionException { |
353 | | - final String methodTag = TAG + ":acquireToken"; |
| 354 | + final AcquireTokenResult result; |
| 355 | + try { |
| 356 | + //Get the broker interactive parameters intent |
| 357 | + final Intent interactiveRequestIntent = getBrokerAuthorizationIntent(parameters); |
| 358 | + final Bundle resultBundle = acquireTokenInternal(parameters, interactiveRequestIntent); |
| 359 | + final String negotiatedBrokerProtocolVersion = resultBundle.getString(NEGOTIATED_BP_VERSION_KEY); |
| 360 | + // For MSA Accounts Broker doesn't save the accounts, instead it just passes the result along, |
| 361 | + // MSAL needs to save this account locally for future token calls. |
| 362 | + // parameters.getOAuth2TokenCache() will be non-null only in case of MSAL native |
| 363 | + // If the request is from MSALCPP , OAuth2TokenCache will be null. |
| 364 | + if (parameters.getOAuth2TokenCache() != null && !BrokerProtocolVersionUtil.canSupportMsaAccountsInBroker(negotiatedBrokerProtocolVersion)) { |
| 365 | + saveMsaAccountToCache(resultBundle, (MsalOAuth2TokenCache) parameters.getOAuth2TokenCache()); |
| 366 | + } |
| 367 | + |
| 368 | + verifyBrokerVersionIsSupported(resultBundle, parameters.getRequiredBrokerProtocolVersion()); |
| 369 | + result = mResultAdapter.getAcquireTokenResultFromResultBundle(resultBundle); |
| 370 | + } catch (final BaseException | ExecutionException e) { |
| 371 | + Telemetry.emit( |
| 372 | + new ApiEndEvent() |
| 373 | + .putException(e) |
| 374 | + .putApiId(TelemetryEventStrings.Api.BROKER_ACQUIRE_TOKEN_INTERACTIVE) |
| 375 | + ); |
| 376 | + throw e; |
| 377 | + } |
354 | 378 |
|
| 379 | + Telemetry.emit( |
| 380 | + new ApiEndEvent() |
| 381 | + .putResult(result) |
| 382 | + .putApiId(TelemetryEventStrings.Api.BROKER_ACQUIRE_TOKEN_INTERACTIVE) |
| 383 | + ); |
| 384 | + |
| 385 | + return result; |
| 386 | + } |
| 387 | + |
| 388 | + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) |
| 389 | + protected Bundle acquireTokenInternal(final @Nullable InteractiveTokenCommandParameters parameters, final @NonNull Intent interactiveRequestIntent) throws BaseException, InterruptedException, ExecutionException { |
| 390 | + final String methodTag = TAG + ":acquireTokenInternal"; |
355 | 391 | Telemetry.emit( |
356 | 392 | new ApiStartEvent() |
357 | 393 | .putProperties(parameters) |
358 | 394 | .putApiId(TelemetryEventStrings.Api.BROKER_ACQUIRE_TOKEN_INTERACTIVE) |
359 | 395 | ); |
360 | | - |
361 | | - //Create BrokerResultFuture to block on response from the broker... response will be return as an activity result |
| 396 | + //Create BrokerResultFuture to block on response from the broker... |
362 | 397 | //BrokerActivity will receive the result and ask the API dispatcher to complete the request |
363 | 398 | //In completeAcquireToken below we will set the result on the future and unblock the flow. |
364 | 399 | mBrokerResultFuture = new ResultFuture<>(); |
365 | 400 |
|
366 | | - //Get the broker interactive parameters intent |
367 | | - final Intent interactiveRequestIntent = getBrokerAuthorizationIntent(parameters); |
368 | | - |
369 | 401 | Activity activity = null; |
370 | 402 | if (parameters instanceof AndroidInteractiveTokenCommandParameters) { |
371 | 403 | activity = ((AndroidInteractiveTokenCommandParameters) parameters).getActivity(); |
@@ -418,39 +450,10 @@ public void onReceive(@NonNull PropertyBag propertyBag) { |
418 | 450 | // Start the BrokerActivity using our existing Activity |
419 | 451 | activity.startActivity(brokerActivityIntent); |
420 | 452 | } |
421 | | - |
422 | | - final AcquireTokenResult result; |
423 | | - try { |
424 | | - //Wait to be notified of the result being returned... we could add a timeout here if we want to |
425 | | - final Bundle resultBundle = mBrokerResultFuture.get(); |
426 | | - |
427 | | - final String negotiatedBrokerProtocolVersion = interactiveRequestIntent.getStringExtra(NEGOTIATED_BP_VERSION_KEY); |
428 | | - // For MSA Accounts Broker doesn't save the accounts, instead it just passes the result along, |
429 | | - // MSAL needs to save this account locally for future token calls. |
430 | | - // parameters.getOAuth2TokenCache() will be non-null only in case of MSAL native |
431 | | - // If the request is from MSALCPP , OAuth2TokenCache will be null. |
432 | | - if (parameters.getOAuth2TokenCache() != null && !BrokerProtocolVersionUtil.canSupportMsaAccountsInBroker(negotiatedBrokerProtocolVersion)) { |
433 | | - saveMsaAccountToCache(resultBundle, (MsalOAuth2TokenCache) parameters.getOAuth2TokenCache()); |
434 | | - } |
435 | | - |
436 | | - verifyBrokerVersionIsSupported(resultBundle, parameters.getRequiredBrokerProtocolVersion()); |
437 | | - result = mResultAdapter.getAcquireTokenResultFromResultBundle(resultBundle); |
438 | | - } catch (final BaseException | ExecutionException e) { |
439 | | - Telemetry.emit( |
440 | | - new ApiEndEvent() |
441 | | - .putException(e) |
442 | | - .putApiId(TelemetryEventStrings.Api.BROKER_ACQUIRE_TOKEN_INTERACTIVE) |
443 | | - ); |
444 | | - throw e; |
445 | | - } |
446 | | - |
447 | | - Telemetry.emit( |
448 | | - new ApiEndEvent() |
449 | | - .putResult(result) |
450 | | - .putApiId(TelemetryEventStrings.Api.BROKER_ACQUIRE_TOKEN_INTERACTIVE) |
451 | | - ); |
452 | | - |
453 | | - return result; |
| 453 | + //Wait to be notified of the result being returned... we could add a timeout here if we want to |
| 454 | + final Bundle resultBundle = mBrokerResultFuture.get(); |
| 455 | + resultBundle.putString(NEGOTIATED_BP_VERSION_KEY, interactiveRequestIntent.getStringExtra(NEGOTIATED_BP_VERSION_KEY)); |
| 456 | + return resultBundle; |
454 | 457 | } |
455 | 458 |
|
456 | 459 | @Override |
@@ -1425,60 +1428,85 @@ public void putValueInSuccessEvent(@NonNull final ApiEndEvent event, |
1425 | 1428 | /** |
1426 | 1429 | * Execute web app request in broker. |
1427 | 1430 | * |
1428 | | - * @param request request string |
| 1431 | + * @param request request string. |
1429 | 1432 | * @param minBrokerProtocolVersion minimum broker protocol version the caller requires. |
1430 | 1433 | * @param additionalRequiredParams additional required parameters for web app request. |
1431 | 1434 | * @throws BaseException |
1432 | 1435 | */ |
1433 | 1436 | public String executeWebAppRequest(@NonNull final String request, |
1434 | 1437 | @NonNull final String minBrokerProtocolVersion, |
1435 | 1438 | @NonNull final WebAppsAdditionalRequiredParameters additionalRequiredParams) throws BaseException { |
1436 | | - return getBrokerOperationExecutor().execute(null, |
1437 | | - new BrokerOperation<String>() { |
1438 | | - private String negotiatedBrokerProtocolVersion; |
| 1439 | + try { |
| 1440 | + return getBrokerOperationExecutor().execute(null, |
| 1441 | + new BrokerOperation<String>() { |
| 1442 | + private String negotiatedBrokerProtocolVersion; |
1439 | 1443 |
|
1440 | | - @Override |
1441 | | - public void performPrerequisites(@NonNull final IIpcStrategy strategy) throws BaseException { |
1442 | | - negotiatedBrokerProtocolVersion = hello(strategy, minBrokerProtocolVersion); |
1443 | | - } |
| 1444 | + @Override |
| 1445 | + public void performPrerequisites(@NonNull final IIpcStrategy strategy) throws BaseException { |
| 1446 | + negotiatedBrokerProtocolVersion = hello(strategy, minBrokerProtocolVersion); |
| 1447 | + } |
1444 | 1448 |
|
1445 | | - @NonNull |
1446 | | - @Override |
1447 | | - public BrokerOperationBundle getBundle() throws ClientException { |
1448 | | - return new BrokerOperationBundle( |
1449 | | - BrokerOperationBundle.Operation.BROKER_WEBAPPS_API_EXECUTE_WEB_APPS_REQUEST, |
1450 | | - mActiveBrokerPackageName, |
1451 | | - mRequestAdapter.getRequestBundleForExecuteWebAppRequest(request,negotiatedBrokerProtocolVersion, minBrokerProtocolVersion) |
1452 | | - ); |
1453 | | - } |
| 1449 | + @NonNull |
| 1450 | + @Override |
| 1451 | + public BrokerOperationBundle getBundle() throws ClientException { |
| 1452 | + final String additionalParamsString = ObjectMapper.serializeObjectToJsonString(additionalRequiredParams); |
| 1453 | + return new BrokerOperationBundle( |
| 1454 | + BrokerOperationBundle.Operation.BROKER_WEBAPPS_API_EXECUTE_WEB_APPS_REQUEST, |
| 1455 | + mActiveBrokerPackageName, |
| 1456 | + mRequestAdapter.getRequestBundleForExecuteWebAppRequest( |
| 1457 | + request, |
| 1458 | + negotiatedBrokerProtocolVersion, |
| 1459 | + minBrokerProtocolVersion, |
| 1460 | + additionalParamsString |
| 1461 | + ) |
| 1462 | + ); |
| 1463 | + } |
1454 | 1464 |
|
1455 | | - @NonNull |
1456 | | - @Override |
1457 | | - public String extractResultBundle(@Nullable final Bundle resultBundle) throws BaseException { |
1458 | | - if (resultBundle == null) { |
1459 | | - throw mResultAdapter.getExceptionForEmptyResultBundle(); |
| 1465 | + @NonNull |
| 1466 | + @Override |
| 1467 | + public String extractResultBundle(@Nullable final Bundle resultBundle) throws BaseException { |
| 1468 | + if (resultBundle == null) { |
| 1469 | + throw mResultAdapter.getExceptionForEmptyResultBundle(); |
| 1470 | + } |
| 1471 | + verifyBrokerVersionIsSupported(resultBundle, minBrokerProtocolVersion); |
| 1472 | + if (resultBundle.containsKey(BROKER_WEB_APPS_INTERACTIVE_INTENT)) { |
| 1473 | + final Intent interactiveIntent = resultBundle.getParcelable(BROKER_WEB_APPS_INTERACTIVE_INTENT); |
| 1474 | + if (interactiveIntent != null) { |
| 1475 | + try { |
| 1476 | + final Bundle interactiveGetTokenBundle = acquireTokenInternal(null, interactiveIntent); |
| 1477 | + return mResultAdapter.getExecuteWebAppRequestResultFromBundle(interactiveGetTokenBundle); |
| 1478 | + } catch (final Throwable t) { |
| 1479 | + return WebAppsUtil.createErrorResponseString(t, "Error occurred during interactive request process"); |
| 1480 | + } |
| 1481 | + } |
| 1482 | + } |
| 1483 | + return mResultAdapter.getExecuteWebAppRequestResultFromBundle(resultBundle); |
1460 | 1484 | } |
1461 | | - verifyBrokerVersionIsSupported(resultBundle, minBrokerProtocolVersion); |
1462 | | - return mResultAdapter.getExecuteWebAppRequestResultFromBundle(resultBundle); |
1463 | | - } |
1464 | 1485 |
|
1465 | | - @NonNull |
1466 | | - @Override |
1467 | | - public String getMethodName() { |
1468 | | - return ":executeWebAppRequest"; |
1469 | | - } |
| 1486 | + @NonNull |
| 1487 | + @Override |
| 1488 | + public String getMethodName() { |
| 1489 | + return ":executeWebAppRequest"; |
| 1490 | + } |
1470 | 1491 |
|
1471 | | - @Nullable |
1472 | | - @Override |
1473 | | - public String getTelemetryApiId() { |
1474 | | - return null; |
1475 | | - } |
| 1492 | + @Nullable |
| 1493 | + @Override |
| 1494 | + public String getTelemetryApiId() { |
| 1495 | + return null; |
| 1496 | + } |
1476 | 1497 |
|
1477 | | - @Override |
1478 | | - public void putValueInSuccessEvent(@NonNull final ApiEndEvent event, |
1479 | | - @NonNull final String result) { |
1480 | | - } |
1481 | | - }); |
| 1498 | + @Override |
| 1499 | + public void putValueInSuccessEvent(@NonNull final ApiEndEvent event, |
| 1500 | + @NonNull final String result) { |
| 1501 | + } |
| 1502 | + }); |
| 1503 | + } catch (final UnsupportedBrokerException ex) { |
| 1504 | + // We want to throw this exception to keep it in line with the other APIs. |
| 1505 | + throw ex; |
| 1506 | + } |
| 1507 | + catch (final Exception ex) { |
| 1508 | + return WebAppsUtil.createErrorResponseString(ex, "Unexpected error occurred"); |
| 1509 | + } |
1482 | 1510 | } |
1483 | 1511 |
|
1484 | 1512 | /** |
|
0 commit comments