From 8abfb72433241891c07ae25bfda24517dfc96ba3 Mon Sep 17 00:00:00 2001 From: Danilo Ramirez Date: Fri, 22 Oct 2021 14:42:03 +1100 Subject: [PATCH 1/3] Create EscapeSingleQuote in utils --- internal/utils/odata_query_string.go | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 internal/utils/odata_query_string.go diff --git a/internal/utils/odata_query_string.go b/internal/utils/odata_query_string.go new file mode 100644 index 0000000000..2024f94d11 --- /dev/null +++ b/internal/utils/odata_query_string.go @@ -0,0 +1,11 @@ +package utils + +import "strings" + +// EscapeSingleQuote replaces all occurrences of single quote, with 2 single quotes. +// For requests that use single quotes, if any parameter values also contain single quotes, +// those must be double escaped; otherwise, the request will fail due to invalid syntax. +// https://docs.microsoft.com/en-us/graph/query-parameters#escaping-single-quotes +func EscapeSingleQuote(qparam string) string { + return strings.ReplaceAll(qparam, `'`, `''`) +} From b5a4b2a18ee667f762e782e8995225ea163e6402 Mon Sep 17 00:00:00 2001 From: Danilo Ramirez Date: Fri, 22 Oct 2021 14:42:58 +1100 Subject: [PATCH 2/3] Consume EscapeSingleQuote in user(s) data source --- internal/services/users/user_data_source.go | 5 +++-- internal/services/users/users_data_source.go | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/services/users/user_data_source.go b/internal/services/users/user_data_source.go index 54c9b3b188..58bab1c7e5 100644 --- a/internal/services/users/user_data_source.go +++ b/internal/services/users/user_data_source.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/tf" + "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/hashicorp/terraform-provider-azuread/internal/validate" ) @@ -316,7 +317,7 @@ func userDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interf if upn, ok := d.Get("user_principal_name").(string); ok && upn != "" { query := odata.Query{ - Filter: fmt.Sprintf("userPrincipalName eq '%s'", upn), + Filter: fmt.Sprintf("userPrincipalName eq '%s'", utils.EscapeSingleQuote(upn)), } users, _, err := client.List(ctx, query) if err != nil { @@ -346,7 +347,7 @@ func userDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interf user = *u } else if mailNickname, ok := d.Get("mail_nickname").(string); ok && mailNickname != "" { query := odata.Query{ - Filter: fmt.Sprintf("mailNickname eq '%s'", mailNickname), + Filter: fmt.Sprintf("mailNickname eq '%s'", utils.EscapeSingleQuote(mailNickname)), } users, _, err := client.List(ctx, query) if err != nil { diff --git a/internal/services/users/users_data_source.go b/internal/services/users/users_data_source.go index d0a4169880..087e8f470d 100644 --- a/internal/services/users/users_data_source.go +++ b/internal/services/users/users_data_source.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/tf" + "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/hashicorp/terraform-provider-azuread/internal/validate" ) @@ -179,7 +180,7 @@ func usersDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inter expectedCount = len(upns) for _, v := range upns { query := odata.Query{ - Filter: fmt.Sprintf("userPrincipalName eq '%s'", v), + Filter: fmt.Sprintf("userPrincipalName eq '%s'", utils.EscapeSingleQuote(v.(string))), } result, _, err := client.List(ctx, query) if err != nil { @@ -222,7 +223,7 @@ func usersDataSourceRead(ctx context.Context, d *schema.ResourceData, meta inter expectedCount = len(mailNicknames) for _, v := range mailNicknames { query := odata.Query{ - Filter: fmt.Sprintf("mailNickname eq '%s'", v), + Filter: fmt.Sprintf("mailNickname eq '%s'", utils.EscapeSingleQuote(v.(string))), } result, _, err := client.List(ctx, query) if err != nil { From dd251a38f6d3d88814180a4d6f2fddf74e881d5a Mon Sep 17 00:00:00 2001 From: Danilo Ramirez Date: Thu, 4 Nov 2021 12:51:38 +1100 Subject: [PATCH 3/3] Include apostrophe in UPN of "test" user in "complete()" UserResource test scenario it is used by TestAccUserDataSource_byUserPrincipalName --- internal/services/users/user_resource_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/services/users/user_resource_test.go b/internal/services/users/user_resource_test.go index 04a85e8f95..e28395a884 100644 --- a/internal/services/users/user_resource_test.go +++ b/internal/services/users/user_resource_test.go @@ -149,7 +149,7 @@ data "azuread_domains" "test" { } resource "azuread_user" "test" { - user_principal_name = "acctestUser.%[1]d@${data.azuread_domains.test.domains.0.domain_name}" + user_principal_name = "acctestUser'%[1]d@${data.azuread_domains.test.domains.0.domain_name}" display_name = "acctestUser-%[1]d" password = "%[2]s" } @@ -171,7 +171,7 @@ resource "azuread_user" "manager" { } resource "azuread_user" "test" { - user_principal_name = "acctestUser.%[1]d@${data.azuread_domains.test.domains.0.domain_name}" + user_principal_name = "acctestUser'%[1]d@${data.azuread_domains.test.domains.0.domain_name}" mail = "acctestUser.%[1]d@hashicorp.biz" mail_nickname = "acctestUser-%[1]d-MailNickname" other_mails = ["acctestUser.%[1]d@hashicorp.net", "acctestUser.%[1]d@hashicorp.org"] @@ -223,7 +223,7 @@ data "azuread_domains" "test" { } resource "azuread_user" "testA" { - user_principal_name = "acctestUser.%[1]d.A@${data.azuread_domains.test.domains.0.domain_name}" + user_principal_name = "acctestUser'%[1]d.A@${data.azuread_domains.test.domains.0.domain_name}" display_name = "acctestUser-%[1]d-A" password = "%[2]s" }