Skip to content

Commit b39e1c1

Browse files
When multiple organization users found, filter results for an exact match on email or login (#2285)
* if multiple organization users found, loop through results and return exact match on 'login' * update tests * fetch users via GetOrgUsersForCurrentOrg which returns email addresses * feedback: tweak error message when users are not found --------- Co-authored-by: Victor Cinaglia <[email protected]>
1 parent 0e05778 commit b39e1c1

File tree

2 files changed

+78
-12
lines changed

2 files changed

+78
-12
lines changed

internal/resources/grafana/data_source_organization_user.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,48 @@ func dataSourceOrganizationUserRead(ctx context.Context, d *schema.ResourceData,
4545
client, orgID := OAPIClientFromNewOrgResource(meta, d)
4646

4747
var resp interface {
48-
GetPayload() []*models.UserLookupDTO
48+
GetPayload() []*models.OrgUserDTO
4949
}
5050

51+
matchBy := matchByEmail
5152
emailOrLogin := d.Get("email").(string)
53+
searchType := "email"
5254
if emailOrLogin == "" {
5355
emailOrLogin = d.Get("login").(string)
56+
matchBy = matchByLogin
57+
searchType = "login"
5458
}
5559
if emailOrLogin == "" {
5660
return diag.Errorf("must specify one of email or login")
5761
}
5862

59-
params := org.NewGetOrgUsersForCurrentOrgLookupParams().WithQuery(&emailOrLogin)
60-
resp, err := client.Org.GetOrgUsersForCurrentOrgLookup(params)
63+
params := org.NewGetOrgUsersForCurrentOrgParams().WithQuery(&emailOrLogin)
64+
resp, err := client.Org.GetOrgUsersForCurrentOrg(params)
6165
if err != nil {
6266
return diag.FromErr(err)
6367
}
6468

65-
// Make sure that exactly 1 user was returned
66-
if len(resp.GetPayload()) > 1 {
67-
return diag.Errorf("ambiguous query when reading organization user, multiple users returned by query: %q", emailOrLogin)
68-
} else if len(resp.GetPayload()) == 0 {
69+
if len(resp.GetPayload()) == 0 {
6970
return diag.Errorf("organization user not found with query: %q", emailOrLogin)
7071
}
7172

72-
user := resp.GetPayload()[0]
73-
d.Set("user_id", user.UserID)
74-
d.Set("login", user.Login)
73+
for _, user := range resp.GetPayload() {
74+
if matchBy(user, emailOrLogin) {
75+
d.Set("user_id", user.UserID)
76+
d.Set("login", user.Login)
77+
d.Set("email", user.Email)
78+
d.SetId(MakeOrgResourceID(orgID, user.UserID))
79+
return nil
80+
}
81+
}
82+
83+
return diag.Errorf("no organization user found with %s: %q (users returned: %d)", searchType, emailOrLogin, len(resp.GetPayload()))
84+
}
85+
86+
func matchByEmail(user *models.OrgUserDTO, email string) bool {
87+
return user.Email == email
88+
}
7589

76-
d.SetId(MakeOrgResourceID(orgID, user.UserID))
77-
return nil
90+
func matchByLogin(user *models.OrgUserDTO, login string) bool {
91+
return user.Login == login
7892
}

internal/resources/grafana/data_source_organization_user_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,55 @@ func TestAccDatasourceOrganizationUser_basic(t *testing.T) {
3838
},
3939
})
4040
}
41+
42+
func TestAccDatasourceOrganizationUser_disambiguation(t *testing.T) {
43+
testutils.CheckOSSTestsEnabled(t)
44+
45+
var user1, user2 models.UserProfileDTO
46+
checks := []resource.TestCheckFunc{
47+
userCheckExists.exists("grafana_user.user1", &user1),
48+
userCheckExists.exists("grafana_user.user2", &user2),
49+
resource.TestCheckResourceAttr("data.grafana_organization_user.from_email", "login", "login1"),
50+
resource.TestCheckResourceAttr("data.grafana_organization_user.from_email", "email", "[email protected]"),
51+
resource.TestCheckResourceAttr("data.grafana_organization_user.from_login", "login", "log"),
52+
resource.TestCheckResourceAttr("data.grafana_organization_user.from_login", "email", "[email protected]~"),
53+
}
54+
55+
resource.ParallelTest(t, resource.TestCase{
56+
ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
57+
CheckDestroy: resource.ComposeTestCheckFunc(
58+
userCheckExists.destroyed(&user1, nil),
59+
userCheckExists.destroyed(&user2, nil),
60+
),
61+
Steps: []resource.TestStep{
62+
{
63+
Config: testAccDatasourceOrganizationUserDisambiguation,
64+
Check: resource.ComposeTestCheckFunc(checks...),
65+
},
66+
},
67+
})
68+
}
69+
70+
var testAccDatasourceOrganizationUserDisambiguation = `
71+
resource "grafana_user" "user1" {
72+
73+
name = "Test User 1"
74+
login = "login1"
75+
password = "my-password"
76+
}
77+
78+
resource "grafana_user" "user2" {
79+
email = "[email protected]~"
80+
name = "Test User 1a"
81+
login = "log"
82+
password = "my-password"
83+
}
84+
85+
data "grafana_organization_user" "from_email" {
86+
email = grafana_user.user1.email
87+
}
88+
89+
data "grafana_organization_user" "from_login" {
90+
login = grafana_user.user2.login
91+
}
92+
`

0 commit comments

Comments
 (0)