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

Commit

Permalink
Merge pull request #149 from alexkappa/fix-role-user_ids
Browse files Browse the repository at this point in the history
Fix role and permission handling
  • Loading branch information
alexkappa authored Dec 13, 2019
2 parents 2013ce5 + 54b3677 commit 37e17fe
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 160 deletions.
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

0 comments on commit 37e17fe

Please sign in to comment.