Skip to content

Commit

Permalink
Fix import issue in auth0_user_role resource
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiught committed Jun 13, 2023
1 parent c8320fe commit a9405f9
Show file tree
Hide file tree
Showing 7 changed files with 3,921 additions and 466 deletions.
1 change: 0 additions & 1 deletion docs/resources/user_permission.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ Import is supported using the following syntax:
# This resource can be imported by specifying the
# user ID, resource identifier and permission name separated by "::" (note the double colon)
# <userID>::<resourceServerIdentifier>::<permission>

#
# Example:
terraform import auth0_user_permission.permission "auth0|111111111111111111111111::https://api.travel0.com/v1::read:posts"
Expand Down
6 changes: 4 additions & 2 deletions docs/resources/user_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ resource "auth0_user_role" "user_roles" {
Import is supported using the following syntax:

```shell
# This resource can be imported using the user ID.
# This resource can be imported by specifying the
# user ID and role ID separated by "::" (note the double colon)
# <userID>::<roleID>
#
# Example:
terraform import auth0_user_role.user_role "auth0|111111111111111111111111"
terraform import auth0_user_role.user_role "auth0|111111111111111111111111::role_123"
```
1 change: 0 additions & 1 deletion examples/resources/auth0_user_permission/import.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# This resource can be imported by specifying the
# user ID, resource identifier and permission name separated by "::" (note the double colon)
# <userID>::<resourceServerIdentifier>::<permission>

#
# Example:
terraform import auth0_user_permission.permission "auth0|111111111111111111111111::https://api.travel0.com/v1::read:posts"
6 changes: 4 additions & 2 deletions examples/resources/auth0_user_role/import.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# This resource can be imported using the user ID.
# This resource can be imported by specifying the
# user ID and role ID separated by "::" (note the double colon)
# <userID>::<roleID>
#
# Example:
terraform import auth0_user_role.user_role "auth0|111111111111111111111111"
terraform import auth0_user_role.user_role "auth0|111111111111111111111111::role_123"
15 changes: 7 additions & 8 deletions internal/auth0/user/resource_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/auth0/terraform-provider-auth0/internal/config"
internalSchema "github.com/auth0/terraform-provider-auth0/internal/schema"
)

// NewRoleResource will return a new auth0_user_role (1:1) resource.
Expand Down Expand Up @@ -46,7 +47,7 @@ func NewRoleResource() *schema.Resource {
ReadContext: readUserRole,
DeleteContext: deleteUserRole,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: internalSchema.ImportResourceGroupID(internalSchema.SeparatorDoubleColon, "user_id", "role_id"),
},
Description: "With this resource, you can manage assigned roles for a user.",
}
Expand All @@ -57,21 +58,21 @@ func createUserRole(ctx context.Context, data *schema.ResourceData, meta interfa
mutex := meta.(*config.Config).GetMutex()

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

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

roleID := data.Get("role_id").(string)
if err := api.User.AssignRoles(userID, []*management.Role{{ID: &roleID}}); err != nil {
if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound {
data.SetId("")
return nil
}

return diag.FromErr(err)
}

data.SetId(userID + internalSchema.SeparatorDoubleColon + roleID)

return readUserRole(ctx, data, meta)
}

Expand All @@ -97,6 +98,7 @@ func readUserRole(_ context.Context, data *schema.ResourceData, meta interface{}
data.Set("role_name", role.GetName()),
data.Set("role_description", role.GetDescription()),
)

return diag.FromErr(result.ErrorOrNil())
}
}
Expand All @@ -110,21 +112,18 @@ func deleteUserRole(_ context.Context, data *schema.ResourceData, meta interface
mutex := meta.(*config.Config).GetMutex()

userID := data.Get("user_id").(string)
roleID := data.Get("role_id").(string)

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

roleID := data.Get("role_id").(string)
if err := api.User.RemoveRoles(userID, []*management.Role{{ID: &roleID}}); err != nil {
if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound {
data.SetId("")
return nil
}

return diag.FromErr(err)
}

data.SetId("")

return nil
}
140 changes: 87 additions & 53 deletions internal/auth0/user/resource_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,94 +5,81 @@ import (
"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/stretchr/testify/assert"

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

const updateUserWithOneRoleAssigned = `
resource auth0_role owner {
name = "owner"
description = "Owner"
}
const updateUserWithOneRoleAssigned = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_role" "user_role-1" {
depends_on = [ auth0_user.user ]
resource auth0_user user {
depends_on = [auth0_role.owner]
user_id = auth0_user.user.id
role_id = auth0_role.owner.id
}
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
data "auth0_user" "user_data" {
depends_on = [ auth0_user_role.user_role-1 ]
lifecycle {
ignore_changes = [roles]
}
user_id = auth0_user.user.id
}
`

resource auth0_user_role user_role-1 {
const updateUserWithTwoRolesAssigned = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_role" "user_role-1" {
depends_on = [ auth0_user.user ]
user_id = auth0_user.user.id
role_id = auth0_role.owner.id
}
data auth0_user user_data {
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 updateUserWithTwoRolesAssigned = `
resource auth0_role owner {
name = "owner"
description = "Owner"
}
data "auth0_user" "user_data" {
depends_on = [ auth0_user_role.user_role-2 ]
resource auth0_role admin {
name = "admin"
description = "Administrator"
user_id = auth0_user.user.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"
const testAccUserRoleImportSetup = testAccGivenTwoRolesAndAUser + `
resource "auth0_user_roles" "user_roles" {
depends_on = [ auth0_user.user ]
lifecycle {
ignore_changes = [roles]
}
user_id = auth0_user.user.id
roles = [ auth0_role.owner.id, auth0_role.admin.id ]
}
`

resource auth0_user_role user_role-1 {
depends_on = [ auth0_user.user ]
const testAccUserRoleImportCheck = testAccUserRoleImportSetup + `
resource "auth0_user_role" "user_role-1" {
depends_on = [ auth0_user_roles.user_roles ]
user_id = auth0_user.user.id
role_id = auth0_role.owner.id
}
resource auth0_user_role user_role-2 {
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
}
data auth0_user user_data {
data "auth0_user" "user_data" {
depends_on = [ auth0_user_role.user_role-2 ]
user_id = auth0_user.user.id
}
`

const removeAssignedRolesFromUser = `
resource auth0_user user {
connection_name = "Username-Password-Authentication"
email = "{{.testName}}@acceptance.test.com"
password = "passpass$12$12"
}
`

func TestAccUserRole(t *testing.T) {
testName := strings.ToLower(t.Name())

Expand All @@ -104,8 +91,8 @@ func TestAccUserRole(t *testing.T) {
resource.TestCheckResourceAttr("data.auth0_user.user_data", "roles.#", "1"),
resource.TestCheckResourceAttrSet("auth0_user_role.user_role-1", "user_id"),
resource.TestCheckResourceAttrSet("auth0_user_role.user_role-1", "role_id"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_name", "owner"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_description", "Owner"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_name", "test-owner"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_description", "Test Owner"),
),
},
{
Expand All @@ -114,18 +101,65 @@ func TestAccUserRole(t *testing.T) {
resource.TestCheckResourceAttr("data.auth0_user.user_data", "roles.#", "2"),
resource.TestCheckResourceAttrSet("auth0_user_role.user_role-1", "user_id"),
resource.TestCheckResourceAttrSet("auth0_user_role.user_role-1", "role_id"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_name", "owner"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_description", "Owner"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_name", "test-owner"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-1", "role_description", "Test Owner"),
resource.TestCheckResourceAttrSet("auth0_user_role.user_role-2", "user_id"),
resource.TestCheckResourceAttrSet("auth0_user_role.user_role-2", "role_id"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-2", "role_name", "admin"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-2", "role_description", "Administrator"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-2", "role_name", "test-admin"),
resource.TestCheckResourceAttr("auth0_user_role.user_role-2", "role_description", "Test Administrator"),
),
},
{
Config: acctest.ParseTestName(removeAssignedRolesFromUser, testName),
Config: acctest.ParseTestName(testAccUserRolesDeleteResource, testName),
},
{
RefreshState: true,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_user.user", "roles.#", "0"),
resource.TestCheckResourceAttr("data.auth0_user.user_data", "roles.#", "0"),
),
},
{
Config: acctest.ParseTestName(testAccUserRoleImportSetup, testName),
},
{
Config: acctest.ParseTestName(testAccUserRoleImportCheck, testName),
ResourceName: "auth0_user_role.user_role-1",
ImportState: true,
ImportStateIdFunc: func(state *terraform.State) (string, error) {
userID, err := acctest.ExtractResourceAttributeFromState(state, "auth0_user.user", "id")
assert.NoError(t, err)

roleID, err := acctest.ExtractResourceAttributeFromState(state, "auth0_role.owner", "id")
assert.NoError(t, err)

return userID + "::" + roleID, nil
},
ImportStatePersist: true,
},
{
Config: acctest.ParseTestName(testAccUserRoleImportCheck, testName),
ResourceName: "auth0_user_role.user_role-2",
ImportState: true,
ImportStateIdFunc: func(state *terraform.State) (string, error) {
userID, err := acctest.ExtractResourceAttributeFromState(state, "auth0_user.user", "id")
assert.NoError(t, err)

roleID, err := acctest.ExtractResourceAttributeFromState(state, "auth0_role.admin", "id")
assert.NoError(t, err)

return userID + "::" + roleID, nil
},
ImportStatePersist: true,
},
{
Config: acctest.ParseTestName(testAccUserRoleImportCheck, testName),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectEmptyPlan(),
},
},
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.auth0_user.user_data", "roles.#", "2"),
),
},
},
Expand Down
Loading

0 comments on commit a9405f9

Please sign in to comment.