Skip to content

Commit

Permalink
Merge pull request #81 from Infisical/daniel/oidc-identity-bug
Browse files Browse the repository at this point in the history
fix(oidc-auth): comma formatted bound claims required space formatting
  • Loading branch information
DanielHougaard authored Dec 16, 2024
2 parents 83ef708 + 3c8e9a9 commit 6601b93
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 6 deletions.
97 changes: 97 additions & 0 deletions internal/pkg/modifiers/comma_space_map_modifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package pkg

import (
"context"
"strings"

"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
)

// CommaSpaceMapModifier ensures consistent formatting of comma-separated strings in map values.
type CommaSpaceMapModifier struct{}

func (m CommaSpaceMapModifier) Description(ctx context.Context) string {
return "Ensures consistent formatting of comma-separated strings in map values with spaces after commas"
}

func (m CommaSpaceMapModifier) MarkdownDescription(ctx context.Context) string {
return "Ensures consistent formatting of comma-separated strings in map values with spaces after commas"
}

func (m CommaSpaceMapModifier) PlanModifyMap(ctx context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) {
if req.PlanValue.IsUnknown() || req.PlanValue.IsNull() {
return
}

planElements := req.PlanValue.Elements()
newElements := make(map[string]types.String)

// Track config format for each key
configFormats := make(map[string]bool)

// Detect config format for each key
if !req.ConfigValue.IsNull() {
configElements := req.ConfigValue.Elements()
for key, v := range configElements {
if str, ok := v.(types.String); ok && !str.IsNull() {
configFormats[key] = strings.Contains(str.ValueString(), ", ")
}
}
}

// Fallback to state value if config format not found
if !req.StateValue.IsNull() {
stateElements := req.StateValue.Elements()
for key, v := range stateElements {
if _, exists := configFormats[key]; !exists {
if str, ok := v.(types.String); ok && !str.IsNull() {
configFormats[key] = strings.Contains(str.ValueString(), ", ")
}
}
}
}

for key, value := range planElements {
strValue, ok := value.(types.String)
if !ok {
continue
}

if !strValue.IsNull() && !strValue.IsUnknown() {
parts := strings.Split(strValue.ValueString(), ",")
for i, part := range parts {
parts[i] = strings.TrimSpace(part)
}

useSpaces, found := configFormats[key]
if !found {
useSpaces = false
}

var formattedValue string
if useSpaces {
formattedValue = strings.Join(parts, ", ")
} else {
formattedValue = strings.Join(parts, ",")
}

newElements[key] = types.StringValue(formattedValue)
} else {
newElements[key] = strValue
}
}

newMapValue, diags := types.MapValueFrom(ctx, types.StringType, newElements)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

resp.PlanValue = newMapValue
}

// CommaSpaceMap returns a new instance of CommaSpaceMapModifier.
func CommaSpaceMap() CommaSpaceMapModifier {
return CommaSpaceMapModifier{}
}
37 changes: 31 additions & 6 deletions internal/provider/resource/identity_oidc_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"
infisical "terraform-provider-infisical/internal/client"
infisicalclient "terraform-provider-infisical/internal/client"
pkg "terraform-provider-infisical/internal/pkg/modifiers"
infisicalstrings "terraform-provider-infisical/internal/pkg/strings"
"terraform-provider-infisical/internal/pkg/terraform"

Expand Down Expand Up @@ -88,11 +89,14 @@ func (r *IdentityOidcAuthResource) Schema(_ context.Context, _ resource.SchemaRe
PlanModifiers: []planmodifier.List{listplanmodifier.UseStateForUnknown()},
},
"bound_claims": schema.MapAttribute{
Description: "The attributes that should be present in the JWT for it to be valid. The provided values can be a glob pattern.",
Optional: true,
Computed: true,
ElementType: types.StringType,
PlanModifiers: []planmodifier.Map{mapplanmodifier.UseStateForUnknown()},
Description: "The attributes that should be present in the JWT for it to be valid. The provided values can be a glob pattern.",
Optional: true,
Computed: true,
ElementType: types.StringType,
PlanModifiers: []planmodifier.Map{
mapplanmodifier.UseStateForUnknown(),
pkg.CommaSpaceMapModifier{},
},
},
"bound_subject": schema.StringAttribute{
Description: "The expected principal that is the subject of the JWT.",
Expand Down Expand Up @@ -175,7 +179,28 @@ func updateOidcAuthStateByApi(ctx context.Context, diagnose diag.Diagnostics, pl

boundClaimsElements := make(map[string]attr.Value)
for key, value := range newIdentityOidcAuth.BoundClaims {
boundClaimsElements[key] = types.StringValue(value)
// Check plan format
useSpaces := false
if !plan.BoundClaims.IsNull() {
if planValue, ok := plan.BoundClaims.Elements()[key]; ok {
if planStr, ok := planValue.(types.String); ok {
useSpaces = strings.Contains(planStr.ValueString(), ", ")
}
}
}

// Split and normalize
parts := strings.Split(value, ",")
for i, part := range parts {
parts[i] = strings.TrimSpace(part)
}

// Use the same format as the plan
if useSpaces {
boundClaimsElements[key] = types.StringValue(strings.Join(parts, ", "))
} else {
boundClaimsElements[key] = types.StringValue(strings.Join(parts, ","))
}
}

boundClaimsMapValue, diags := types.MapValue(types.StringType, boundClaimsElements)
Expand Down

0 comments on commit 6601b93

Please sign in to comment.