Implemented BotFrameworkAdapter OAuth methods. More cleanup.

This commit is contained in:
Tracy Boehrer 2019-09-27 09:54:15 -05:00
Родитель 08589b677f
Коммит 111d631e72
20 изменённых файлов: 263 добавлений и 191 удалений

Просмотреть файл

@ -125,12 +125,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<analysisCache>true</analysisCache>
<excludes>
<exclude>**/**</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>

Просмотреть файл

@ -97,18 +97,18 @@ public class ActivityHandler implements Bot {
protected CompletableFuture<Void> onConversationUpdateActivity(TurnContext turnContext) {
Activity activity = turnContext.getActivity();
if (activity.getMembersAdded() != null) {
if (activity.getRecipient() != null && activity.getMembersAdded().stream()
.anyMatch(m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) {
if (activity.getMembersAdded() != null
&& activity.getRecipient() != null
&& activity.getMembersAdded().stream().anyMatch(
m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) {
return onMembersAdded(activity.getMembersAdded(), turnContext);
}
} else if (activity.getRecipient() != null && activity.getMembersRemoved() != null) {
if (activity.getMembersRemoved().stream()
.anyMatch(m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) {
return onMembersAdded(activity.getMembersAdded(), turnContext);
} else if (activity.getMembersRemoved() != null
&& activity.getRecipient() != null
&& activity.getMembersRemoved().stream()
.anyMatch(m -> !StringUtils.equals(m.getId(), activity.getRecipient().getId()))) {
return onMembersRemoved(activity.getMembersRemoved(), turnContext);
}
return onMembersRemoved(activity.getMembersRemoved(), turnContext);
}
return CompletableFuture.completedFuture(null);

Просмотреть файл

@ -7,13 +7,36 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.BaseEncoding;
import com.microsoft.bot.builder.integration.AdapterIntegration;
import com.microsoft.bot.connector.*;
import com.microsoft.bot.connector.authentication.*;
import com.microsoft.bot.connector.Channels;
import com.microsoft.bot.connector.ConnectorClient;
import com.microsoft.bot.connector.Conversations;
import com.microsoft.bot.connector.ExecutorFactory;
import com.microsoft.bot.connector.OAuthClient;
import com.microsoft.bot.connector.OAuthClientConfig;
import com.microsoft.bot.connector.authentication.AuthenticationConfiguration;
import com.microsoft.bot.connector.authentication.AuthenticationConstants;
import com.microsoft.bot.connector.authentication.ChannelProvider;
import com.microsoft.bot.connector.authentication.ClaimsIdentity;
import com.microsoft.bot.connector.authentication.CredentialProvider;
import com.microsoft.bot.connector.authentication.JwtTokenValidation;
import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials;
import com.microsoft.bot.connector.rest.RestConnectorClient;
import com.microsoft.bot.connector.rest.RestOAuthClient;
import com.microsoft.bot.schema.*;
import com.microsoft.bot.schema.AadResourceUrls;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes;
import com.microsoft.bot.schema.ChannelAccount;
import com.microsoft.bot.schema.ConversationAccount;
import com.microsoft.bot.schema.ConversationParameters;
import com.microsoft.bot.schema.ConversationReference;
import com.microsoft.bot.schema.ConversationResourceResponse;
import com.microsoft.bot.schema.ConversationsResult;
import com.microsoft.bot.schema.ResourceResponse;
import com.microsoft.bot.schema.RoleTypes;
import com.microsoft.bot.schema.TokenExchangeState;
import com.microsoft.bot.schema.TokenResponse;
import com.microsoft.bot.schema.TokenStatus;
import com.microsoft.rest.retry.RetryStrategy;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import java.net.MalformedURLException;
@ -28,8 +51,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.concurrent.CompletableFuture.completedFuture;
/**
* A bot adapter that can connect a bot to a service endpoint.
*
@ -50,8 +71,19 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
* {@link Middleware}
*/
public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegration, UserTokenProvider {
/**
* Key to store Activity to match .Net.
*/
private static final String INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse";
/**
* Key to store bot claims identity to match .Net.
*/
private static final String BOT_IDENTITY_KEY = "BotIdentity";
/**
* Key to store ConnectorClient to match .Net.
*/
private static final String CONNECTOR_CLIENT_KEY = "ConnectorClient";
/**
@ -277,7 +309,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
if (invokeResponse == null) {
throw new IllegalStateException("Bot failed to return a valid 'invokeResponse' activity.");
} else {
return completedFuture((InvokeResponse) invokeResponse.getValue());
return CompletableFuture.completedFuture((InvokeResponse) invokeResponse.getValue());
}
}
@ -324,7 +356,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
*/
for (int index = 0; index < activities.size(); index++) {
Activity activity = activities.get(index);
ResourceResponse response = null;
ResourceResponse response;
if (activity.isType(ActivityTypes.DELAY)) {
// The Activity Schema doesn't have a delay type build in, so it's simulated
@ -336,12 +368,15 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new RuntimeException(e);
}
// No need to create a response. One will be created below.
response = null;
} else if (activity.isType(ActivityTypes.INVOKE_RESPONSE)) {
context.getTurnState().add(INVOKE_RESPONSE_KEY, activity);
// No need to create a response. One will be created below.
response = null;
} else if (activity.isType(ActivityTypes.TRACE)
&& !StringUtils.equals(activity.getChannelId(), Channels.EMULATOR)) {
// if it is a Trace activity we only send to the channel if it's the emulator.
response = null;
} else if (!StringUtils.isEmpty(activity.getReplyToId())) {
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
response = connectorClient.getConversations().replyToActivity(activity).join();
@ -454,7 +489,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation");
}
if (StringUtils.isEmpty((context.getActivity().getConversation().getId()))) {
if (StringUtils.isEmpty(context.getActivity().getConversation().getId())) {
throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation.id");
}
@ -594,18 +629,14 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("connectionName");
}
CompletableFuture<TokenResponse> result = new CompletableFuture<>();
try {
// TODO: getUserToken
// OAuthClientOld client = createOAuthApiClient(context);
// return client.getUserToken(context.getActivity().getFrom().getId(), connectionName, magicCode);
result.completeExceptionally(new NotImplementedException("getUserToken"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
return createOAuthClient(context)
.thenCompose(oAuthClient -> {
return oAuthClient.getUserToken().getToken(
context.getActivity().getFrom().getId(),
connectionName,
context.getActivity().getChannelId(),
magicCode);
});
}
/**
@ -622,40 +653,36 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("connectionName");
}
CompletableFuture<String> result = new CompletableFuture<>();
return createOAuthClient(context)
.thenCompose(oAuthClient -> {
try {
Activity activity = context.getActivity();
try {
Activity activity = context.getActivity();
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{
setConnectionName(connectionName);
setConversation(new ConversationReference(){{
setActivityId(activity.getId());
setBot(activity.getRecipient());
setChannelId(activity.getChannelId());
setConversation(activity.getConversation());
setServiceUrl(activity.getServiceUrl());
setUser(activity.getFrom());
}});
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{
setConnectionName(connectionName);
setConversation(new ConversationReference(){{
setActivityId(activity.getId());
setBot(activity.getRecipient());
setChannelId(activity.getChannelId());
setConversation(activity.getConversation());
setServiceUrl(activity.getServiceUrl());
setUser(activity.getFrom());
}});
// TODO: on what planet would this ever be valid (from dotnet)?
//MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId,
}};
// TODO: on what planet would this ever be valid (from dotnet)?
//MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId,
}};
ObjectMapper mapper = new ObjectMapper();
String serializedState = mapper.writeValueAsString(tokenExchangeState);
byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8);
String state = BaseEncoding.base64().encode(encodedState);
ObjectMapper mapper = new ObjectMapper();
String serializedState = mapper.writeValueAsString(tokenExchangeState);
byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8);
String state = BaseEncoding.base64().encode(encodedState);
// TODO: getOauthSignInLink
// ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
// return client.getBotSignIn().getSignInUrl(state);
result.completeExceptionally(new NotImplementedException("getOauthSignInLink"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
return oAuthClient.getBotSignIn().getSignInUrl(state);
} catch (Throwable t) {
throw new CompletionException(t);
}
});
}
/**
@ -664,7 +691,7 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
* @param context Context for the current turn of conversation with the user.
* @param connectionName Name of the auth connection to use.
* @param userId The user id that will be associated with the token.
* @param finalRedirect
* @param finalRedirect The final URL that the OAuth flow will redirect to.
* @return A task that represents the work queued to execute.
*/
@Override
@ -681,43 +708,39 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("userId");
}
CompletableFuture<String> result = new CompletableFuture<>();
return createOAuthClient(context)
.thenCompose(oAuthClient -> {
try {
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{
setConnectionName(connectionName);
setConversation(new ConversationReference(){{
setActivityId(null);
setBot(new ChannelAccount() {{
setRole(RoleTypes.BOT);
}});
setChannelId(Channels.DIRECTLINE);
setConversation(new ConversationAccount());
setServiceUrl(null);
setUser(new ChannelAccount() {{
setRole(RoleTypes.USER);
setId(userId);
}});
}});
try {
TokenExchangeState tokenExchangeState = new TokenExchangeState() {{
setConnectionName(connectionName);
setConversation(new ConversationReference(){{
setActivityId(null);
setBot(new ChannelAccount() {{
setRole(RoleTypes.BOT);
}});
setChannelId(Channels.DIRECTLINE);
setConversation(new ConversationAccount());
setServiceUrl(null);
setUser(new ChannelAccount() {{
setRole(RoleTypes.USER);
setId(userId);
}});
}});
// TODO: on what planet would this ever be valid (from dotnet)?
//MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId,
}};
// TODO: on what planet would this ever be valid (from dotnet)?
//MsAppId = (_credentialProvider as MicrosoftAppCredentials)?.MicrosoftAppId,
}};
ObjectMapper mapper = new ObjectMapper();
String serializedState = mapper.writeValueAsString(tokenExchangeState);
byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8);
String state = BaseEncoding.base64().encode(encodedState);
ObjectMapper mapper = new ObjectMapper();
String serializedState = mapper.writeValueAsString(tokenExchangeState);
byte[] encodedState = serializedState.getBytes(StandardCharsets.UTF_8);
String state = BaseEncoding.base64().encode(encodedState);
// TODO: getOauthSignInLink
// ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
// return client.getBotSignIn().getSignInUrl(state);
result.completeExceptionally(new NotImplementedException("getOauthSignInLink"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
return oAuthClient.getBotSignIn().getSignInUrl(state);
} catch (Throwable t) {
throw new CompletionException(t);
}
});
}
/**
@ -734,18 +757,12 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("connectionName");
}
CompletableFuture<Void> result = new CompletableFuture<>();
try {
// TODO: signoutUser
//ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
//return client.signOutUser(context.getActivity().getFrom().getId(), connectionName);
result.completeExceptionally(new NotImplementedException("signOutUser"));
return result;
} catch (Throwable t) {
result.completeExceptionally(t);
return result;
}
return createOAuthClient(context)
.thenCompose(oAuthClient -> {
return oAuthClient.getUserToken().signOut(
context.getActivity().getFrom().getId(), connectionName, context.getActivity().getChannelId());
})
.thenApply(signOutResult -> null);
}
/**
@ -753,20 +770,24 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
*
* @param context Context for the current turn of conversation with the user.
* @param userId The user Id for which token status is retrieved.
* @param includeFilter
* @param includeFilter Optional comma separated list of connection's to include.
* Blank will return token status for all configured connections.
* @return Array of {@link TokenStatus}.
*/
@Override
public CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext context, String userId, String includeFilter) {
public CompletableFuture<List<TokenStatus>> getTokenStatus(TurnContext context,
String userId,
String includeFilter) {
BotAssert.contextNotNull(context);
if (StringUtils.isEmpty(userId)) {
throw new IllegalArgumentException("userId");
}
// TODO: getTokenStatus
CompletableFuture<TokenStatus[]> result = new CompletableFuture<>();
result.completeExceptionally(new NotImplementedException("getTokenStatus"));
return result;
return createOAuthClient(context)
.thenCompose(oAuthClient -> {
return oAuthClient.getUserToken().getTokenStatus(
userId, context.getActivity().getChannelId(), includeFilter);
});
}
/**
@ -793,17 +814,19 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
throw new IllegalArgumentException("resourceUrls");
}
String effectiveUserId = userId;
if (StringUtils.isEmpty(effectiveUserId)) {
if (context.getActivity() != null && context.getActivity().getFrom() != null) {
effectiveUserId = context.getActivity().getFrom().getId();
}
}
return createOAuthClient(context)
.thenCompose(oAuthClient -> {
String effectiveUserId = userId;
if (StringUtils.isEmpty(effectiveUserId)
&& context.getActivity() != null
&& context.getActivity().getFrom() != null) {
// TODO: getAadTokens
CompletableFuture<Map<String, TokenResponse>> result = new CompletableFuture<>();
result.completeExceptionally(new NotImplementedException("getAadTokens"));
return result;
effectiveUserId = context.getActivity().getFrom().getId();
}
return oAuthClient.getUserToken().getAadTokens(
effectiveUserId, connectionName, new AadResourceUrls(resourceUrls));
});
}
/**
@ -832,7 +855,6 @@ public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegratio
MicrosoftAppCredentials credentials,
ConversationParameters conversationParameters,
BotCallbackHandler callback) {
// TODO: all these joins are gross
return CompletableFuture.supplyAsync(() -> {
ConnectorClient connectorClient;
try {

Просмотреть файл

@ -96,7 +96,8 @@ public abstract class BotState implements PropertyManager {
if (force || cachedState == null || cachedState.getState() == null) {
return storage.read(new String[]{storageKey})
.thenApply(val -> {
turnContext.getTurnState().replace(contextServiceKey, new CachedBotState((Map<String, Object>)val.get(storageKey)));
turnContext.getTurnState().replace(
contextServiceKey, new CachedBotState((Map<String, Object>) val.get(storageKey)));
return null;
});
}
@ -128,7 +129,7 @@ public abstract class BotState implements PropertyManager {
}
CachedBotState cachedState = turnContext.getTurnState().get(contextServiceKey);
if (force || (cachedState != null && cachedState.isChanged())) {
if (force || cachedState != null && cachedState.isChanged()) {
String storageKey = getStorageKey(turnContext);
Map<String, Object> changes = new HashMap<String, Object>() {{
put(storageKey, cachedState.state);
@ -298,36 +299,43 @@ public abstract class BotState implements PropertyManager {
*/
private ObjectMapper mapper = new ObjectMapper();
public CachedBotState() {
/**
* Construct with empty state.
*/
CachedBotState() {
this(null);
}
public CachedBotState(Map<String, Object> withState) {
/**
* Construct with supplied state.
* @param withState The initial state.
*/
CachedBotState(Map<String, Object> withState) {
state = withState != null ? withState : new ConcurrentHashMap<>();
hash = computeHash(withState);
}
public Map<String, Object> getState() {
Map<String, Object> getState() {
return state;
}
public void setState(Map<String, Object> withState) {
void setState(Map<String, Object> withState) {
state = withState;
}
public String getHash() {
String getHash() {
return hash;
}
public void setHash(String witHashCode) {
void setHash(String witHashCode) {
hash = witHashCode;
}
public boolean isChanged() {
boolean isChanged() {
return !StringUtils.equals(hash, computeHash(state));
}
public String computeHash(Object obj) {
String computeHash(Object obj) {
if (obj == null) {
return "";
}
@ -345,8 +353,9 @@ public abstract class BotState implements PropertyManager {
*
* <p>Note the semantic of this accessor are intended to be lazy, this means teh Get, Set and Delete
* methods will first call LoadAsync. This will be a no-op if the data is already loaded.
* The implication is you can just use this accessor in the application code directly without first calling LoadAsync
* this approach works with the AutoSaveStateMiddleware which will save as needed at the end of a turn.
* The implication is you can just use this accessor in the application code directly without first
* calling LoadAsync this approach works with the AutoSaveStateMiddleware which will save as needed
* at the end of a turn.</p>
*
* @param <T> type of value the propertyAccessor accesses.
*/

Просмотреть файл

@ -59,8 +59,8 @@ public interface BotTelemetryClient {
* @param target External dependency target.
* @param dependencyName Name of the command initiated with this dependency call. Low cardinality value.
* Examples are stored procedure name and URL path template.
* @param data Command initiated by this dependency call. Examples are SQL statement and HTTP URL's with
* all query parameters.
* @param data Command initiated by this dependency call. Examples are SQL statement and HTTP URL's
* with all query parameters.
* @param startTime The time when the dependency was called.
* @param duration The time taken by the external dependency to handle the call.
* @param resultCode Result code of dependency call execution.

Просмотреть файл

@ -8,6 +8,9 @@ import com.microsoft.bot.schema.ConversationReference;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
/**
* A method that can participate in delete activity events for the current turn.
*/
@FunctionalInterface
public interface DeleteActivityHandler {
/**

Просмотреть файл

@ -159,7 +159,7 @@ public class RecognizerResult implements RecognizerConvert {
@Override
public void convert(Object result) {
setText(((RecognizerResult) result).getText());
setAlteredText((((RecognizerResult) result).getAlteredText()));
setAlteredText(((RecognizerResult) result).getAlteredText());
setIntents(((RecognizerResult) result).getIntents());
setEntities(((RecognizerResult) result).getEntities());

Просмотреть файл

@ -5,7 +5,6 @@ package com.microsoft.bot.builder;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.bot.connector.Channels;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes;

Просмотреть файл

@ -6,7 +6,11 @@ package com.microsoft.bot.builder;
/**
* Telemetry logger property names.
*/
public class TelemetryConstants {
public final class TelemetryConstants {
private TelemetryConstants() {
}
public static final String CHANNELIDPROPERTY = "channelId";
public static final String CONVERSATIONIDPROPERTY = "conversationId";
public static final String CONVERSATIONNAMEPROPERTY = "conversationName";

Просмотреть файл

@ -6,7 +6,11 @@ package com.microsoft.bot.builder;
/**
* The Telemetry Logger Event names.
*/
public class TelemetryLoggerConstants {
public final class TelemetryLoggerConstants {
private TelemetryLoggerConstants() {
}
/**
* The name of the event when a new message is received from the user.
*/

Просмотреть файл

@ -262,10 +262,8 @@ public class TelemetryLoggerMiddleware implements Middleware {
}};
// Use the LogPersonalInformation flag to toggle logging PII data, text is a common example
if (logPersonalInformation) {
if (!StringUtils.isEmpty(activity.getText())) {
properties.put(TelemetryConstants.TEXTPROPERTY, activity.getText());
}
if (logPersonalInformation && !StringUtils.isEmpty(activity.getText())) {
properties.put(TelemetryConstants.TEXTPROPERTY, activity.getText());
}
// Additional Properties can override "stock" properties.

Просмотреть файл

@ -10,8 +10,6 @@ import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes;
import com.microsoft.bot.schema.ChannelAccount;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.OffsetDateTime;
import java.time.ZoneId;
@ -24,8 +22,6 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* When added, this middleware will log incoming and outgoing activities to a TranscriptStore.
*/
public class TranscriptLoggerMiddleware implements Middleware {
private static final Logger logger = LoggerFactory.getLogger(TranscriptLoggerMiddleware.class);
/**
* To/From JSON.
*/

Просмотреть файл

@ -474,7 +474,7 @@ public class TurnContextImpl implements TurnContext, AutoCloseable {
public void finalize() {
try {
close();
} catch (Exception e) {
} catch (Exception ignored) {
}
}

Просмотреть файл

@ -21,12 +21,10 @@ public class TurnContextStateCollection implements AutoCloseable {
Object service = state.get(key);
try {
T result = (T) service;
return (T) service;
} catch (ClassCastException e) {
return null;
}
return (T) service;
}
/**
@ -98,7 +96,7 @@ public class TurnContextStateCollection implements AutoCloseable {
public void finalize() {
try {
close();
} catch (Exception e) {
} catch (Exception ignored) {
}
}

Просмотреть файл

@ -6,6 +6,7 @@ package com.microsoft.bot.builder;
import com.microsoft.bot.schema.TokenResponse;
import com.microsoft.bot.schema.TokenStatus;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@ -74,7 +75,7 @@ public interface UserTokenProvider {
* @param userId The user Id for which token status is retrieved.
* @return Array of TokenStatus.
*/
default CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext turnContext, String userId) {
default CompletableFuture<List<TokenStatus>> getTokenStatus(TurnContext turnContext, String userId) {
return getTokenStatus(turnContext, userId, null);
}
@ -87,7 +88,7 @@ public interface UserTokenProvider {
* for all configured connections.
* @return Array of TokenStatus.
*/
CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext turnContext, String userId, String includeFilter);
CompletableFuture<List<TokenStatus>> getTokenStatus(TurnContext turnContext, String userId, String includeFilter);
/**
* Retrieves Azure Active Directory tokens for particular resources on a configured connection.

Просмотреть файл

@ -7,28 +7,48 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ConversationReference;
public final class InspectionActivityExtensions {
final class InspectionActivityExtensions {
private InspectionActivityExtensions() {
}
public static Activity makeCommandActivity(String command) {
return Activity.createTraceActivity("Command", "https://www.botframework.com/schemas/command", command, "Command");
static Activity makeCommandActivity(String command) {
return Activity.createTraceActivity(
"Command",
"https://www.botframework.com/schemas/command",
command,
"Command");
}
public static Activity traceActivity(JsonNode state) {
return Activity.createTraceActivity("BotState", "https://www.botframework.com/schemas/botState", state, "Bot State");
static Activity traceActivity(JsonNode state) {
return Activity.createTraceActivity(
"BotState",
"https://www.botframework.com/schemas/botState",
state,
"Bot State");
}
public static Activity traceActivity(Activity activity, String name, String label) {
return Activity.createTraceActivity(name, "https://www.botframework.com/schemas/activity", activity, label);
static Activity traceActivity(Activity activity, String name, String label) {
return Activity.createTraceActivity(
name,
"https://www.botframework.com/schemas/activity",
activity,
label);
}
public static Activity traceActivity(ConversationReference conversationReference) {
return Activity.createTraceActivity("MessageDelete", "https://www.botframework.com/schemas/conversationReference", conversationReference, "Deleted Message");
static Activity traceActivity(ConversationReference conversationReference) {
return Activity.createTraceActivity(
"MessageDelete",
"https://www.botframework.com/schemas/conversationReference",
conversationReference,
"Deleted Message");
}
public static Activity traceActivity(Throwable exception) {
return Activity.createTraceActivity("TurnError", "https://www.botframework.com/schemas/error", exception.getMessage(), "Turn Error");
static Activity traceActivity(Throwable exception) {
return Activity.createTraceActivity(
"TurnError",
"https://www.botframework.com/schemas/error",
exception.getMessage(),
"Turn Error");
}
}

Просмотреть файл

@ -5,7 +5,11 @@ package com.microsoft.bot.builder.inspection;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsoft.bot.builder.*;
import com.microsoft.bot.builder.ConversationState;
import com.microsoft.bot.builder.MessageFactory;
import com.microsoft.bot.builder.StatePropertyAccessor;
import com.microsoft.bot.builder.TurnContext;
import com.microsoft.bot.builder.UserState;
import com.microsoft.bot.connector.authentication.MicrosoftAppCredentials;
import com.microsoft.bot.schema.Activity;
import com.microsoft.bot.schema.ActivityTypes;

Просмотреть файл

@ -18,14 +18,16 @@ import java.util.stream.Collectors;
public abstract class InterceptionMiddleware implements Middleware {
private Logger logger;
public static class Intercept {
public Intercept(boolean forward, boolean intercept) {
static class Intercept {
Intercept(boolean forward, boolean intercept) {
shouldForwardToApplication = forward;
shouldIntercept = intercept;
}
public boolean shouldForwardToApplication;
public boolean shouldIntercept;
@SuppressWarnings({"checkstyle:JavadocVariable", "checkstyle:VisibilityModifier"})
boolean shouldForwardToApplication;
@SuppressWarnings({"checkstyle:JavadocVariable", "checkstyle:VisibilityModifier"})
boolean shouldIntercept;
}
public InterceptionMiddleware(Logger withLogger) {
@ -125,7 +127,7 @@ public abstract class InterceptionMiddleware implements Middleware {
}
private CompletableFuture<Void> invokeTraceException(TurnContext turnContext, Activity traceActivity) {
return outbound(turnContext, Collections.singletonList(Activity.createContactRelationUpdateActivity()))
return outbound(turnContext, Collections.singletonList(traceActivity))
.exceptionally(exception -> {
logger.warn("Exception in exception interception {}", exception.getMessage());
return null;

Просмотреть файл

@ -47,8 +47,8 @@ public interface UserToken {
* @return the observable to the Map&lt;String, TokenResponse&gt; object
*/
CompletableFuture<Map<String, TokenResponse>> getAadTokens(String userId,
String connectionName,
AadResourceUrls aadResourceUrls);
String connectionName,
AadResourceUrls aadResourceUrls);
/**
*

Просмотреть файл

@ -6,6 +6,7 @@
package com.microsoft.bot.schema;
import java.util.Arrays;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
@ -19,24 +20,37 @@ public class AadResourceUrls {
@JsonProperty(value = "resourceUrls")
private List<String> resourceUrls;
/**
* Construct with var args or String[].
* @param withResourceUrl Array of urls.
*/
public AadResourceUrls(String... withResourceUrl) {
resourceUrls = Arrays.asList(withResourceUrl);
}
/**
* Construct with List of urls.
* @param withResourceUrls List of urls.
*/
public AadResourceUrls(List<String> withResourceUrls) {
resourceUrls = withResourceUrls;
}
/**
* Get the resourceUrls value.
*
* @return the resourceUrls value
*/
public List<String> resourceUrls() {
return this.resourceUrls;
public List<String> getResourceUrls() {
return resourceUrls;
}
/**
* Set the resourceUrls value.
*
* @param resourceUrls the resourceUrls value to set
* @return the AadResourceUrls object itself.
* @param withResourceUrls the resourceUrls value to set
*/
public AadResourceUrls withResourceUrls(List<String> resourceUrls) {
this.resourceUrls = resourceUrls;
return this;
public void setResourceUrls(List<String> withResourceUrls) {
resourceUrls = withResourceUrls;
}
}