From 245024b2cae0712beec75f9bd1923f0ac211050f Mon Sep 17 00:00:00 2001 From: Adam Chalkley Date: Fri, 12 Jul 2024 06:38:23 -0500 Subject: [PATCH 1/2] Add initial support for Workflow connectors - lower `AdaptiveCardMaxVersion` from `1.5` to `1.4` - this almost seems like a bug on Teams' end as this limitation is not communicated (from what I could tell) via https://adaptivecards.io/designer/ - using a value of `1.4` appears to work equally well for O365 and Workflow connectors - treat a 202 response code as sufficient response verification - instead of expecting a `1` in the response body as previously confirmed - see also atc0005/go-teams-notify#59 - add `logic.azure.com` to valid URL patterns for default validation - debugging / troubleshooting - log status code and response string for O365 connector responses - log validation pattern match refs GH-262 --- adaptivecard/adaptivecard.go | 8 +++++++- send.go | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/adaptivecard/adaptivecard.go b/adaptivecard/adaptivecard.go index 85d29b8..40cbe4a 100644 --- a/adaptivecard/adaptivecard.go +++ b/adaptivecard/adaptivecard.go @@ -49,7 +49,13 @@ const ( // // https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference#support-for-adaptive-cards // https://adaptivecards.io/designer - AdaptiveCardMaxVersion float64 = 1.5 + // + // NOTE: Documented as 1.5 (adaptivecards.io/designer), but in practice > + // 1.4 is rejected for Power Automate workflow connectors. + // + // Setting to 1.4 works both for legacy O365 connectors and Workflow + // connectors. + AdaptiveCardMaxVersion float64 = 1.4 AdaptiveCardMinVersion float64 = 1.0 AdaptiveCardVersionTmpl string = "%0.1f" ) diff --git a/send.go b/send.go index 3348059..83822bd 100644 --- a/send.go +++ b/send.go @@ -34,6 +34,11 @@ const ( WebhookURLOrgWebhookPrefix = "https://example.webhook.office.com" ) +// Known Workflow URL patterns for submitting messages to Microsoft Teams. +const ( + WorkflowURLBaseDomain = "logic.azure.com" +) + // DisableWebhookURLValidation is a special keyword used to indicate to // validation function(s) that webhook URL validation should be disabled. // @@ -380,6 +385,7 @@ func processResponse(response *http.Response) (string, error) { } responseString := string(responseData) + // TODO: Refactor for v3 series once O365 connector support is dropped. switch { // 400 Bad Response is likely an indicator that we failed to provide a // required field in our JSON payload. For example, when leaving out the @@ -393,8 +399,22 @@ func processResponse(response *http.Response) (string, error) { return "", err - // Microsoft Teams developers have indicated that a 200 status code is - // insufficient to confirm that a message was successfully submitted. + case response.StatusCode == 202: + // 202 Accepted response is expected for Workflow connector URL + // submissions. + + logger.Println("202 Accepted response received as expected for workflow connector") + + return responseString, nil + + // DEPRECATED + // + // See https://github.com/atc0005/go-teams-notify/issues/262 + // + // Microsoft Teams developers have indicated that receiving a 200 status + // code when submitting payloads to O365 connectors is insufficient to + // confirm that a message was successfully submitted. + // // Instead, clients should ensure that a specific response string was also // returned along with a 200 status code to confirm that a message was // sent successfully. Because there is a chance that unintentional @@ -402,6 +422,11 @@ func processResponse(response *http.Response) (string, error) { // // See atc0005/go-teams-notify#59 for more information. case responseString != strings.TrimSpace(ExpectedWebhookURLResponseText): + logger.Printf( + "StatusCode: %v, Status: %v\n", response.StatusCode, response.Status, + ) + logger.Printf("ResponseString: %v\n", responseString) + err = fmt.Errorf( "got %q, expected %q: %w", responseString, @@ -432,7 +457,10 @@ func validateWebhook(webhookURL string, skipWebhookValidation bool, patterns []s } if len(patterns) == 0 { - patterns = []string{DefaultWebhookURLValidationPattern} + patterns = []string{ + DefaultWebhookURLValidationPattern, + WorkflowURLBaseDomain, + } } // Indicate passing validation if at least one pattern matches. @@ -442,6 +470,8 @@ func validateWebhook(webhookURL string, skipWebhookValidation bool, patterns []s return err } if matched { + logger.Printf("Pattern %v matched", pat) + return nil } } From 7cdd311cb312ea74ec4da95f7b4a886fb4e52c4a Mon Sep 17 00:00:00 2001 From: Adam Chalkley Date: Thu, 25 Jul 2024 05:44:20 -0500 Subject: [PATCH 2/2] Refactor regex for default Workflow URLs Switch from static base pattern of `logic.azure.com` to a regex OR pattern to permit either of `logic.azure.com` or `*.azure-api.net` as has been observed in the wild. This also has the side effect of resolving potential CodeQL alerts raised in PR GH-275. refs GH-262 --- send.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/send.go b/send.go index 83822bd..f38c23b 100644 --- a/send.go +++ b/send.go @@ -36,7 +36,7 @@ const ( // Known Workflow URL patterns for submitting messages to Microsoft Teams. const ( - WorkflowURLBaseDomain = "logic.azure.com" + WorkflowURLBaseDomain = `^https:\/\/(?:.*)(:?\.azure-api|logic\.azure)\.(?:com|net)` ) // DisableWebhookURLValidation is a special keyword used to indicate to