Skip to content

Commit

Permalink
Added new always_apply field to the okta_profile_mapping resource (
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdanprodan-okta committed Oct 26, 2021
1 parent 752acff commit 79a9387
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 28 deletions.
89 changes: 69 additions & 20 deletions okta/resource_okta_profile_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,14 @@ package okta

import (
"context"
"fmt"
"log"

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

var mappingResource = &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Required: true,
Description: "The mapping property key.",
},
"expression": {
Type: schema.TypeString,
Required: true,
},
"push_status": {
Type: schema.TypeString,
Optional: true,
Default: dontPush,
ValidateDiagFunc: elemInSlice([]string{push, dontPush}),
},
},
}

const (
push = "PUSH"
dontPush = "DONT_PUSH"
Expand Down Expand Up @@ -76,10 +58,36 @@ func resourceOktaProfileMapping() *schema.Resource {
Optional: true,
Elem: mappingResource,
},
"always_apply": {
Type: schema.TypeBool,
Optional: true,
Description: "Whether apply the changes to all users with this profile after updating or creating the these mappings.",
Default: false,
},
},
}
}

var mappingResource = &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Required: true,
Description: "The mapping property key.",
},
"expression": {
Type: schema.TypeString,
Required: true,
},
"push_status": {
Type: schema.TypeString,
Optional: true,
Default: dontPush,
ValidateDiagFunc: elemInSlice([]string{push, dontPush}),
},
},
}

func resourceProfileMappingCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := getSupplementFromMetadata(m)
sourceID := d.Get("source_id").(string)
Expand All @@ -100,6 +108,10 @@ func resourceProfileMappingCreate(ctx context.Context, d *schema.ResourceData, m
if err != nil {
return diag.Errorf("failed to create profile mapping: %v", err)
}
err = applyMapping(ctx, d, m, mapping)
if err != nil {
return diag.FromErr(err)
}
return resourceProfileMappingRead(ctx, d, m)
}

Expand Down Expand Up @@ -148,6 +160,10 @@ func resourceProfileMappingUpdate(ctx context.Context, d *schema.ResourceData, m
if err != nil {
return diag.Errorf("failed to update profile mapping: %v", err)
}
err = applyMapping(ctx, d, m, mapping)
if err != nil {
return diag.FromErr(err)
}
return resourceProfileMappingRead(ctx, d, m)
}

Expand Down Expand Up @@ -226,3 +242,36 @@ func buildMapping(d *schema.ResourceData) sdk.Mapping {
Properties: buildMappingProperties(d.Get("mappings").(*schema.Set)),
}
}

func applyMapping(ctx context.Context, d *schema.ResourceData, m interface{}, mapping *sdk.Mapping) error {
if !d.Get("always_apply").(bool) {
return nil
}
source := d.Get("source_id").(string)
target := d.Get("target_id").(string)
var appID string
if mapping.Source.Type == "appuser" {
appID = mapping.Source.ID
}
if mapping.Target.Type == "appuser" {
appID = mapping.Target.ID
}
appUserTypes, _, err := getSupplementFromMetadata(m).GetAppUserTypes(ctx, appID)
if err != nil {
return fmt.Errorf("failed to list app user types: %v", err)
}
if len(appUserTypes) == 0 || len(appUserTypes) > 2 {
log.Println("[WARN] mappings were not applied")
return nil
}
if mapping.Source.Type == "appuser" {
source = appUserTypes[0].Id
} else {
target = appUserTypes[0].Id
}
_, err = getSupplementFromMetadata(m).ApplyMappings(ctx, source, target)
if err != nil {
return fmt.Errorf("failed to apply mappings for source '%s' and target '%s': %v", source, target, err)
}
return nil
}
33 changes: 33 additions & 0 deletions sdk/app_user_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package sdk

import (
"context"
"fmt"
"net/http"

"github.com/okta/okta-sdk-golang/v2/okta"
)

type AppUserType struct {
Id string `json:"id"`
DisplayName string `json:"displayName"`
Name string `json:"name"`
Schemas []string `json:"schemas"`
IsDefault bool `json:"isDefault"`
Type string `json:"type"`
Links interface{} `json:"_links"`
}

func (m *APISupplement) GetAppUserTypes(ctx context.Context, appID string) ([]*AppUserType, *okta.Response, error) {
url := fmt.Sprintf("/api/v1/apps/%s/user/types", appID)
req, err := m.RequestExecutor.WithAccept("application/json").WithContentType("application/json").NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}
var appUserTypes []*AppUserType
resp, err := m.RequestExecutor.Do(ctx, req, &appUserTypes)
if err != nil {
return nil, resp, err
}
return appUserTypes, resp, nil
}
10 changes: 10 additions & 0 deletions sdk/mappings.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,13 @@ func (m *APISupplement) FindProfileMappingSource(ctx context.Context, name, typ
}
return nil, fmt.Errorf("could not locate profile mapping source with name '%s' and type '%s'", name, typ)
}

func (m *APISupplement) ApplyMappings(ctx context.Context, sourceID, targetID string) (*okta.Response, error) {
url := fmt.Sprintf("/api/internal/v1/mappings/reapply?source=%s&target=%s", sourceID, targetID)
re := m.cloneRequestExecutor()
req, err := re.WithAccept("application/json").WithContentType("application/json").NewRequest(http.MethodPut, url, nil)
if err != nil {
return nil, err
}
return re.Do(ctx, req, nil)
}
2 changes: 1 addition & 1 deletion website/docs/r/app_group_assignment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ resource "okta_app_oauth" "app" {
}
```

~> **Important:** When the `app_group_assignment` is retained, by setting `retain_assignment` to `true`, it is no longer managed by Terraform after it is destroyed. To truly delete the assignment, you will need to remove it either through the Okta Console or API. This argument exists for the use case where the same group is assigned in multiple places in order to prevent a single destruction removing all of them.
~> **IMPORTANT:** When the `app_group_assignment` is retained, by setting `retain_assignment` to `true`, it is no longer managed by Terraform after it is destroyed. To truly delete the assignment, you will need to remove it either through the Okta Console or API. This argument exists for the use case where the same group is assigned in multiple places in order to prevent a single destruction removing all of them.

## Argument Reference

Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/app_group_assignments.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ resource "okta_app_oauth" "app" {
}
```

~> **Important:** When using `okta_app_group_assignments` it is expected to manage ALL group assignments for the target application.
~> **IMPORTANT:** When using `okta_app_group_assignments` it is expected to manage ALL group assignments for the target application.

## Argument Reference

Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/app_oauth.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ The following arguments are supported:

- `logo` - (Optional) Local file path to the logo. The file must be in PNG, JPG, or GIF format, and less than 1 MB in size.

- `groups_claim` - (Optional) Groups claim for an OpenID Connect client application. **Important Note**: available only when using api token in the provider config.
- `groups_claim` - (Optional) Groups claim for an OpenID Connect client application. **IMPORTANT**: this field is available only when using api token in the provider config.
- `type` - (Required) Groups claim type. Valid values: `"FILTER"`, `"EXPRESSION"`.
- `filter_type` - (Optional) Groups claim filter. Can only be set if type is `"FILTER"`. Valid values: `"EQUALS"`, `"STARTS_WITH"`, `"CONTAINS"`, `"REGEX"`.
- `name` - (Required) Name of the claim that will be used in the token.
Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/app_user.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ lifecycle {
}
```

~> **Important:** When the `okta_app_user` is retained, by setting `retain_assignment` to `true`, it is no longer managed by Terraform after it is destroyed. To truly delete the assignment, you will need to remove it either through the Okta Console or API. This argument exists for the use case where the same user is assigned in multiple places in order to prevent a single destruction removing all of them.
~> **IMPORTANT:** When the `okta_app_user` is retained, by setting `retain_assignment` to `true`, it is no longer managed by Terraform after it is destroyed. To truly delete the assignment, you will need to remove it either through the Okta Console or API. This argument exists for the use case where the same user is assigned in multiple places in order to prevent a single destruction removing all of them.

## Example Usage

Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/org_configuration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: |-

This resource allows you manage org settings, logo, support and communication options.

~> **IMPORTANT NOTE:** You must specify all Org Setting properties when you update an org's profile. Any property not specified in the script will be deleted.
~> **IMPORTANT:** You must specify all Org Setting properties when you update an org's profile. Any property not specified in the script will be deleted.

## Example Usage

Expand Down
4 changes: 3 additions & 1 deletion website/docs/r/profile_mapping.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: |-

This resource allows you to manage a profile mapping by source and target IDs.

**Important Note**: available only when using api token in the provider config.
~> **WARNING:** This feature available only when using api token in the provider config.

## Example Usage

Expand Down Expand Up @@ -57,6 +57,8 @@ The following arguments are supported:
- `expression` - (Required) Combination or single source properties that will be mapped to the target property.
- `push_status` - (Optional) Whether to update target properties on user create & update or just on create.

- `always_apply` (Optional) Whether apply the changes to all users with this profile after updating or creating the these mappings.

## Attributes Reference

- `id` - ID of the mappings.
Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/security_notification_emails.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: |-

This resource allows you to configure Security Notification Emails.

**Important Note**: available only when using api token in the provider config.
~> **WARNING:** This resource is available only when using api token in the provider config.

## Example Usage

Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/user_base_schema_property.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Manages a User Base Schema property.

This resource allows you to configure a base user schema property.

IMPORTANT NOTE:
## IMPORTANT NOTE:

Based on the [official documentation](https://developer.okta.com/docs/reference/api/schemas/#user-profile-base-subschema)
base properties can not be modified, except to update permissions, to change the nullability of `firstName` and
Expand Down

0 comments on commit 79a9387

Please sign in to comment.