8000 fix(adyen): fix missing hmac key when pod is restarted by paul-nicolas · Pull Request #446 · formancehq/payments · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix(adyen): fix missing hmac key when pod is restarted #446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
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
5 changes: 2 additions & 3 deletions internal/connectors/plugins/public/adyen/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import (
//go:generate mockgen -source client.go -destination client_generated.go -package client . Client
type Client interface {
GetMerchantAccounts(ctx context.Context, pageNumber, pageSize int32) ([]management.Merchant, error)
CreateWebhook(ctx context.Context, url string, connectorID string) error
CreateWebhook(ctx context.Context, url string, connectorID string) (CreateWebhookResponse, error)
VerifyWebhookBasicAuth(basicAuth *models.BasicAuth) bool
VerifyWebhookHMAC(item webhook.NotificationItem) bool
VerifyWebhookHMAC(item webhook.NotificationItem, hmacKey string) bool
DeleteWebhook(ctx context.Context, connectorID string) error
TranslateWebhook(req string) (*webhook.Webhook, error)
}
Expand All @@ -34,7 +34,6 @@ type client struct {
companyID string

standardWebhook *management.Webhook
hmacKey string
}

func New(
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 15 additions & 10 deletions internal/connectors/plugins/public/adyen/client/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,21 @@
return nil
}

func (c *client) CreateWebhook(ctx context.Context, url string, connectorID string) error {
type CreateWebhookResponse struct {
HMACKey string
}

func (c *client) CreateWebhook(ctx context.Context, url string, connectorID string) (CreateWebhookResponse, error) {

Check warning on line 58 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L58

Added line #L58 was not covered by tests
if c.standardWebhook != nil {
return nil
return CreateWebhookResponse{}, nil

Check warning on line 60 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L60

Added line #L60 was not covered by tests
}

if err := c.searchWebhook(ctx, connectorID); err != nil {
return err
return CreateWebhookResponse{}, err

Check warning on line 64 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L64

Added line #L64 was not covered by tests
}

if c.standardWebhook != nil {
return nil
return CreateWebhookResponse{}, nil

Check warning on line 68 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L68

Added line #L68 was not covered by tests
}

req := management.CreateCompanyWebhookRequest{
Expand All @@ -88,21 +92,22 @@
CreateCompanyWebhookRequest(req),
)
if err != nil {
return c.wrapSDKError(err, raw.StatusCode)
return CreateWebhookResponse{}, c.wrapSDKError(err, raw.StatusCode)

Check warning on line 95 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L95

Added line #L95 was not covered by tests
}

hmac, raw, err := c.client.Management().WebhooksCompanyLevelApi.GenerateHmacKey(
metrics.OperationContext(ctx, "create_hook_hmac_key"),
c.client.Management().WebhooksCompanyLevelApi.GenerateHmacKeyInput(c.companyID, *webhook.Id),
)
if err != nil {
return c.wrapSDKError(err, raw.StatusCode)
return CreateWebhookResponse{}, c.wrapSDKError(err, raw.StatusCode)

Check warning on line 103 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L103

Added line #L103 was not covered by tests
}

c.standardWebhook = &webhook
c.hmacKey = hmac.HmacKey

return nil
return CreateWebhookResponse{
HMACKey: hmac.HmacKey,
}, nil

Check warning on line 110 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L108-L110

Added lines #L108 - L110 were not covered by tests
}

func (c *client) VerifyWebhookBasicAuth(basicAuth *models.BasicAuth) bool {
Expand All @@ -118,8 +123,8 @@
return false
}

func (c *client) VerifyWebhookHMAC(item webhook.NotificationItem) bool {
return hmacvalidator.ValidateHmac(item.NotificationRequestItem, c.hmacKey)
func (c *client) VerifyWebhookHMAC(item webhook.NotificationItem, hmacKey string) bool {
return hmacvalidator.ValidateHmac(item.NotificationRequestItem, hmacKey)

Check warning on line 127 in internal/connectors/plugins/public/adyen/client/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/client/webhooks.go#L126-L127

Added lines #L126 - L127 were not covered by tests
}

func (c *client) DeleteWebhook(ctx context.Context, connectorID string) error {
Expand Down
15 changes: 13 additions & 2 deletions internal/connectors/plugins/public/adyen/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
"github.com/formancehq/payments/internal/models"
)

const (
webhookHMACMetadataKey = "hmac_key"
)

type supportedWebhook struct {
urlPath string
fn func(context.Context, models.TranslateWebhookRequest) (models.TranslateWebhookResponse, error)
Expand Down Expand Up @@ -44,12 +48,19 @@
return configs, err
}

resp, err := p.client.CreateWebhook(ctx, url, req.ConnectorID)
if err != nil {
return configs, err
}

Check warning on line 54 in internal/connectors/plugins/public/adyen/webhooks.go

View check run for this annotation

Codecov / codecov/patch

internal/connectors/plugins/public/adyen/webhooks.go#L53-L54

Added lines #L53 - L54 were not covered by tests

configs = append(configs, models.PSPWebhookConfig{
Name: name,
URLPath: standardConfig.urlPath,
Metadata: map[string]string{
webhookHMACMetadataKey: resp.HMACKey,
},
})

err = p.client.CreateWebhook(ctx, url, req.ConnectorID)
return configs, err
}

Expand All @@ -64,7 +75,7 @@
}

for _, item := range *webhooks.NotificationItems {
if !p.client.VerifyWebhookHMAC(item) {
if !p.client.VerifyWebhookHMAC(item, req.Config.Metadata[webhookHMACMetadataKey]) {
return models.VerifyWebhookResponse{}, fmt.Errorf("invalid HMAC: %w", models.ErrWebhookVerification)
}
}
Expand Down
16 changes: 13 additions & 3 deletions internal/connectors/plugins/public/adyen/webhooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ var _ = Describe("Adyen Plugin Accounts", func() {
}

expectedURL := "http://localhost:8080/test/standard"
m.EXPECT().CreateWebhook(gomock.Any(), expectedURL, req.ConnectorID).Return(nil)
m.EXPECT().CreateWebhook(gomock.Any(), expectedURL, req.ConnectorID).Return(client.CreateWebhookResponse{HMACKey: "test"}, nil)

configs, err := plg.CreateWebhooks(ctx, req)
Expect(err).To(BeNil())
Expect(configs.Configs).To(HaveLen(1))
Expect(configs.Configs[0].Metadata[webhookHMACMetadataKey]).To(Equal("test"))
})
})

Expand Down Expand Up @@ -105,6 +106,9 @@ var _ = Describe("Adyen Plugin Accounts", func() {
req := models.VerifyWebhookRequest{
Config: &models.WebhookConfig{
Name: "standard",
Metadata: map[string]string{
webhookHMACMetadataKey: "test",
},
},
Webhook: models.PSPWebhook{
BasicAuth: &models.BasicAuth{
Expand Down Expand Up @@ -132,6 +136,9 @@ var _ = Describe("Adyen Plugin Accounts", func() {
req := models.VerifyWebhookRequest{
Config: &models.WebhookConfig{
Name: "standard",
Metadata: map[string]string{
webhookHMACMetadataKey: "test",
},
},
Webhook: models.PSPWebhook{
QueryValues: map[string][]string{},
Expand All @@ -142,7 +149,7 @@ var _ = Describe("Adyen Plugin Accounts", func() {

m.EXPECT().VerifyWebhookBasicAuth(req.Webhook.BasicAuth).Return(true)
m.EXPECT().TranslateWebhook(string(req.Webhook.Body)).Return(&w, nil)
m.EXPECT().VerifyWebhookHMAC(gomock.Any()).Return(false)
m.EXPECT().VerifyWebhookHMAC(gomock.Any(), "test").Return(false)

resp, err := plg.VerifyWebhook(ctx, req)
Expect(err).ToNot(BeNil())
Expand All @@ -157,6 +164,9 @@ var _ = Describe("Adyen Plugin Accounts", func() {
req := models.VerifyWebhookRequest{
Config: &models.WebhookConfig{
Name: "standard",
Metadata: map[string]string{
webhookHMACMetadataKey: "test",
},
},
Webhook: models.PSPWebhook{
QueryValues: map[string][]string{},
Expand All @@ -167,7 +177,7 @@ var _ = Describe("Adyen Plugin Accounts", func() {

m.EXPECT().VerifyWebhookBasicAuth(req.Webhook.BasicAuth).Return(true)
m.EXPECT().TranslateWebhook(string(req.Webhook.Body)).Return(&w, nil)
m.EXPECT().VerifyWebhookHMAC(gomock.Any()).Return(true)
m.EXPECT().VerifyWebhookHMAC(gomock.Any(), "test").Return(true)

resp, err := plg.VerifyWebhook(ctx, req)
Expect(err).To(BeNil())
Expand Down
Loading
0