Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import com.microsoft.bot.schema.TokenStatus;
import com.microsoft.bot.restclient.retry.RetryStrategy;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang3.StringUtils;

import java.net.HttpURLConnection;
Expand Down Expand Up @@ -1069,41 +1070,47 @@ public CompletableFuture<Void> createConversation(String channelId, String servi
* If null, the default credentials will be used.
* @return An OAuth client for the bot.
*/
protected CompletableFuture<OAuthClient> createOAuthAPIClient(TurnContext turnContext,
AppCredentials oAuthAppCredentials) {
protected CompletableFuture<OAuthClient> createOAuthAPIClient(
TurnContext turnContext,
AppCredentials oAuthAppCredentials
) {
if (!OAuthClientConfig.emulateOAuthCards
&& StringUtils.equalsIgnoreCase(turnContext.getActivity().getChannelId(), Channels.EMULATOR)
&& credentialProvider.isAuthenticationDisabled().join()) {
&& credentialProvider.isAuthenticationDisabled().join()
) {
OAuthClientConfig.emulateOAuthCards = true;
}
AtomicBoolean sendEmulateOAuthCards = new AtomicBoolean(false);

String appId = getBotAppId(turnContext);
String cacheKey = appId + (oAuthAppCredentials != null ? oAuthAppCredentials.getAppId() : "");
String oAuthScope = getBotFrameworkOAuthScope();
AppCredentials credentials = oAuthAppCredentials != null ? oAuthAppCredentials
: getAppCredentials(appId, oAuthScope).join();

OAuthClient client = oAuthClients.computeIfAbsent(cacheKey, key -> {
OAuthClient oAuthClient = new RestOAuthClient(
OAuthClientConfig.emulateOAuthCards ? turnContext.getActivity().getServiceUrl()
: OAuthClientConfig.OAUTHENDPOINT,
credentials);

if (OAuthClientConfig.emulateOAuthCards) {
// do not join task - we want this to run in the background.
OAuthClientConfig.sendEmulateOAuthCards(oAuthClient, OAuthClientConfig.emulateOAuthCards);
}
sendEmulateOAuthCards.set(OAuthClientConfig.emulateOAuthCards);

String oAuthScope = getBotFrameworkOAuthScope();
AppCredentials credentials = oAuthAppCredentials != null
? oAuthAppCredentials
: getAppCredentials(appId, oAuthScope).join();

return oAuthClient;
return new RestOAuthClient(
OAuthClientConfig.emulateOAuthCards
? turnContext.getActivity().getServiceUrl()
: OAuthClientConfig.OAUTHENDPOINT,
credentials
);
});

// adding the oAuthClient into the TurnState
// TokenResolver.cs will use it get the correct credentials to poll for
// token for streaming scenario
if (turnContext.getTurnState().get(BotAdapter.OAUTH_CLIENT_KEY) == null) {
turnContext.getTurnState().add(BotAdapter.OAUTH_CLIENT_KEY, client);
}

if (sendEmulateOAuthCards.get()) {
return client.getUserToken().sendEmulateOAuthCards(true)
.thenApply(voidresult -> client);
}

return CompletableFuture.completedFuture(client);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
package com.microsoft.bot.connector;

import com.microsoft.bot.connector.authentication.AuthenticationConstants;
import org.apache.commons.lang3.NotImplementedException;

import java.util.concurrent.CompletableFuture;

/**
* OAuthClient config.
Expand All @@ -27,19 +24,4 @@ private OAuthClientConfig() {
*/
@SuppressWarnings("checkstyle:VisibilityModifier")
public static boolean emulateOAuthCards = false;

/**
* Send a dummy OAuth card when the bot is being used on the Emulator for
* testing without fetching a real token.
*
* @param client The OAuth client.
* @param emulate Indicates whether the Emulator should emulate the OAuth card.
* @return A task that represents the work queued to execute.
*/
public static CompletableFuture<Void> sendEmulateOAuthCards(
OAuthClient client,
boolean emulate
) {
throw new NotImplementedException("sendEmulateOAuthCards");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,12 @@ CompletableFuture<List<TokenStatus>> getTokenStatus(
String channelId,
String include
);

/**
* Send a dummy OAuth card when the bot is being used on the Emulator for testing without fetching a real token.
*
* @param emulateOAuthCards Indicates whether the Emulator should emulate the OAuth card.
* @return A task that represents the work queued to execute.
*/
CompletableFuture<Void> sendEmulateOAuthCards(boolean emulateOAuthCards);
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ CompletableFuture<Response<ResponseBody>> getTokenStatus(
@Query("channelId") String channelId,
@Query("include") String include
);

@Headers({ "Content-Type: application/json; charset=utf-8",
"x-ms-logging-context: com.microsoft.bot.schema.UserTokens sendEmulateOAuthCards" })
@POST("api/usertoken/emulateOAuthCards")
CompletableFuture<Response<ResponseBody>> sendEmulateOAuthCards(
@Query("emulate") boolean emulate
);
}

/**
Expand Down Expand Up @@ -532,4 +539,39 @@ private ServiceResponse<List<TokenStatus>> getTokenStatusDelegate(
.registerError(ErrorResponseException.class)
.build(response);
}

/**
* Send a dummy OAuth card when the bot is being used on the Emulator for testing without fetching a real token.
*
* @param emulateOAuthCards Indicates whether the Emulator should emulate the OAuth card.
* @return A task that represents the work queued to execute.
*/
@Override
public CompletableFuture<Void> sendEmulateOAuthCards(boolean emulateOAuthCards) {
return service.sendEmulateOAuthCards(emulateOAuthCards)
.thenApply(responseBodyResponse -> {
try {
return sendEmulateOAuthCardsDelegate(responseBodyResponse).body();
} catch (ErrorResponseException e) {
throw e;
} catch (Throwable t) {
throw new ErrorResponseException("sendEmulateOAuthCards", responseBodyResponse);
}
});
}

private ServiceResponse<Void> sendEmulateOAuthCardsDelegate(
Response<ResponseBody> response
) throws ErrorResponseException, IOException, IllegalArgumentException {

return client.restClient()
.responseBuilderFactory()
.<Void, ErrorResponseException>newInstance(client.serializerAdapter())
.register(HttpURLConnection.HTTP_OK, new TypeToken<Void>() {
}.getType())
.register(HttpURLConnection.HTTP_ACCEPTED, new TypeToken<Void>() {
}.getType())
.registerError(ErrorResponseException.class)
.build(response);
}
}