Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ override.tf.json
# Environment
.env
.envrc
.devcontainer/*
68 changes: 64 additions & 4 deletions internal/auth0/action/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/auth0/go-auth0"
"github.com/auth0/go-auth0/management"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
Expand All @@ -13,6 +14,18 @@ import (
"github.com/auth0/terraform-provider-auth0/internal/config"
internalError "github.com/auth0/terraform-provider-auth0/internal/error"
)
// supportedTriggers returns the list of all supported trigger types
var supportedTriggers = []string{
"post-login",
"credentials-exchange",
"pre-user-registration",
"post-user-registration",
"post-change-password",
"send-phone-message",
"password-reset-post-challenge",
"custom-email-provider",
"custom-phone-provider",
}

// NewResource will return a new auth0_action resource.
func NewResource() *schema.Resource {
Expand Down Expand Up @@ -186,11 +199,26 @@ func updateAction(ctx context.Context, data *schema.ResourceData, meta interface
func deleteAction(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
api := meta.(*config.Config).GetAPI()

if err := api.Action.Delete(ctx, data.Id()); err != nil {
return diag.FromErr(internalError.HandleAPIError(data, err))
}
err := retry.RetryContext(ctx, data.Timeout(schema.TimeoutDelete), func() *retry.RetryError {

return nil
// Auto-unbind action
if err := unbindActionFromTriggers(ctx, api, data.Id()); err != nil {
return retry.RetryableError(fmt.Errorf("failed to unbind action: %w", err))
}

if err := api.Action.Delete(ctx, data.Id()); err != nil {
if internalError.IsStatusError(err, 409) {
return retry.RetryableError(err)
}
if apiErr := internalError.HandleAPIError(data, err); apiErr != nil {
return retry.NonRetryableError(apiErr)
}
return retry.NonRetryableError(err)
}
return nil
})

return diag.FromErr(err)
}

func deployAction(ctx context.Context, data *schema.ResourceData, meta interface{}) error {
Expand Down Expand Up @@ -232,3 +260,35 @@ func deployAction(ctx context.Context, data *schema.ResourceData, meta interface

return data.Set("version_id", actionVersion.GetID())
}

// unbindActionFromTriggers removes the action from triggers
func unbindActionFromTriggers(ctx context.Context, api *management.Management, actionID string) error {
for _, trigger := range supportedTriggers {
bindings, err := api.Action.Bindings(ctx, trigger)
if err != nil {
continue
}

// Filter out the action deleted
var filteredBindings []*management.ActionBinding
for _, binding := range bindings.Bindings {
if binding.Action.GetID() != actionID {
filteredBindings = append(filteredBindings, &management.ActionBinding{
Ref: &management.ActionBindingReference{
Type: auth0.String("action_id"),
Value: binding.Action.ID,
},
DisplayName: binding.DisplayName,
})
}
}

// Update bindings if action was found and removed
if len(filteredBindings) != len(bindings.Bindings) {
if err := api.Action.UpdateBindings(ctx, trigger, filteredBindings); err != nil {
return fmt.Errorf("failed to update %s trigger bindings: %w", trigger, err)
}
}
}
return nil
}
12 changes: 1 addition & 11 deletions internal/auth0/action/resource_trigger_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,7 @@ func NewTriggerActionResource() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
"post-login",
"credentials-exchange",
"pre-user-registration",
"post-user-registration",
"post-change-password",
"send-phone-message",
"password-reset-post-challenge",
"custom-email-provider",
"custom-phone-provider",
}, false),
ValidateFunc: validation.StringInSlice(supportedTriggers, false),
Description: "The ID of the trigger to bind with. Available options: `post-login`, `credentials-exchange`, `pre-user-registration`, `post-user-registration`, `post-change-password`, `send-phone-message`, `password-reset-post-challenge`, `custom-email-provider`, `custom-phone-provider`.",
},
"action_id": {
Expand Down
12 changes: 1 addition & 11 deletions internal/auth0/action/resource_trigger_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,7 @@ func NewTriggerActionsResource() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
"post-login",
"credentials-exchange",
"pre-user-registration",
"post-user-registration",
"post-change-password",
"send-phone-message",
"password-reset-post-challenge",
"custom-email-provider",
"custom-phone-provider",
}, false),
ValidateFunc: validation.StringInSlice(supportedTriggers, false),
Description: "The ID of the trigger to bind with. Options include: `post-login`, `credentials-exchange`, " +
"`pre-user-registration`, `post-user-registration`, `post-change-password`, `send-phone-message`, " +
"`password-reset-post-challenge`, `custom-email-provider`, `custom-phone-provider`.",
Expand Down
4 changes: 4 additions & 0 deletions internal/auth0/client/data_source_clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ func readClientsForDataSource(ctx context.Context, data *schema.ResourceData, me

func generateFilterID(nameFilter string, appTypes []string, isFirstParty bool) string {
h := sha256.New()
//lint error if possible use the below commented line
h.Write([]byte(fmt.Sprintf("%s-%v-%v", nameFilter, appTypes, isFirstParty)))
// fmt.Fprintf(h, "%s-%v-%v", nameFilter, appTypes, isFirstParty)
return fmt.Sprintf("clients-%x", h.Sum(nil))
}


9 changes: 9 additions & 0 deletions internal/error/api_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ func IsStatusNotFound(err error) bool {

return false
}

// IsStatusError checks to see if the error from the Auth0 Management API matches a specific status code.
func IsStatusError(err error, statusCode int) bool {
if mErr, ok := err.(management.Error); ok && mErr.Status() == statusCode {
return true
}

return false
}