From 8b393f0cdb69a81735afaceb93fd3ab7886e0e33 Mon Sep 17 00:00:00 2001 From: Ray Terrill Date: Thu, 2 Feb 2023 16:44:33 -0800 Subject: [PATCH 1/4] Add support for mail lookup --- internal/services/users/user_data_source.go | 39 ++++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/internal/services/users/user_data_source.go b/internal/services/users/user_data_source.go index c8d09493cc..b3dee22366 100644 --- a/internal/services/users/user_data_source.go +++ b/internal/services/users/user_data_source.go @@ -27,11 +27,20 @@ func userDataSource() *schema.Resource { }, Schema: map[string]*schema.Schema{ + "mail": { + Description: "The SMTP address for the user", + Type: schema.TypeString, + Optional: true, + ExactlyOneOf: []string{"mail", "mail_nickname", "object_id", "user_principal_name"}, + Computed: true, + ValidateDiagFunc: validate.NoEmptyStrings, + }, + "mail_nickname": { Description: "The email alias of the user", Type: schema.TypeString, Optional: true, - ExactlyOneOf: []string{"mail_nickname", "object_id", "user_principal_name"}, + ExactlyOneOf: []string{"mail", "mail_nickname", "object_id", "user_principal_name"}, Computed: true, ValidateDiagFunc: validate.NoEmptyStrings, }, @@ -41,7 +50,7 @@ func userDataSource() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"mail_nickname", "object_id", "user_principal_name"}, + ExactlyOneOf: []string{"mail", "mail_nickname", "object_id", "user_principal_name"}, ValidateDiagFunc: validate.UUID, }, @@ -50,7 +59,7 @@ func userDataSource() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"mail_nickname", "object_id", "user_principal_name"}, + ExactlyOneOf: []string{"mail", "mail_nickname", "object_id", "user_principal_name"}, ValidateDiagFunc: validate.NoEmptyStrings, }, @@ -174,12 +183,6 @@ func userDataSource() *schema.Resource { Computed: true, }, - "mail": { - Description: "The SMTP address for the user", - Type: schema.TypeString, - Computed: true, - }, - "manager_id": { Description: "The object ID of the user's manager", Type: schema.TypeString, @@ -345,6 +348,24 @@ func userDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interf return tf.ErrorDiagPathF(nil, "object_id", "User not found with object ID: %q", objectId) } user = *u + } else if mail, ok := d.Get("mail").(string); ok && mail != "" { + query := odata.Query{ + Filter: fmt.Sprintf("mail eq '%s'", utils.EscapeSingleQuote(mail)), + } + users, _, err := client.List(ctx, query) + if err != nil { + return tf.ErrorDiagF(err, "Finding user with email alias: %q", mail) + } + if users == nil { + return tf.ErrorDiagF(errors.New("API returned nil result"), "Bad API Response") + } + count := len(*users) + if count > 1 { + return tf.ErrorDiagPathF(nil, "mail", "More than one user found with email: %q", upn) + } else if count == 0 { + return tf.ErrorDiagPathF(err, "mail", "User not found with email: %q", upn) + } + user = (*users)[0] } else if mailNickname, ok := d.Get("mail_nickname").(string); ok && mailNickname != "" { query := odata.Query{ Filter: fmt.Sprintf("mailNickname eq '%s'", utils.EscapeSingleQuote(mailNickname)), From 3b518b8e2b09a478c7eee86a84e83b22a809faae Mon Sep 17 00:00:00 2001 From: Ray Terrill Date: Wed, 8 Feb 2023 19:10:18 -0800 Subject: [PATCH 2/4] Add test --- .../services/users/user_data_source_test.go | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/internal/services/users/user_data_source_test.go b/internal/services/users/user_data_source_test.go index 3e2472a8b1..a428d28323 100644 --- a/internal/services/users/user_data_source_test.go +++ b/internal/services/users/user_data_source_test.go @@ -70,6 +70,25 @@ func TestAccUserDataSource_byMailNicknameNonexistent(t *testing.T) { }}) } +func TestAccUserDataSource_byMail(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azuread_user", "test") + r := UserDataSource{} + + data.DataSourceTest(t, []resource.TestStep{{ + Config: r.byMail(data), + Check: r.testCheckFunc(data), + }}) +} + +func TestAccUserDataSource_byMailNonexistent(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azuread_user", "test") + + data.DataSourceTest(t, []resource.TestStep{{ + Config: UserDataSource{}.byMailNonexistent(data), + ExpectError: regexp.MustCompile("User not found with mail:"), + }}) +} + func (UserDataSource) testCheckFunc(data acceptance.TestData) resource.TestCheckFunc { return resource.ComposeTestCheckFunc( check.That(data.ResourceName).Key("account_enabled").Exists(), @@ -158,3 +177,25 @@ data "azuread_user" "test" { } `, data.RandomInteger) } + +func (UserDataSource) byMail(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s + +data "azuread_user" "test" { + mail = azuread_user.test.mail +} +`, UserResource{}.complete(data)) +} + +func (UserDataSource) byMailNonexistent(data acceptance.TestData) string { + return fmt.Sprintf(` +data "azuread_domains" "test" { + only_initial = true +} + +data "azuread_user" "test" { + mail = "not-a-real-user-%[1]d${data.azuread_domains.test.domains.0.domain_name}" +} +`, data.RandomInteger) +} From 611badd3e8ae45b8ed7cf4f50b207dbe7cf7f210 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 13 Apr 2023 22:12:41 +0100 Subject: [PATCH 3/4] document `mail` property for data.azuread_user --- docs/data-sources/user.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/data-sources/user.md b/docs/data-sources/user.md index 89f105b799..a3eddf0a6b 100644 --- a/docs/data-sources/user.md +++ b/docs/data-sources/user.md @@ -26,11 +26,12 @@ data "azuread_user" "example" { The following arguments are supported: +* `mail` - (Optional) The SMTP address for the user. * `mail_nickname` - (Optional) The email alias of the user. * `object_id` - (Optional) The object ID of the user. * `user_principal_name` - (Optional) The user principal name (UPN) of the user. -~> One of `user_principal_name`, `object_id` or `mail_nickname` must be specified. +~> One of `user_principal_name`, `object_id`, `mail` or `mail_nickname` must be specified. ## Attributes Reference From 790001febcaad103300c4cab486f9ac71c28f40b Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 13 Apr 2023 22:14:57 +0100 Subject: [PATCH 4/4] clean up error messages --- internal/services/users/user_data_source.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/services/users/user_data_source.go b/internal/services/users/user_data_source.go index 310131452c..3045e80606 100644 --- a/internal/services/users/user_data_source.go +++ b/internal/services/users/user_data_source.go @@ -353,16 +353,16 @@ func userDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interf } users, _, err := client.List(ctx, query) if err != nil { - return tf.ErrorDiagF(err, "Finding user with email alias: %q", mail) + return tf.ErrorDiagF(err, "Finding user with mail: %q", mail) } if users == nil { return tf.ErrorDiagF(errors.New("API returned nil result"), "Bad API Response") } count := len(*users) if count > 1 { - return tf.ErrorDiagPathF(nil, "mail", "More than one user found with email: %q", upn) + return tf.ErrorDiagPathF(nil, "mail", "More than one user found with mail: %q", upn) } else if count == 0 { - return tf.ErrorDiagPathF(err, "mail", "User not found with email: %q", upn) + return tf.ErrorDiagPathF(err, "mail", "User not found with mail: %q", upn) } user = (*users)[0] } else if mailNickname, ok := d.Get("mail_nickname").(string); ok && mailNickname != "" {