Skip to content

Commit

Permalink
Refactor auth0_user_roles resource and its tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiught committed Jun 13, 2023
1 parent c04911d commit 88bcc92
Show file tree
Hide file tree
Showing 5 changed files with 4,381 additions and 1,767 deletions.
34 changes: 19 additions & 15 deletions internal/auth0/user/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func createUser(ctx context.Context, d *schema.ResourceData, m interface{}) diag

d.SetId(user.GetID())

if err = persistUserRoles(d, api); err != nil {
if err = persistUserRoles(d, m); err != nil {
return diag.FromErr(err)
}

Expand All @@ -289,7 +289,7 @@ func updateUser(ctx context.Context, d *schema.ResourceData, m interface{}) diag
}
}

if err = persistUserRoles(d, api); err != nil {
if err = persistUserRoles(d, m); err != nil {
return diag.Errorf("failed assigning user roles. %s", err)
}

Expand Down Expand Up @@ -473,21 +473,21 @@ func validateNoPasswordAndEmailVerifiedSimultaneously() validateUserFunc {
}
}

func persistUserRoles(d *schema.ResourceData, api *management.Management) error {
func persistUserRoles(d *schema.ResourceData, meta interface{}) error {
if !d.HasChange("roles") {
return nil
}

rolesToAdd, rolesToRemove := value.Difference(d, "roles")

if err := removeUserRoles(api, d.Id(), rolesToRemove); err != nil {
if err := removeUserRoles(meta, d.Id(), rolesToRemove); err != nil {
return err
}

return assignUserRoles(api, d.Id(), rolesToAdd)
return assignUserRoles(meta, d.Id(), rolesToAdd)
}

func removeUserRoles(api *management.Management, userID string, userRolesToRemove []interface{}) error {
func removeUserRoles(meta interface{}, userID string, userRolesToRemove []interface{}) error {
if len(userRolesToRemove) == 0 {
return nil
}
Expand All @@ -498,18 +498,16 @@ func removeUserRoles(api *management.Management, userID string, userRolesToRemov
rmRoles = append(rmRoles, role)
}

err := api.User.RemoveRoles(userID, rmRoles)
if err != nil {
// Ignore 404 errors as the role may have been deleted prior to un-assigning them from the user.
if err, ok := err.(management.Error); ok && err.Status() == http.StatusNotFound {
return nil
}
}
api := meta.(*config.Config).GetAPI()
mutex := meta.(*config.Config).GetMutex()

mutex.Lock(userID)
defer mutex.Unlock(userID)

return err
return api.User.RemoveRoles(userID, rmRoles)
}

func assignUserRoles(api *management.Management, userID string, userRolesToAdd []interface{}) error {
func assignUserRoles(meta interface{}, userID string, userRolesToAdd []interface{}) error {
if len(userRolesToAdd) == 0 {
return nil
}
Expand All @@ -521,6 +519,12 @@ func assignUserRoles(api *management.Management, userID string, userRolesToAdd [
addRoles = append(addRoles, role)
}

api := meta.(*config.Config).GetAPI()
mutex := meta.(*config.Config).GetMutex()

mutex.Lock(userID)
defer mutex.Unlock(userID)

return api.User.AssignRoles(userID, addRoles)
}

Expand Down
17 changes: 8 additions & 9 deletions internal/auth0/user/resource_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,18 @@ func NewRolesResource() *schema.Resource {
}

func upsertUserRoles(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
api := meta.(*config.Config).GetAPI()
mutex := meta.(*config.Config).GetMutex()

userID := data.Get("user_id").(string)
data.SetId(userID)

mutex.Lock(userID)
defer mutex.Unlock(userID)
if err := persistUserRoles(data, meta); err != nil {
if err, ok := err.(management.Error); ok && err.Status() == http.StatusNotFound {
data.SetId("")
return nil
}

if err := persistUserRoles(data, api); err != nil {
return diag.FromErr(err)
}

userID := data.Get("user_id").(string)
data.SetId(userID)

return readUserRoles(ctx, data, meta)
}

Expand Down
189 changes: 69 additions & 120 deletions internal/auth0/user/resource_roles_test.go
Original file line number Diff line number Diff line change
@@ -1,115 +1,121 @@
package user_test

import (
"os"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/terraform"

"github.com/auth0/terraform-provider-auth0/internal/acctest"
)

const testAccUserRolesUpdateUserWithOneRoleAssigned = `
resource auth0_role owner {
name = "owner"
description = "Owner"
const testAccGivenTwoRolesAndAUser = `
resource "auth0_role" "owner" {
name = "test-owner"
description = "Test Owner"
}
resource auth0_user user {
depends_on = [auth0_role.owner]
resource "auth0_role" "admin" {
name = "test-admin"
description = "Test Administrator"
}
resource "auth0_user" "user" {
depends_on = [ auth0_role.owner, auth0_role.admin ]
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
lifecycle {
ignore_changes = [roles]
}
}
`

resource auth0_user_roles user_roles {
const testAccUserRolesUpdateUserWithOneRoleAssigned = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_roles" "user_roles" {
depends_on = [ auth0_user.user ]
user_id = auth0_user.user.id
roles = [auth0_role.owner.id]
roles = [ auth0_role.owner.id ]
}
data auth0_user user_data {
depends_on = [auth0_user_roles.user_roles]
data "auth0_user" "user_data" {
depends_on = [ auth0_user_roles.user_roles ]
user_id = auth0_user.user.id
}
`

const testAccUserRolesUpdateUserWithTwoRolesAssigned = `
resource auth0_role owner {
name = "owner"
description = "Owner"
}
const testAccUserRolesUpdateUserWithTwoRolesAssigned = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_roles" "user_roles" {
depends_on = [ auth0_user.user ]
resource auth0_role admin {
name = "admin"
description = "Administrator"
user_id = auth0_user.user.id
roles = [auth0_role.owner.id, auth0_role.admin.id]
}
resource auth0_user user {
depends_on = [auth0_role.owner, auth0_role.admin]
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
data "auth0_user" "user_data" {
depends_on = [auth0_user_roles.user_roles]
lifecycle {
ignore_changes = [roles]
}
user_id = auth0_user.user.id
}
`

resource auth0_user_roles user_roles {
const testAccUserRolesUpdateUserWithNoRolesAssigned = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_roles" "user_roles" {
depends_on = [ auth0_user.user ]
user_id = auth0_user.user.id
roles = [auth0_role.owner.id, auth0_role.admin.id]
roles = []
}
data auth0_user user_data {
data "auth0_user" "user_data" {
depends_on = [auth0_user_roles.user_roles]
user_id = auth0_user.user.id
}
`

const testAccUserRolesUpdateUserWithNoRolesAssigned = `
resource auth0_user user {
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
const testAccUserRolesDeleteResource = testAccGivenTwoRolesAndAUser + `
data "auth0_user" "user_data" {
depends_on = [ auth0_user.user ]
lifecycle {
ignore_changes = [roles]
}
user_id = auth0_user.user.id
}
`

resource auth0_user_roles user_roles {
const testAccUserRolesImportSetup = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_role" "user_role-1" {
depends_on = [ auth0_user.user ]
user_id = auth0_user.user.id
roles = []
role_id = auth0_role.owner.id
}
data auth0_user user_data {
depends_on = [auth0_user_roles.user_roles]
resource "auth0_user_role" "user_role-2" {
depends_on = [ auth0_user_role.user_role-1 ]
user_id = auth0_user.user.id
role_id = auth0_role.admin.id
}
`

const testAccUserRolesDeleteResource = `
resource auth0_user user {
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
const testAccUserRolesImportCheck = testAccUserRolesImportSetup + `
resource "auth0_user_roles" "user_roles" {
depends_on = [ auth0_user_role.user_role-2 ]
user_id = auth0_user.user.id
roles = [ auth0_role.owner.id, auth0_role.admin.id ]
}
data "auth0_user" "user_data" {
depends_on = [auth0_user_roles.user_roles]
user_id = auth0_user.user.id
}
`

Expand Down Expand Up @@ -148,91 +154,34 @@ func TestAccUserRoles(t *testing.T) {
},
{
Config: acctest.ParseTestName(testAccUserRolesDeleteResource, testName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_user.user", "roles.#", "0"),
),
},
},
})
}

const testAccUserRolesImport = `
resource auth0_role owner {
name = "owner"
description = "Owner"
}
resource auth0_role admin {
name = "admin"
description = "Administrator"
}
resource auth0_user user {
depends_on = [auth0_role.owner, auth0_role.admin]
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
lifecycle {
ignore_changes = [ roles, connection_name, password ]
}
}
resource auth0_user_roles user_roles {
depends_on = [ auth0_user.user ]
user_id = auth0_user.user.id
roles = [ auth0_role.owner.id, auth0_role.admin.id ]
}
`

func TestAccUserRolesImport(t *testing.T) {
if os.Getenv("AUTH0_DOMAIN") != acctest.RecordingsDomain {
// The test runs only with recordings as it requires an initial setup.
t.Skip()
}

testName := strings.ToLower(t.Name())

acctest.Test(t, resource.TestCase{
Steps: []resource.TestStep{
{
Config: acctest.ParseTestName(testAccUserRolesImport, testName),
ResourceName: "auth0_role.owner",
ImportState: true,
ImportStateId: "rol_XLLMqPwfx8kdG63e",
ImportStatePersist: true,
},
{
Config: acctest.ParseTestName(testAccUserRolesImport, testName),
ResourceName: "auth0_role.admin",
ImportState: true,
ImportStateId: "rol_LjLyGzVZE5K34IaY",
ImportStatePersist: true,
RefreshState: true,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.auth0_user.user_data", "roles.#", "0"),
),
},
{
Config: acctest.ParseTestName(testAccUserRolesImport, testName),
ResourceName: "auth0_user.user",
ImportState: true,
ImportStateId: "auth0|646cbae1e37ebde3a5ad6fd0",
ImportStatePersist: true,
Config: acctest.ParseTestName(testAccUserRolesImportSetup, testName),
},
{
Config: acctest.ParseTestName(testAccUserRolesImport, testName),
ResourceName: "auth0_user_roles.user_roles",
ImportState: true,
ImportStateId: "auth0|646cbae1e37ebde3a5ad6fd0",
Config: acctest.ParseTestName(testAccUserRolesImportCheck, testName),
ResourceName: "auth0_user_roles.user_roles",
ImportState: true,
ImportStateIdFunc: func(state *terraform.State) (string, error) {
return acctest.ExtractResourceAttributeFromState(state, "auth0_user.user", "id")
},
ImportStatePersist: true,
},
{
Config: acctest.ParseTestName(testAccUserRolesImportCheck, testName),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectEmptyPlan(),
},
},
Config: acctest.ParseTestName(testAccUserRolesImport, testName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.auth0_user.user_data", "roles.#", "2"),
resource.TestCheckResourceAttr("auth0_user_roles.user_roles", "roles.#", "2"),
),
},
Expand Down
Loading

0 comments on commit 88bcc92

Please sign in to comment.