Skip to content

Commit

Permalink
Merge pull request #996 from rayterrill/280
Browse files Browse the repository at this point in the history
Add support for mail lookup
  • Loading branch information
manicminer authored Apr 13, 2023
2 parents 8c48079 + 790001f commit 2b36bc7
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 10 deletions.
3 changes: 2 additions & 1 deletion docs/data-sources/user.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
39 changes: 30 additions & 9 deletions internal/services/users/user_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,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,
},
Expand All @@ -40,7 +49,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,
},

Expand All @@ -49,7 +58,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,
},

Expand Down Expand Up @@ -173,12 +182,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,
Expand Down Expand Up @@ -344,6 +347,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 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 mail: %q", upn)
} else if count == 0 {
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 != "" {
query := odata.Query{
Filter: fmt.Sprintf("mailNickname eq '%s'", utils.EscapeSingleQuote(mailNickname)),
Expand Down
41 changes: 41 additions & 0 deletions internal/services/users/user_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,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(),
Expand Down Expand Up @@ -157,3 +176,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)
}

0 comments on commit 2b36bc7

Please sign in to comment.