forked from integrations/terraform-provider-github
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add data source to get organization members' SAML/SCIM linked i…
…dentities (integrations#1778) * add `github_organization_external_identities` which returns a list of github organization members and their SAML linked identity * add docs * add more fields to external_identities * docs --------- Co-authored-by: Keegan Campbell <[email protected]>
- Loading branch information
Showing
5 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
127 changes: 127 additions & 0 deletions
127
github/data_source_github_organization_external_identities.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package github | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/shurcooL/githubv4" | ||
) | ||
|
||
func dataSourceGithubOrganizationExternalIdentities() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceGithubOrganizationExternalIdentitiesRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"identities": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"login": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"saml_identity": { | ||
Type: schema.TypeMap, | ||
Computed: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
"scim_identity": { | ||
Type: schema.TypeMap, | ||
Computed: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceGithubOrganizationExternalIdentitiesRead(d *schema.ResourceData, meta interface{}) error { | ||
name := meta.(*Owner).name | ||
|
||
client4 := meta.(*Owner).v4client | ||
ctx := meta.(*Owner).StopContext | ||
|
||
var query struct { | ||
Organization struct { | ||
SamlIdentityProvider struct { | ||
ExternalIdentities struct { | ||
Edges []struct { | ||
Node struct { | ||
User struct { | ||
Login githubv4.String | ||
} | ||
SamlIdentity struct { | ||
NameId githubv4.String | ||
Username githubv4.String | ||
GivenName githubv4.String | ||
FamilyName githubv4.String | ||
} | ||
ScimIdentity struct { | ||
Username githubv4.String | ||
GivenName githubv4.String | ||
FamilyName githubv4.String | ||
} | ||
} | ||
} | ||
PageInfo struct { | ||
EndCursor githubv4.String | ||
HasNextPage bool | ||
} | ||
} `graphql:"externalIdentities(first: 100, after: $after)"` | ||
} | ||
} `graphql:"organization(login: $login)"` | ||
} | ||
variables := map[string]interface{}{ | ||
"login": githubv4.String(name), | ||
"after": (*githubv4.String)(nil), | ||
} | ||
|
||
var identities []map[string]interface{} | ||
|
||
for { | ||
err := client4.Query(ctx, &query, variables) | ||
if err != nil { | ||
return err | ||
} | ||
for _, edge := range query.Organization.SamlIdentityProvider.ExternalIdentities.Edges { | ||
identity := map[string]interface{}{ | ||
"login": string(edge.Node.User.Login), | ||
"saml_identity": nil, | ||
"scim_identity": nil, | ||
} | ||
|
||
if edge.Node.SamlIdentity.NameId != "" { | ||
identity["saml_identity"] = map[string]string{ | ||
"name_id": string(edge.Node.SamlIdentity.NameId), | ||
"username": string(edge.Node.SamlIdentity.Username), | ||
"given_name": string(edge.Node.SamlIdentity.GivenName), | ||
"family_name": string(edge.Node.SamlIdentity.FamilyName), | ||
} | ||
} | ||
|
||
if edge.Node.ScimIdentity.Username != "" { | ||
identity["scim_identity"] = map[string]string{ | ||
"username": string(edge.Node.ScimIdentity.Username), | ||
"given_name": string(edge.Node.ScimIdentity.GivenName), | ||
"family_name": string(edge.Node.ScimIdentity.FamilyName), | ||
} | ||
} | ||
|
||
identities = append(identities, identity) | ||
} | ||
if !query.Organization.SamlIdentityProvider.ExternalIdentities.PageInfo.HasNextPage { | ||
break | ||
} | ||
variables["after"] = githubv4.NewString(query.Organization.SamlIdentityProvider.ExternalIdentities.PageInfo.EndCursor) | ||
} | ||
|
||
d.SetId(name) | ||
d.Set("identities", identities) | ||
|
||
return nil | ||
} |
47 changes: 47 additions & 0 deletions
47
github/data_source_github_organization_external_identities_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package github | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
) | ||
|
||
func TestAccGithubOrganizationExternalIdentities(t *testing.T) { | ||
if isEnterprise != "true" { | ||
t.Skip("Skipping because `ENTERPRISE_ACCOUNT` is not set or set to false") | ||
} | ||
|
||
t.Run("queries without error", func(t *testing.T) { | ||
config := `data "github_organization_external_identities" "test" {}` | ||
|
||
check := resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("data.github_organization_external_identities.test", "identities.#"), | ||
resource.TestCheckResourceAttrSet("data.github_organization_external_identities.test", "identities.0.login"), | ||
resource.TestCheckResourceAttrSet("data.github_organization_external_identities.test", "identities.0.saml_identity.name_id"), | ||
) | ||
|
||
testCase := func(t *testing.T, mode string) { | ||
resource.Test(t, resource.TestCase{ | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: config, | ||
Check: check, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
t.Run("with an anonymous account", func(t *testing.T) { | ||
t.Skip("anonymous account not supported for this operation") | ||
}) | ||
|
||
t.Run("with an individual account", func(t *testing.T) { | ||
t.Skip("individual account not supported for this operation") | ||
}) | ||
|
||
t.Run("with an organization account", func(t *testing.T) { | ||
testCase(t, organization) | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
layout: "github" | ||
page_title: "GitHub: github_organization_external_identities" | ||
description: |- | ||
Get a list of organization members and their SAML linked external identity NameID | ||
--- | ||
|
||
# github_organization_external_identities | ||
|
||
Use this data source to retrieve each organization member's SAML or SCIM user | ||
attributes. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
data "github_organization_external_identities" "all" {} | ||
``` | ||
|
||
## Attributes Reference | ||
|
||
- `identities` - An Array of identities returned from GitHub | ||
|
||
--- | ||
|
||
Each element in the `identities` block consists of: | ||
|
||
- `login` - The username of the GitHub user | ||
- `saml_identity` - An Object containing the user's SAML data. This object will | ||
be empty if the user is not managed by SAML. | ||
- `scim_identity` - An Object contining the user's SCIM data. This object will | ||
be empty if the user is not managed by SCIM. | ||
|
||
--- | ||
|
||
If a user is managed by SAML, the `saml_identity` object will contain: | ||
|
||
- `name_id` - The member's SAML NameID | ||
- `username` - The member's SAML Username | ||
- `family_name` - The member's SAML Family Name | ||
- `given_name` - The member's SAML Given Name | ||
|
||
--- | ||
|
||
If a user is managed by SCIM, the `scim_identity` object will contain: | ||
|
||
- `scim_username` - The member's SCIM Username. (will be empty string if user is | ||
not managed by SCIM) | ||
- `scim_groups` - The member's SCIM Groups | ||
- `scim_family_name` - The member's SCIM Family Name | ||
- `scim_given_name` - The member's SCIM Given Name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters