Skip to content
This repository has been archived by the owner on Mar 8, 2022. It is now read-only.

Fix role and permission handling #149

Merged
merged 1 commit into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions auth0/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package auth0

import (
"os"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"gopkg.in/auth0.v2/management"
)
Expand Down Expand Up @@ -57,10 +55,6 @@ func Provider() *schema.Provider {
}
}

func TestMain(m *testing.M) {
resource.TestMain(m)
}

func configure(data *schema.ResourceData) (interface{}, error) {

domain := data.Get("domain").(string)
Expand Down
106 changes: 49 additions & 57 deletions auth0/resource_auth0_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,23 @@ func newRole() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
ForceNew: true,
Removed: `This field has been removed. Use "auth0_user.roles" instead`,
},
"permissions": {
Type: schema.TypeList,
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Required: true,
},
"resource_server_identifier": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Required: true,
},
},
},
Optional: true,
},
},
}
Expand All @@ -66,40 +65,20 @@ func createRole(d *schema.ResourceData, m interface{}) error {
if err := api.Role.Create(c); err != nil {
return err
}
d.SetId(auth0.StringValue(c.ID))

// Enable partial state mode. Sub-resources can potentially cause partial
// state. Therefore we must explicitly tell Terraform what is safe to
// persist and what is not.
//
// See: https://www.terraform.io/docs/extend/writing-custom-providers.html
d.Partial(true)

if d.HasChange("user_ids") {
users := buildUsers(d)
if len(users) > 0 {
err := api.Role.AssignUsers(*c.ID, users...)
if err != nil {
return err
}
}
d.SetPartial("user_ids")
}

if d.HasChange("permissions") {
permissions := buildPermissions(d)
if len(permissions) > 0 {
err := api.Role.AssociatePermissions(*c.ID, permissions...)
if err != nil {
return err
}
}
d.SetPartial("permissions")
if err := assignRolePermissions(d, m); err != nil {
return err
}

// We succeeded, disable partial mode. This causes Terraform to save
// all fields again.
d.Partial(false)
d.SetId(auth0.StringValue(c.ID))

return readRole(d, m)
}
Expand All @@ -116,22 +95,10 @@ func readRole(d *schema.ResourceData, m interface{}) error {
d.Set("name", c.Name)
d.Set("description", c.Description)

users, err := api.Role.Users(d.Id())
if err != nil {
return err
}

userIDs := []string{}
for _, user := range users {
userIDs = append(userIDs, *user.ID)
}
d.Set("user_ids", userIDs)

permissions, err := api.Role.Permissions(d.Id())
if err != nil {
return err
}

d.Set("permissions", func() (m []map[string]interface{}) {
for _, permission := range permissions {
m = append(m, map[string]interface{}{
Expand All @@ -141,6 +108,7 @@ func readRole(d *schema.ResourceData, m interface{}) error {
}
return m
}())

return nil
}

Expand All @@ -151,6 +119,11 @@ func updateRole(d *schema.ResourceData, m interface{}) error {
if err != nil {
return err
}
d.Partial(true)
if err := assignRolePermissions(d, m); err != nil {
return err
}
d.Partial(false)
return readRole(d, m)
}

Expand All @@ -167,25 +140,44 @@ func buildRole(d *schema.ResourceData) *management.Role {
}
}

func buildUsers(d *schema.ResourceData) []*management.User {
var users []*management.User
for _, val := range Slice(d, "user_ids") {
userID, _ := val.(string)
users = append(users, &management.User{
ID: &userID,
func assignRolePermissions(d *schema.ResourceData, m interface{}) error {

add, rm := Diff(d, "permissions")

var addPermissions []*management.Permission
for _, addPermission := range add {
permission := addPermission.(map[string]interface{})
addPermissions = append(addPermissions, &management.Permission{
Name: auth0.String(permission["name"].(string)),
ResourceServerIdentifier: auth0.String(permission["resource_server_identifier"].(string)),
})
}
return users
}

func buildPermissions(d *schema.ResourceData) []*management.Permission {
var permissions []*management.Permission
for _, val := range Slice(d, "permissions") {
permission := val.(map[string]interface{})
permissions = append(permissions, &management.Permission{
Name: String(MapData(permission), "name"),
ResourceServerIdentifier: String(MapData(permission), "resource_server_identifier"),
var rmPermissions []*management.Permission
for _, rmPermission := range rm {
permission := rmPermission.(map[string]interface{})
rmPermissions = append(rmPermissions, &management.Permission{
Name: auth0.String(permission["name"].(string)),
ResourceServerIdentifier: auth0.String(permission["resource_server_identifier"].(string)),
})
}
return permissions

api := m.(*management.Management)

if len(rmPermissions) > 0 {
err := api.Role.RemovePermissions(d.Id(), rmPermissions...)
if err != nil {
return err
}
}

if len(addPermissions) > 0 {
err := api.Role.AssociatePermissions(d.Id(), addPermissions...)
if err != nil {
return err
}
}

d.SetPartial("permissions")
return nil
}
92 changes: 54 additions & 38 deletions auth0/resource_auth0_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,60 +15,76 @@ func TestAccRole(t *testing.T) {
},
Steps: []resource.TestStep{
{
Config: testAccRoleCreate,
Config: testAccRole_create,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_role.my_role", "name", "Application - Role Acceptance Test"),
resource.TestCheckResourceAttr("auth0_role.my_role", "description", "Test Applications Role Long Description"),
resource.TestCheckResourceAttr("auth0_role.the_one", "name", "The One - Role - Acceptance Test"),
resource.TestCheckResourceAttr("auth0_role.the_one", "description", "The One - Role - Acceptance Test"),
resource.TestCheckResourceAttr("auth0_role.the_one", "permissions.#", "1"),
),
},
{
Config: testAccRoleUpdate,
Config: testAccRole_update,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("auth0_role.my_role", "description", "Test Applications Role Long Description And Then Some"),
resource.TestCheckResourceAttr("auth0_role.my_role", "user_ids.0", "auth0|neo"),
resource.TestCheckResourceAttr("auth0_role.my_role", "user_ids.1", "auth0|trinity"),
resource.TestCheckResourceAttr("auth0_role.the_one", "description", "The One who will bring peace - Role - Acceptance Test"),
resource.TestCheckResourceAttr("auth0_role.the_one", "permissions.#", "2"),
),
},
},
})
}

const testAccRoleCreate = `
provider "auth0" {}
const testAccRole_create = `
provider auth0 {}

resource "auth0_role" "my_role" {
name = "Application - Role Acceptance Test"
description = "Test Applications Role Long Description"
resource auth0_resource_server matrix {
name = "The One - Resource Server - Acceptance Test"
identifier = "https://matrix.com/"
scopes {
value = "stop:bullets"
description = "Stop bullets"
}
scopes {
value = "bring:peace"
description = "Bring peace"
}
}

resource auth0_role the_one {
name = "The One - Role - Acceptance Test"
description = "The One - Role - Acceptance Test"
permissions {
name = "stop:bullets"
resource_server_identifier = auth0_resource_server.matrix.identifier
}
}
`

const testAccRoleUpdate = `
provider "auth0" {}

resource "auth0_user" "neo" {
connection_name = "Username-Password-Authentication"
email = "neo@matrix.com"
username = "neo"
nickname = "neo"
password = "IAmThe#1"
user_id = "neo"
}
const testAccRole_update = `
provider auth0 {}

resource "auth0_user" "trinity" {
connection_name = "Username-Password-Authentication"
email = "trinity@matrix.com"
username = "trinity"
nickname = "trinity"
password = "TheM4trixH4$Y0u"
user_id = "trinity"
}
resource auth0_resource_server matrix {
name = "The One - Resource Server - Acceptance Test"
identifier = "https://matrix.com/"
scopes {
value = "stop:bullets"
description = "Create bars"
}
scopes {
value = "bring:peace"
description = "Bring peace"
}
}

resource "auth0_role" "my_role" {
name = "Application Role Acceptance Test"
description = "Test Applications Role Long Description And Then Some"
user_ids = [
auth0_user.neo.id,
auth0_user.trinity.id
]
resource auth0_role the_one {
name = "The One - Role - Acceptance Test"
description = "The One who will bring peace - Role - Acceptance Test"
permissions {
name = "stop:bullets"
resource_server_identifier = auth0_resource_server.matrix.identifier
}
permissions {
name = "bring:peace"
resource_server_identifier = auth0_resource_server.matrix.identifier
}
}
`
Loading