Skip to content

Commit

Permalink
Add organization data source
Browse files Browse the repository at this point in the history
Add docs
  • Loading branch information
sergiught committed Feb 10, 2023
1 parent f11337f commit b27042e
Show file tree
Hide file tree
Showing 6 changed files with 3,437 additions and 0 deletions.
57 changes: 57 additions & 0 deletions docs/data-sources/organization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
page_title: "Data Source: auth0_organization"
description: |-
Data source to retrieve a specific Auth0 organization by organization_id or name.
---

# Data Source: auth0_organization

Data source to retrieve a specific Auth0 organization by `organization_id` or `name`.



<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `name` (String) The name of the organization. If not provided, `organization_id` must be set.
- `organization_id` (String) The ID of the organization. If not provided, `name` must be set.

### Read-Only

- `branding` (List of Object) Defines how to style the login pages. (see [below for nested schema](#nestedatt--branding))
- `connections` (Set of Object) (see [below for nested schema](#nestedatt--connections))
- `display_name` (String) Friendly name of this organization.
- `id` (String) The ID of this resource.
- `members` (Set of Object) (see [below for nested schema](#nestedatt--members))
- `metadata` (Map of String) Metadata associated with the organization. Maximum of 10 metadata properties allowed.

<a id="nestedatt--branding"></a>
### Nested Schema for `branding`

Read-Only:

- `colors` (Map of String)
- `logo_url` (String)


<a id="nestedatt--connections"></a>
### Nested Schema for `connections`

Read-Only:

- `assign_membership_on_login` (Boolean)
- `connection_id` (String)


<a id="nestedatt--members"></a>
### Nested Schema for `members`

Read-Only:

- `email` (String)
- `name` (String)
- `user_id` (String)


237 changes: 237 additions & 0 deletions internal/auth0/organization/data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
package organization

import (
"context"
"net/http"

"github.com/auth0/go-auth0/management"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

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

// NewDataSource will return a new auth0_organization data source.
func NewDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: readOrganizationForDataSource,
Description: "Data source to retrieve a specific Auth0 organization by `organization_id` or `name`.",
Schema: dataSourceSchema(),
}
}

func dataSourceSchema() map[string]*schema.Schema {
dataSourceSchema := internalSchema.TransformResourceToDataSource(NewResource().Schema)
dataSourceSchema["organization_id"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "The ID of the organization. If not provided, `name` must be set.",
AtLeastOneOf: []string{"organization_id", "name"},
}

internalSchema.SetExistingAttributesAsOptional(dataSourceSchema, "name")
dataSourceSchema["name"].Description = "The name of the organization. If not provided, `organization_id` must be set."
dataSourceSchema["name"].AtLeastOneOf = []string{"organization_id", "name"}

dataSourceSchema["connections"] = &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"connection_id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the enabled connection on the organization.",
},
"assign_membership_on_login": {
Type: schema.TypeBool,
Computed: true,
Description: "When `true`, all users that log in with this connection will be " +
"automatically granted membership in the organization. When `false`, users must be " +
"granted membership in the organization before logging in with this connection.",
},
},
},
}

dataSourceSchema["members"] = &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"user_id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the organization member.",
},
"name": {
Type: schema.TypeString,
Computed: true,
Description: "The name of the organization member.",
},
"email": {
Type: schema.TypeString,
Computed: true,
Description: "The email of the organization member.",
},
},
},
}

return dataSourceSchema
}

func readOrganizationForDataSource(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
api := meta.(*management.Management)
var foundOrganization *management.Organization
var err error

organizationID := data.Get("organization_id").(string)
if organizationID != "" {
foundOrganization, err = api.Organization.Read(organizationID)
if err != nil {
if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound {
data.SetId("")
return nil
}
return diag.FromErr(err)
}
} else {
name := data.Get("name").(string)
page := 0

outerLoop:
for {
organizations, err := api.Organization.List(management.Page(page))
if err != nil {
return diag.FromErr(err)
}

for _, organization := range organizations.Organizations {
if organization.GetName() == name {
foundOrganization = organization
break outerLoop
}
}

if !organizations.HasNext() {
break
}

page++
}

if foundOrganization == nil {
return diag.Errorf("No organization found with \"name\" = %q", name)
}
}

data.SetId(foundOrganization.GetID())

result := multierror.Append(
data.Set("name", foundOrganization.GetName()),
data.Set("display_name", foundOrganization.GetDisplayName()),
data.Set("branding", flattenOrganizationBranding(foundOrganization.GetBranding())),
data.Set("metadata", foundOrganization.GetMetadata()),
)

foundConnections, err := fetchAllOrganizationConnections(api, foundOrganization.GetID())
if err != nil {
return diag.FromErr(err)
}

result = multierror.Append(
result,
data.Set("connections", flattenOrganizationConnections(foundConnections)),
)

foundMembers, err := fetchAllOrganizationMembers(api, foundOrganization.GetID())
if err != nil {
return diag.FromErr(err)
}

result = multierror.Append(
result,
data.Set("members", flattenOrganizationMembers(foundMembers)),
)

return diag.FromErr(result.ErrorOrNil())
}

func fetchAllOrganizationConnections(api *management.Management, organizationID string) ([]*management.OrganizationConnection, error) {
var foundConnections []*management.OrganizationConnection
var page int

for {
connections, err := api.Organization.Connections(organizationID, management.Page(page))
if err != nil {
return nil, err
}

foundConnections = append(foundConnections, connections.OrganizationConnections...)

if !connections.HasNext() {
break
}

page++
}

return foundConnections, nil
}

func fetchAllOrganizationMembers(api *management.Management, organizationID string) ([]management.OrganizationMember, error) {
var foundMembers []management.OrganizationMember
var page int

for {
members, err := api.Organization.Members(organizationID, management.Page(page))
if err != nil {
return nil, err
}

foundMembers = append(foundMembers, members.Members...)

if !members.HasNext() {
break
}

page++
}

return foundMembers, nil
}

func flattenOrganizationConnections(connections []*management.OrganizationConnection) []interface{} {
if connections == nil {
return nil
}

result := make([]interface{}, len(connections))
for index, connection := range connections {
result[index] = map[string]interface{}{
"connection_id": connection.GetConnectionID(),
"assign_membership_on_login": connection.GetAssignMembershipOnLogin(),
}
}

return result
}

func flattenOrganizationMembers(members []management.OrganizationMember) []interface{} {
if members == nil {
return nil
}

result := make([]interface{}, len(members))
for index, member := range members {
result[index] = map[string]interface{}{
"user_id": member.GetUserID(),
"name": member.GetName(),
"email": member.GetEmail(),
}
}

return result
}
Loading

0 comments on commit b27042e

Please sign in to comment.