Skip to content

Commit

Permalink
Merge branch 'feature/7-aws-sso-scim_user'
Browse files Browse the repository at this point in the history
  • Loading branch information
JanKoppe committed Jun 10, 2021
2 parents 1ce36da + e3c7257 commit aa7d58e
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 22 deletions.
69 changes: 69 additions & 0 deletions internal/provider/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,75 @@ func (c *APIClient) ListUsers() (*[]User, error) {
return &userLR.Resources, err
}

func (c *APIClient) CreateUser(user *User) (*User, error) {

req, err := c.newRequest("POST", "Users", "", user)

if err != nil {
return nil, err
}

var userResponse User
_, err = c.do(req, &userResponse)

return &userResponse, err
}

func (c *APIClient) PatchUser(opmsg *OperationMessage, id string) (*User, error) {

req, err := c.newRequest("PATCH", fmt.Sprintf("Users/%v", id), "", opmsg)

if err != nil {
return nil, err
}

var userResponse User
_, err = c.do(req, &userResponse)

return &userResponse, err
}

func (c *APIClient) PutUser(user *User, id string) (*User, error) {

req, err := c.newRequest("PUT", fmt.Sprintf("Users/%v", id), "", user)

if err != nil {
return nil, err
}

var userResponse User
_, err = c.do(req, &userResponse)

return &userResponse, err
}

func (c *APIClient) DeleteUser(id string) error {

req, err := c.newRequest("DELETE", fmt.Sprintf("Users/%v", id), "", nil)

if err != nil {
return err
}

_, err = c.do(req, nil)

return err
}

func (c *APIClient) ReadUser(id string) (*User, error) {

req, err := c.newRequest("GET", fmt.Sprintf("Users/%v", id), "", nil)

if err != nil {
return nil, err
}

var userResponse User
_, err = c.do(req, &userResponse)

return &userResponse, err
}

func (c *APIClient) FindUserByUsername(username string) (*User, error) {
filter := fmt.Sprintf("userName eq \"%v\"", username)

Expand Down
2 changes: 1 addition & 1 deletion internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func New(version string) func() *schema.Provider {
"aws-sso-scim_group": dataSourceGroup(),
},
ResourcesMap: map[string]*schema.Resource{
//"aws-sso-scim_user": resourceUser(),
"aws-sso-scim_user": resourceUser(),
"aws-sso-scim_group": resourceGroup(),
"aws-sso-scim_group_member": resourceGroupMember(),
},
Expand Down
156 changes: 156 additions & 0 deletions internal/provider/resource_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package provider

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceUser() *schema.Resource {
return &schema.Resource{
// This description is used by the documentation generator and the language server.
Description: "SCIM User resource.",

CreateContext: resourceUserCreate,
ReadContext: resourceUserRead,
DeleteContext: resourceUserDelete,
UpdateContext: resourceUserUpdate,

// "The givenName, familyName, userName, and displayName fields are required. "
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"given_name": {
Description: "Given Name",
Type: schema.TypeString,
Required: true,
},
"family_name": {
Description: "Family Name",
Type: schema.TypeString,
Required: true,
},
"display_name": {
Description: "Display Name",
Type: schema.TypeString,
Required: true,
},
"user_name": {
Description: "Username",
Type: schema.TypeString,
Required: true,
},
},
}
}

func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*APIClient)
diags := diag.Diagnostics{}

new_user := User{
UserName: d.Get("user_name").(string),
DisplayName: d.Get("display_name").(string),
Name: Name{
FamilyName: d.Get("family_name").(string),
GivenName: d.Get("given_name").(string),
},
}

user, err := client.CreateUser(&new_user)

if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to create User",
Detail: err.Error(),
})
return diags
}

d.SetId(user.ID)

return diags
}

func resourceUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*APIClient)
diags := diag.Diagnostics{}

user, err := client.ReadUser(d.Id())

if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to read User",
Detail: err.Error(),
})
return diags
}

d.Set("display_name", user.DisplayName)
d.Set("user_name", user.UserName)
d.Set("family_name", user.Name.FamilyName)
d.Set("given_name", user.Name.GivenName)

return diags
}

func resourceUserDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*APIClient)
diags := diag.Diagnostics{}

err := client.DeleteUser(d.Get("id").(string))

if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to delete User",
Detail: err.Error(),
})
return diags
}

return diags
}

func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*APIClient)
diags := diag.Diagnostics{}

opmsg := OperationMessage{}

required_map := map[string]string{
"user_name": "userName",
"display_name": "displayName",
"family_name": "name.familyName",
"given_name": "name.givenName",
}

for attribute, path := range required_map {
// These attributes are required and can only be replaced
if d.HasChange(attribute) {
opmsg.Operations = append(opmsg.Operations, Operation{
Operation: "replace",
Path: path,
Value: d.Get(attribute),
})
}
}

_, err := client.PatchUser(&opmsg, d.Id())

if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Unable to update User",
Detail: err.Error(),
})
return diags
}

return resourceUserRead(ctx, d, meta)
}
47 changes: 47 additions & 0 deletions internal/provider/resource_user_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package provider

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccResourceUser(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccResourceUser,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"aws-sso-scim_user.foo", "id")),
},
{
Config: testAccResourceUserUpdate,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("aws-sso-scim_user.foo", "id"),
resource.TestCheckResourceAttr("aws-sso-scim_user.foo", "display_name", "terraform-test-temporary-user-display_name2"),
),
},
},
})
}

const testAccResourceUser = `
resource "aws-sso-scim_user" "foo" {
display_name = "terraform-test-temporary-user-display_name"
user_name = "terraform-test-temporary-user-user_name"
family_name = "terraform-test-temporary-user-family_name"
given_name = "terraform-test-temporary-user-given_name"
}
`

const testAccResourceUserUpdate = `
resource "aws-sso-scim_user" "foo" {
display_name = "terraform-test-temporary-user-display_name2"
user_name = "terraform-test-temporary-user-user_name2"
family_name = "terraform-test-temporary-user-family_name2"
given_name = "terraform-test-temporary-user-given_name2"
}
`
42 changes: 21 additions & 21 deletions internal/provider/scim.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,27 @@ type Address struct {
}

type User struct {
Meta Meta `json:"meta,omitempty"`
ID string `json:"id"`
ExternalID string `json:"externalId,omitempty"`
UserName string `json:"userName"`
Name Name `json:"name,omitempty"`
DisplayName string `json:"displayName,omitempty"`
NickName string `json:"nickName,omitempty"`
ProfileURL string `json:"profileUrl,omitempty"`
Title string `json:"title,omitempty"`
UserType string `json:"userType,omitempty"`
PreferredLanguage string `json:"preferredLanguage,omitempty"`
Locale string `json:"locale,omitempty"`
Timezone string `json:"timezone,omitempty"`
Active bool `json:"active,omitempty"`
Emails []Email `json:"emails,omitempty"`
PhoneNumbers []PhoneNumber `json:"phoneNumbers,omitempty"`
Addresses []Address `json:"addresses,omitempty"`
EnterpriseUser EnterpriseUser `json:"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User,omitempty"`
Schemas []string `json:"schemas"`
Roles []string `json:"roles,omitempty"`
Groups []string `json:"groups,omitempty"`
Meta Meta `json:"meta,omitempty"`
ID string `json:"id"`
ExternalID string `json:"externalId,omitempty"`
UserName string `json:"userName"`
Name Name `json:"name,omitempty"`
DisplayName string `json:"displayName,omitempty"`
NickName string `json:"nickName,omitempty"`
ProfileURL string `json:"profileUrl,omitempty"`
Title string `json:"title,omitempty"`
UserType string `json:"userType,omitempty"`
PreferredLanguage string `json:"preferredLanguage,omitempty"`
Locale string `json:"locale,omitempty"`
Timezone string `json:"timezone,omitempty"`
Active bool `json:"active,omitempty"`
Emails []Email `json:"emails,omitempty"`
PhoneNumbers []PhoneNumber `json:"phoneNumbers,omitempty"`
Addresses []Address `json:"addresses,omitempty"`
EnterpriseUser *EnterpriseUser `json:"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User,omitempty"`
Schemas []string `json:"schemas"`
Roles []string `json:"roles,omitempty"`
Groups []string `json:"groups,omitempty"`
}

type Manager struct {
Expand Down

0 comments on commit aa7d58e

Please sign in to comment.