8000 feat(configs): Simplify connector config definition to reduce boilerplate code by laouji · Pull Request #262 · formancehq/payments · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(configs): Simplify connector config definition to reduce boilerplate code #262

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 10 commits into from
Jan 17, 2025

Conversation

laouji
Copy link
Contributor
@laouji laouji commented Jan 15, 2025

Fixes: ENG-1549

This eliminates the need for a user to define a config.json or a custom validation function as now everything is done within the Config struct. Errors are standardized as well. Can be customized later if we decide it's not human friendly enough.

Validation errors at install time now look like this:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Date: Wed, 15 Jan 2025 09:43:51 GMT
Content-Length: 184

{"errorCode":"VALIDATION","errorMessage":"Key: 'Config.UserCertificate' Error:Field validation for 'UserCertificate' failed on the 'required' tag: validation error: validation error"}

Copy link
Contributor
coderabbitai bot commented Jan 15, 2025

Walkthrough

This pull request introduces significant updates to configuration validation across multiple payment connector plugins. The changes primarily involve integrating the go-playground/validator/v10 package to standardize and simplify configuration validation. Custom validation methods have been replaced with validation tags and centralized validation using the validator library. The Earthfile has also been modified to streamline the configuration generation process, eliminating the previous compile-configs section and adjusting the COPY commands to include necessary source files.

Changes

File Change Summary
Earthfile Removed compile-configs section, simplified configuration generation, adjusted COPY commands.
internal/connectors/engine/engine.go Added validator package, enhanced error handling for configuration validation.
internal/connectors/plugins/public/*/config.go Added validate:"required" tags to configuration structs, removed custom validation methods.
internal/connectors/plugins/public/*/plugin_test.go Updated error message assertions to use ContainSubstring.
tools/connector-template/template/config.gotpl Added validator import, updated configuration validation approach.
internal/api/backend/backend.go Updated import path for ConnectorsConfigs method, changed return type from plugins.Configs to registry.Configs.
internal/api/backend/backend_generated.go Updated import path and return type for ConnectorsConfigs method in MockBackend.
internal/api/services/connector_configs.go Updated import path and return type for ConnectorsConfigs method.
internal/api/v2/handler_connectors_configs.go Updated import path and variable usage in connectorsConfigs function.
internal/api/v2/handler_connectors_configs_test.go Updated import path and method expectation in test case.
internal/api/v3/handler_connectors_configs.go Updated import path and variable names in connectorsConfigs function.
internal/api/v3/handler_connectors_configs_test.go Updated import path and method expectation in test case.
internal/connectors/plugins/registry/configs.go Introduced new types and constants for configuration management.
internal/connectors/plugins/registry/plugins.go Updated RegisterPlugin function signature, added new functions for configuration retrieval.

Assessment against linked issues

Objective Addressed Explanation
Autogenerate config.json Partial progress made with Earthfile modifications, but full autogeneration not yet complete.

Possibly related PRs

Suggested Reviewers

  • Dav-14
  • paul-nicolas

Poem

🐰 Validation's dance, a rabbit's delight,
Tags and checks, making configs just right.
From plugins to Earthfile, we've streamlined the way,
Ensuring our code runs smooth every day!
Hop, validate, deploy! 🚀

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@laouji laouji force-pushed the feat/connector-factory-config branch 2 times, most recently from 9a008e2 to 91618cc Compare January 15, 2025 10:57
Copy link
gitguardian bot commented Jan 15, 2025

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@laouji laouji force-pushed the feat/connector-factory-config branch from 91618cc to 3361830 Compare January 15, 2025 11:05
@laouji
Copy link
Contributor Author
laouji commented Jan 15, 2025

@coderabbitai review

Copy link
Contributor
coderabbitai bot commented Jan 15, 2025
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
codecov bot commented Jan 15, 2025

Codecov Report

Attention: Patch coverage is 74.52830% with 27 lines in your changes missing coverage. Please review.

Project coverage is 72.79%. Comparing base (530220f) to head (f09f9f7).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
internal/connectors/plugins/registry/plugins.go 74.13% 13 Missing and 2 partials ⚠️
internal/connectors/plugins/public/wise/config.go 71.42% 2 Missing ⚠️
internal/connectors/plugins/public/adyen/plugin.go 0.00% 1 Missing ⚠️
internal/connectors/plugins/public/atlar/plugin.go 0.00% 1 Missing ⚠️
.../connectors/plugins/public/bankingcircle/plugin.go 0.00% 1 Missing ⚠️
.../connectors/plugins/public/currencycloud/plugin.go 0.00% 1 Missing ⚠️
...ternal/connectors/plugins/public/generic/plugin.go 0.00% 1 Missing ⚠️
...ernal/connectors/plugins/public/mangopay/plugin.go 0.00% 1 Missing ⚠️
...nternal/connectors/plugins/public/modulr/plugin.go 0.00% 1 Missing ⚠️
...rnal/connectors/plugins/public/moneycorp/plugin.go 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #262      +/-   ##
==========================================
+ Coverage   67.57%   72.79%   +5.21%     
==========================================
  Files         539      538       -1     
  Lines       27012    26985      -27     
==========================================
+ Hits        18253    19643    +1390     
+ Misses       7611     6279    -1332     
+ Partials     1148     1063      -85     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@laouji laouji marked this pull request as ready for review January 15, 2025 11:11
@laouji laouji requested a review from a team as a code owner January 15, 2025 11:11
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (19)
internal/connectors/plugins/public/moneycorp/config.go (1)

22-23: Consider caching the validator instance.

The validator instance is created for each validation call. Since validator creation involves reflection, it's more efficient to create it once and reuse it.

+var validate = validator.New(validator.WithRequiredStructEnabled())
+
 func unmarshalAndValidateConfig(payload json.RawMessage) (Config, error) {
 	var config Config
 	if err := json.Unmarshal(payload, &config); err != nil {
 		return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
 	}
-	validate := validator.New(validator.WithRequiredStructEnabled())
 	return config, validate.Struct(config)
 }
internal/connectors/plugins/public/dummypay/config.go (1)

19-20: Consider wrapping validation errors consistently.

Other connector configs wrap errors with models.ErrInvalidConfig. Consider maintaining consistency:

 	validate := validator.New(validator.WithRequiredStructEnabled())
-	return config, validate.Struct(config)
+	if err := validate.Struct(config); err != nil {
+		return Config{}, fmt.Errorf("failed to validate config: %w", err)
+	}
+	return config, nil
internal/connectors/plugins/public/atlar/config.go (1)

17-17: Consider using consistent parameter types across connectors.

Other connectors use json.RawMessage for the payload parameter, while this one uses []byte.

-func unmarshalAndValidateConfig(payload []byte) (Config, error) {
+func unmarshalAndValidateConfig(payload json.RawMessage) (Config, error) {
internal/connectors/plugins/public/modulr/config.go (2)

22-23: Consider reusing validator instance for better performance.

The validator instance is created for each validation call. Consider creating a package-level validator instance to avoid the overhead of repeated instantiation.

+var validate = validator.New(validator.WithRequiredStructEnabled())
+
 func unmarshalAndValidateConfig(payload []byte) (Config, error) {
 	var config Config
 	if err := json.Unmarshal(payload, &config); err != nil {
 		return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
 	}
-	validate := validator.New(validator.WithRequiredStructEnabled())
 	return config, validate.Struct(config)
 }

23-23: Consider wrapping validation errors consistently.

For consistency with JSON unmarshal errors, consider wrapping validation errors with models.ErrInvalidConfig.

-	return config, validate.Struct(config)
+	if err := validate.Struct(config); err != nil {
+		return config, errors.Wrap(models.ErrInvalidConfig, err.Error())
+	}
+	return config, nil
internal/connectors/plugins/public/mangopay/config.go (1)

22-23: Apply same performance and error handling improvements as modulr.

For consistency across connectors and better performance:

  1. Reuse validator instance
  2. Wrap validation errors with models.ErrInvalidConfig
+var validate = validator.New(validator.WithRequiredStructEnabled())
+
 func unmarshalAndValidateConfig(payload json.RawMessage) (Config, error) {
 	var config Config
 	if err := json.Unmarshal(payload, &config); err != nil {
 		return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
 	}
-	validate := validator.New(validator.WithRequiredStructEnabled())
-	return config, validate.Struct(config)
+	if err := validate.Struct(config); err != nil {
+		return config, errors.Wrap(models.ErrInvalidConfig, err.Error())
+	}
+	return config, nil
internal/connectors/plugins/public/currencycloud/config.go (1)

22-23: Apply same performance and error handling improvements as other connectors.

For consistency across connectors and better performance:

  1. Reuse validator instance
  2. Wrap validation errors with models.ErrInvalidConfig
+var validate = validator.New(validator.WithRequiredStructEnabled())
+
 func unmarshalAndValidateConfig(payload json.RawMessage) (Config, error) {
 	var config Config
 	if err := json.Unmarshal(payload, &config); err != nil {
 		return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
 	}
-	validate := validator.New(validator.WithRequiredStructEnabled())
-	return config, validate.Struct(config)
+	if err := validate.Struct(config); err != nil {
+		return config, errors.Wrap(models.ErrInvalidConfig, err.Error())
+	}
+	return config, nil
internal/connectors/plugins/public/adyen/config.go (1)

24-25: Apply same performance and error handling improvements as other connectors.

For consistency across connectors and better performance:

  1. Reuse validator instance
  2. Wrap validation errors with models.ErrInvalidConfig
+var validate = validator.New(validator.WithRequiredStructEnabled())
+
 func unmarshalAndValidateConfig(payload []byte) (Config, error) {
 	var config Config
 	if err := json.Unmarshal(payload, &config); err != nil {
 		return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
 	}
-	validate := validator.New(validator.WithRequiredStructEnabled())
-	return config, validate.Struct(config)
+	if err := validate.Struct(config); err != nil {
+		return config, errors.Wrap(models.ErrInvalidConfig, err.Error())
+	}
+	return config, nil
tools/connector-template/template/config.gotpl (1)

14-17: Enhance example comments to demonstrate more validation patterns.

While the current examples show basic required field validation, consider adding examples of other common validation patterns that connectors might need, such as:

  • URL validation for endpoints
  • Length constraints for API keys
  • Enum values for modes/environments

Example enhancement:

 // ClientID string `json:"clientID" validate:"required"`
 // APIKey   string `json:"apiKey" validate:"required,min=32,max=64"`
-// Endpoint string `json:"endpoint" validate:"required"`
+// Endpoint string `json:"endpoint" validate:"required,url"`
+// Mode    string `json:"mode" validate:"required, production"`
internal/connectors/plugins/public/bankingcircle/config.go (1)

12-17: Enhance validation rules for URLs and certificates.

While the required validation is good, consider adding more specific validation rules:

  • URL validation for endpoints
  • PEM format validation for certificates
-  Endpoint              string `json:"endpoint" yaml:"endpoint" validate:"required"`
-  AuthorizationEndpoint string `json:"authorizationEndpoint" yaml:"authorizationEndpoint" validate:"required"`
-  UserCertificate       string `json:"userCertificate" yaml:"userCertificate" validate:"required"`
-  UserCertificateKey    string `json:"userCertificateKey" yaml:"userCertificateKey" validate:"required"`
+  Endpoint              string `json:"endpoint" yaml:"endpoint" validate:"required,url"`
+  AuthorizationEndpoint string `json:"authorizationEndpoint" yaml:"authorizationEndpoint" validate:"required,url"`
+  UserCertificate       string `json:"userCertificate" yaml:"userCertificate" validate:"required,startswith=-----BEGIN CERTIFICATE-----"`
+  UserCertificateKey    string `json:"userCertificateKey" yaml:"userCertificateKey" validate:"required,startswith=-----BEGIN PRIVATE KEY-----"`
internal/connectors/plugins/public/wise/config.go (1)

48-51: Consider improving error handling for validation errors.

The current implementation might lose the context of validation errors.

 validate := validator.New(validator.WithRequiredStructEnabled())
 if err := validate.Struct(config); err != nil {
-  return config, err
+  return config, fmt.Errorf("config validation failed: %w", err)
 }
internal/connectors/plugins/public/stripe/plugin_test.go (1)

33-33: Consider adding more specific validation test cases.

While using ContainSubstring("APIKey") is more resilient, consider adding test cases for:

  • Invalid API key format
  • Multiple validation errors
  • Edge cases (empty string vs missing field)

Example additional test cases:

It("should report multiple validation errors", func(ctx SpecContext) {
    config := json.RawMessage(`{"apiKey": "", "webhookSecret": ""}`)
    _, err := New("stripe", logger, config)
    Expect(err.Error()).To(And(
        ContainSubstring("APIKey"),
        ContainSubstring("required"),
    ))
})
internal/connectors/plugins/public/generic/plugin_test.go (1)

33-33: LGTM! The error assertion changes improve maintainability.

The switch from exact error message matching to substring checks makes the tests less brittle and easier to maintain.

Consider using a test helper function to standardize these config validation checks across all plugin tests:

func expectConfigValidationError(err error, field string) {
    Expect(err.Error()).To(ContainSubstring(field))
}

Also applies to: 39-39

Earthfile (1)

37-37: LGTM! The simplified config generation improves maintainability.

Using jq to generate empty JSON objects is a cleaner approach that reduces boilerplate.

Consider adding a comment explaining the purpose of the empty configs and why they're needed:

+        # Generate empty config templates for each connector
         RUN jq -cn "{(\"$c\"): {}}" >> raw_configs.json
internal/connectors/plugins/public/wise/plugin_test.go (1)

78-78: LGTM! Consider adding more validation test cases.

The error message change correctly reflects the switch to using the validator package for config validation.

Consider adding test cases for:

  • Individual required field validation
  • Field format validation (e.g., malformed API keys)
  • Edge cases like whitespace-only values
test/e2e/api_connectors_test.go (1)

95-98: LGTM! Consider adding more edge cases.

The test cases effectively cover empty and invalid directory paths for both versions.

Consider adding test cases for:

  • Directory paths with special characters but valid format
  • Maximum length directory paths
  • Directory paths with trailing slashes
internal/connectors/engine/engine.go (1)

339-342: Consider extracting common validation error handling.

The validation error handling is identical to InstallConnector. Consider extracting this into a helper function to reduce duplication.

+func wrapValidationError(err error) error {
+    if _, ok := err.(validator.ValidationErrors); ok || errors.Is(err, models.ErrInvalidConfig) {
+        return errors.Wrap(ErrValidation, err.Error())
+    }
+    return err
+}

 func (e *engine) UpdateConnector(ctx context.Context, connectorID models.ConnectorID, rawConfig json.RawMessage) error {
     // ...
     err := e.plugins.RegisterPlugin(connector.ID, connector.Name, config, connector.Config, true)
     if err != nil {
         otel.RecordError(span, err)
-        if _, ok := err.(validator.ValidationErrors); ok || errors.Is(err, models.ErrInvalidConfig) {
-            return errors.Wrap(ErrValidation, err.Error())
-        }
-        return err
+        return wrapValidationError(err)
     }
     // ...
 }
internal/connectors/plugins/public/currencycloud/plugin_test.go (1)

33-33: LGTM! Consider standardizing test case naming.

The switch to substring-based error validation is a good improvement that makes tests less brittle. For consistency across connector plugins, consider renaming the test cases to follow the pattern:

-It("should report errors in config - loginID"
+It("reports validation errors in the config - loginID"

Also applies to: 39-39, 45-45

internal/connectors/plugins/public/mangopay/plugin_test.go (1)

33-34: Consider standardizing error message format across connectors.

While the explicit nil checks improve test robustness, consider standardizing the error message format across all connectors. This would make error handling more consistent and maintainable.

Also applies to: 40-41, 47-48

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b41654b and 3361830.

⛔ Files ignored due to path filters (14)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
  • internal/connectors/plugins/configs.json is excluded by !**/*.json
  • internal/connectors/plugins/public/adyen/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/atlar/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/bankingcircle/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/currencycloud/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/dummypay/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/generic/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/mangopay/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/modulr/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/moneycorp/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/stripe/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/wise/config.json is excluded by !**/*.json
📒 Files selected for processing (25)
  • Earthfile (1 hunks)
  • internal/connectors/engine/engine.go (3 hunks)
  • internal/connectors/plugins/public/adyen/config.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/atlar/config.go (1 hunks)
  • internal/connectors/plugins/public/atlar/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/config.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/config.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/dummypay/config.go (1 hunks)
  • internal/connectors/plugins/public/generic/config.go (1 hunks)
  • internal/connectors/plugins/public/generic/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/config.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/modulr/config.go (1 hunks)
  • internal/connectors/plugins/public/modulr/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/config.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/stripe/config.go (1 hunks)
  • internal/connectors/plugins/public/stripe/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/wise/config.go (2 hunks)
  • internal/connectors/plugins/public/wise/plugin_test.go (1 hunks)
  • test/e2e/api_connectors_test.go (2 hunks)
  • tools/connector-template/template/config.gotpl (2 hunks)
🔇 Additional comments (17)
internal/connectors/plugins/public/moneycorp/config.go (2)

7-7: LGTM! Good choice of validation library.

Using go-playground/validator/v10 is a solid choice for standardizing validation across connectors.


12-14: LGTM! Clean struct definition with validation tags.

The validation tags effectively replace custom validation logic, reducing boilerplate while maintaining clear requirements.

internal/connectors/plugins/public/moneycorp/plugin_test.go (1)

37-37: LGTM! Test updated to match new validation error messages.

The test correctly verifies the validation error from the validator library.

internal/connectors/plugins/public/stripe/config.go (1)

12-12: LGTM! Clean validation implementation.

The changes effectively simplify the config validation while maintaining proper error handling.

Also applies to: 20-21

internal/connectors/plugins/public/generic/config.go (1)

12-13: LGTM! Consistent validation implementation.

The changes follow the established pattern for config validation across connectors.

Also applies to: 21-22

internal/connectors/plugins/public/atlar/config.go (1)

12-14: LGTM! Validation implementation is clean.

The validation changes align well with other connectors.

Also applies to: 22-23

internal/connectors/plugins/public/adyen/config.go (1)

12-16: Verify secure handling of sensitive configuration fields.

The config contains several sensitive fields (APIKey, WebhookUsername, WebhookPassword). Let's verify they're handled securely throughout the codebase.

✅ Verification successful

Sensitive configuration fields are properly secured.

The configuration fields (APIKey, WebhookUsername, WebhookPassword) are handled securely:

  • Encrypted at rest using PGP symmetric encryption with AES256
  • No plain-text storage in the database
  • No logging of sensitive values
  • Proper encryption/decryption flow in the storage layer
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential security issues with sensitive config fields

# Check for logging of sensitive fields
echo "Checking for potential logging of sensitive fields..."
rg -i "log|print|fmt" -A 5 -B 5 "APIKey|WebhookUsername|WebhookPassword"

# Check for storage/transmission of sensitive fields
echo "Checking how sensitive fields are stored/transmitted..."
rg "APIKey|WebhookUsername|WebhookPassword" -A 5 -B 5 "database|store|send|http|marshal"

Length of output: 555


Script:

#!/bin/bash
# Search for usage of sensitive fields in logging contexts
echo "=== Checking logging patterns ==="
rg -i "log|print|fmt" -C 5 --type go

# Search for sensitive field usage patterns
echo -e "\n=== Checking field usage patterns ==="
rg "(APIKey|WebhookUsername|WebhookPassword)" -C 5 --type go

# Search for struct initialization and field access
echo -e "\n=== Checking initialization and access patterns ==="
ast-grep --pattern 'Config{$$$}'
ast-grep --pattern '$_.APIKey'
as
8000
t-grep --pattern '$_.WebhookUsername'
ast-grep --pattern '$_.WebhookPassword'

Length of output: 66704


Script:

#!/bin/bash
# Search for Adyen config struct usage and encryption patterns
echo "=== Checking Adyen config implementation ==="
rg -C 5 "type.+Config.+struct" internal/connectors/plugins/public/adyen/

# Check for encryption/secure storage patterns
echo -e "\n=== Checking encryption patterns ==="
rg -C 5 "encrypt|mask|redact|sensitive" internal/connectors/plugins/public/adyen/

# Check for config field usage
echo -e "\n=== Checking config field usage ==="
rg -C 5 "Config.*{" internal/connectors/plugins/public/adyen/
rg -C 5 "\.APIKey|\.WebhookUsername|\.WebhookPassword" internal/connectors/plugins/public/adyen/

Length of output: 3531


Script:

#!/bin/bash
# Check storage layer implementation
echo "=== Checking storage layer ==="
rg -C 5 "configEncryptionKey|encrypt" internal/storage/

# Check general security patterns
echo -e "\n=== Checking general security patterns ==="
rg -C 5 "sensitive|encrypt" internal/connectors/

# Check client implementation
echo -e "\n=== Checking client implementation ==="
rg -C 5 "New\(" internal/connectors/plugins/public/adyen/client/

Length of output: 23677

tools/connector-template/template/config.gotpl (1)

26-27: LGTM! Good use of WithRequiredStructEnabled.

The validation setup is correct and consistent with best practices. Using WithRequiredStructEnabled() ensures proper validation of required fields.

internal/connectors/plugins/public/bankingcircle/config.go (1)

25-26: LGTM! Consistent validation setup.

The validation setup matches the template pattern and correctly uses WithRequiredStructEnabled().

internal/connectors/plugins/public/wise/config.go (1)

16-17: LGTM! Good separation of basic and custom validation.

The validation tags are correctly applied while maintaining custom RSA key validation.

internal/connectors/plugins/public/atlar/plugin_test.go (1)

33-33: LGTM! Error assertion changes align with the project's direction.

The changes to use substring checks for config validation errors are consistent with other plugin tests and improve maintainability.

Also applies to: 39-39, 45-45

internal/connectors/plugins/public/modulr/plugin_test.go (1)

33-33: LGTM! Error assertion changes maintain consistency.

The changes to use substring checks for config validation errors maintain consistency with other plugin tests and support the goal of reducing boilerplate.

Also applies to: 39-39, 45-45

test/e2e/api_connectors_test.go (1)

87-93: LGTM! Well-structured test function enhancement.

The updated test function signature with dirVal and expectedErr parameters improves test clarity and allows for more precise validation testing.

internal/connectors/engine/engine.go (2)

18-18: LGTM! Validator package import added.

The validator package import is correctly placed and version is appropriately pinned.


136-139: LGTM! Comprehensive validation error handling.

The error handling properly handles both validator errors and custom invalid config errors, maintaining error context through wrapping.

internal/connectors/plugins/public/adyen/plugin_test.go (1)

36-37: LGTM! Comprehensive config validation.

The test cases properly validate all required fields with clear, comprehensive test data. The error validation approach using substrings is consistent with other connector implementations.

Also applies to: 40-41, 44-44

internal/connectors/plugins/public/bankingcircle/plugin_test.go (1)

33-33: Verify the intentional difference in error validation approaches.

The test uses substring validation for basic fields but maintains exact error matching for certificate validation. While this might be intentional for security reasons, please verify if this mixed approach is desired.

Run this script to check error handling consistency across connectors:

Also applies to: 39-39, 45-45, 51-51, 57-57, 63-63, 67-69

✅ Verification successful

The mixed error validation approach is intentionally designed and appropriate

The codebase consistently uses:

  • Substring matching for basic config field validation, allowing for flexible error messages
  • Exact error matching for security-critical certificate validation, ensuring precise error handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check error handling patterns across connector plugins
# Look for certificate-related error handling patterns

# Search for certificate validation patterns
rg -A 2 "certificate.*error|error.*certificate" internal/connectors/plugins/public/

# Search for error validation patterns in tests
ast-grep --pattern 'Expect($_, $_).To(MatchError($_))'

Length of output: 1579


Script:

#!/bin/bash
# Search for all error validation patterns in the test file
rg "Expect\(.*error.*\).To\(" internal/connectors/plugins/public/bankingcircle/plugin_test.go -B 2 -A 1

# Search for ContainSubstring usage in tests across all connectors for comparison
rg "ContainSubstring.*error|error.*ContainSubstring" internal/connectors/plugins/public/ -A 1

Length of output: 201


Script:

#!/bin/bash
# Search for Expect patterns in test file
rg "Expect\(" internal/connectors/plugins/public/bankingcircle/plugin_test.go -B 1 -A 1

# Use ast-grep to find test assertions
ast-grep --pattern 'Expect($_).To($_)'

# Simple search for ContainSubstring
rg "ContainSubstring" internal/connectors/plugins/public/bankingcircle/plugin_test.go

Length of output: 65980

return fmt.Errorf("missing directory in config: %w", models.ErrInvalidConfig)
}
return nil
Directory string `json:"directory" validate:"required,dirpath"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Missing implementation for "dirpath" custom validator

The dirpath validation tag is used in the Directory field, but there is no implementation of this custom validator in the codebase. This will cause validation to fail at runtime.

  • Add the custom validator implementation and register it with the validator instance
  • Example implementation:
    v.RegisterValidation("dirpath", func(fl validator.FieldLevel) bool {
        // Add directory path validation logic here
        return true
    })
🔗 Analysis chain

Verify the implementation of the "dirpath" custom validator.

The dirpath validation tag is used but its implementation is not visible in the provided code. This custom validator needs to be registered with the validator instance.

Let's check if the custom validator is defined elsewhere:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for dirpath validator implementation
rg -l "RegisterValidation.*dirpath" 

Length of output: 37


Script:

#!/bin/bash
# Search for dirpath validator function definition
rg -l "func.*dirpath"

# Search for validator initialization patterns
rg -l "validator\.New\(\)"

# Search for similar directory validation patterns
rg -i "directory.*validate"

Length of output: 201


return nil
APIKey string `json:"apiKey" validate:"required"`
WebhookUsername string `json:"webhookUsername" validate:"required"`
Copy link
Contributor
@paul-nicolas paul-nicolas Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebhookUsername, WebhookPassword and LiveEndpointPrefix can be empty, are we sending an error now if that's the case with the validator ?

Copy link
Contributor Author
@laouji laouji Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok perhaps I misunderstood your explanation yesterday about the webhooks being necessary. All three fields were marked as "required" in the config.json, but it hadn't been enforced by the original config.Validate() function, so I thought they had been accidentally left out from the implementation. I was trying to align documentation and implementation.
If they are optional, then we can remove the required tag.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh my bad, it was a miscommunication then ! Webhooks are necessary in Adyen, but the username/password is not, depending on if the users wants to have an basic auth or not

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and for the LiveEndpointPrefix field, it is not necessary for test endpoits/sandbox for adyen

@laouji laouji force-pushed the feat/connector-factory-config branch from 3361830 to 8cb597a Compare January 16, 2025 20:07
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (12)
internal/connectors/plugins/registry/plugins.go (1)

66-67: Remove debug statements using fmt.Printf

The calls to fmt.Printf at lines 66-67 and 86-87 appear to be leftover debug statements. It's recommended to remove these prints or replace them with appropriate logging at the correct log level.

Also applies to: 86-87

internal/connectors/plugins/registry/configs.go (2)

13-19: Add documentation for configuration types.

Consider adding package-level documentation to explain:

  • The purpose and usage of each type
  • The relationship between Configs, Config, and Parameter
  • Examples of how to define custom configurations

21-38: Enhance default parameter definitions.

Consider the following improvements:

  1. Add validation for the duration format in pollingPeriod
  2. Document the expected format and valid ranges for each parameter
  3. Consider using constants for default values to improve maintainability

Example enhancement:

+const (
+    DefaultPollingPeriod = "2m"
+    DefaultPageSize      = "100"
+)

 var (
     defaultParameters = map[string]Parameter{
         "pollingPeriod": {
             DataType:     TypeDurationNs,
             Required:     false,
-            DefaultValue: "2m",
+            DefaultValue: DefaultPollingPeriod,
         },
internal/connectors/plugins/registry/plugins_test.go (2)

22-33: Consider adding validation for more edge cases.

The Config struct provides good coverage for basic types, but consider adding tests for:

  • Nested structs
  • Array/slice types
  • Map types
  • Custom validation rules

31-32: Document the purpose of special field types.

Add comments explaining why NilJsonTag and unexportedField are included in the test struct, as their purpose isn't immediately clear.

internal/api/backend/backend.go (1)

34-34: Document the breaking change in Backend interface.

Consider adding a comment in the code or updating the changelog to document this breaking change in the Backend interface.

+// ConnectorsConfigs returns the registry configurations for all supported connectors.
+// Note: Changed from plugins.Configs to registry.Configs in v0.x.x
 ConnectorsConfigs() registry.Configs
tools/connector-template/template/plugin.gotpl (1)

Line range hint 35-35: Address TODO comment in template.

The template contains a TODO comment about using the config to create the client. This should be updated to demonstrate the proper usage of the config struct.

-    _ = config // TODO: use config to create client and remove this line
+    client := client.New(
+        // TODO: Add example of using config fields to create client
+        // config.Field1,
+        // config.Field2,
+    )
internal/connectors/engine/workflow/main_test.go (1)

87-87: Consider adding test cases for config validation.

While the change adapts the test to the new RegisterPlugin signature, consider adding test cases that:

  1. Verify config validation behavior
  2. Test various config scenarios (valid, invalid, empty)
internal/connectors/plugins/public/generic/config.go (1)

21-22: Consider improving validation error handling.

The current implementation might not provide user-friendly error messages when validation fails. Consider wrapping validation errors with more context.

 validate := validator.New(validator.WithRequiredStructEnabled())
-return config, validate.Struct(config)
+if err := validate.Struct(config); err != nil {
+    return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
+}
+return config, nil
internal/connectors/plugins/public/currencycloud/config.go (1)

Line range hint 1-23: Consider creating a common validation helper.

Given that all connectors now share identical validation logic, consider creating a common helper function to reduce code duplication.

Example implementation:

// internal/connectors/plugins/common/config/validator.go
package config

import (
    "encoding/json"
    "github.com/go-playground/validator/v10"
    "github.com/pkg/errors"
    "github.com/formancehq/payments/internal/models"
)

func UnmarshalAndValidate[T any](payload json.RawMessage) (T, error) {
    var config T
    if err := json.Unmarshal(payload, &config); err != nil {
        return config, errors.Wrap(models.ErrInvalidConfig, err.Error())
    }
    
    validate := validator.New(validator.WithRequiredStructEnabled())
    if err := validate.Struct(config); err != nil {
        return config, errors.Wrap(models.ErrInvalidConfig, err.Error())
    }
    
    return config, nil
}

This would allow each connector to simplify its validation to:

func unmarshalAndValidateConfig(payload json.RawMessage) (Config, error) {
    return config.UnmarshalAndValidate[Config](payload)
}
test/e2e/api_connectors_test.go (1)

134-145: Consider adding v2 test cases for config updates.

While the test cases effectively validate directory paths for v3, consider adding similar test cases for v2 to maintain consistent test coverage across versions.

Add these test cases:

 DescribeTable("should respond with a validation error when plugin-side config invalid",
   func(ver int, dirValue string, expectedErr string) {
     config := newConnectorConfigurationFn()(id)
     config.Directory = dirValue
     err := ConnectorConfigUpdate(ctx, app.GetValue(), ver, connectorID, &config)
     Expect(err).NotTo(BeNil())
     Expect(err.Error()).To(ContainSubstring("400"))
     Expect(err.Error()).To(ContainSubstring(expectedErr))
   },
   Entry("empty directory", 3, "", "validation for 'Directory' failed on the 'required' tag"),
   Entry("invalid directory", 3, "$#2djskajdj", "validation for 'Directory' failed on the 'dirpath' tag"),
+  Entry("empty directory with v2", 2, "", "validation for 'Directory' failed on the 'required' tag"),
+  Entry("invalid directory with v2", 2, "$#2djskajdj", "validation for 'Directory' failed on the 'dirpath' tag"),
 )
internal/connectors/engine/engine.go (1)

339-341: Consider extracting duplicated error handling logic.

The error handling logic is identical to the one in InstallConnector. Consider extracting it into a helper function to reduce code duplication.

Example refactor:

+func isValidationError(err error) bool {
+  _, ok := err.(validator.ValidationErrors)
+  return ok || errors.Is(err, models.ErrInvalidConfig)
+}
+
+func wrapValidationError(err error) error {
+  if isValidationError(err) {
+    return errors.Wrap(ErrValidation, err.Error())
+  }
+  return err
+}
+
 func (e *engine) InstallConnector(ctx context.Context, provider string, rawConfig json.RawMessage) (models.ConnectorID, error) {
   // ...
   err := e.plugins.RegisterPlugin(connector.ID, connector.Name, config, connector.Config, false)
   if err != nil {
     otel.RecordError(span, err)
-    if _, ok := err.(validator.ValidationErrors); ok || errors.Is(err, models.ErrInvalidConfig) {
-      return models.ConnectorID{}, errors.Wrap(ErrValidation, err.Error())
-    }
-    return models.ConnectorID{}, err
+    return models.ConnectorID{}, wrapValidationError(err)
   }
   // ...
 }

 func (e *engine) UpdateConnector(ctx context.Context, connectorID models.ConnectorID, rawConfig json.RawMessage) error {
   // ...
   err := e.plugins.RegisterPlugin(connector.ID, connector.Name, config, connector.Config, true)
   if err != nil {
     otel.RecordError(span, err)
-    if _, ok := err.(validator.ValidationErrors); ok || errors.Is(err, models.ErrInvalidConfig) {
-      return errors.Wrap(ErrValidation, err.Error())
-    }
-    return err
+    return wrapValidationError(err)
   }
   // ...
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3361830 and 8cb597a.

⛔ Files ignored due to path filters (14)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
  • internal/connectors/plugins/configs.json is excluded by !**/*.json
  • internal/connectors/plugins/public/adyen/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/atlar/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/bankingcircle/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/currencycloud/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/dummypay/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/generic/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/mangopay/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/modulr/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/moneycorp/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/stripe/config.json is excluded by !**/*.json
  • internal/connectors/plugins/public/wise/config.json is excluded by !**/*.json
📒 Files selected for processing (49)
  • Earthfile (0 hunks)
  • internal/api/backend/backend.go (2 hunks)
  • internal/api/backend/backend_generated.go (2 hunks)
  • internal/api/services/connector_configs.go (1 hunks)
  • internal/api/v2/handler_connectors_configs.go (2 hunks)
  • internal/api/v2/handler_connectors_configs_test.go (2 hunks)
  • internal/api/v3/handler_connectors_configs.go (2 hunks)
  • internal/api/v3/handler_connectors_configs_test.go (2 hunks)
  • internal/connectors/engine/engine.go (3 hunks)
  • internal/connectors/engine/workflow/main_test.go (1 hunks)
  • internal/connectors/plugins/configs.go (0 hunks)
  • internal/connectors/plugins/public/adyen/config.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/atlar/config.go (1 hunks)
  • internal/connectors/plugins/public/atlar/plugin.go (1 hunks)
  • internal/connectors/plugins/public/atlar/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/config.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/plugin.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/config.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/plugin.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/dummypay/config.go (1 hunks)
  • internal/connectors/plugins/public/dummypay/plugin.go (1 hunks)
  • internal/connectors/plugins/public/generic/config.go (1 hunks)
  • internal/connectors/plugins/public/generic/plugin.go (1 hunks)
  • internal/connectors/plugins/public/generic/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/config.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/plugin.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/modulr/config.go (1 hunks)
  • internal/connectors/plugins/public/modulr/plugin.go (1 hunks)
  • internal/connectors/plugins/public/modulr/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/config.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/plugin.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/stripe/config.go (1 hunks)
  • internal/connectors/plugins/public/stripe/plugin.go (1 hunks)
  • internal/connectors/plugins/public/stripe/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/wise/config.go (2 hunks)
  • internal/connectors/plugins/public/wise/plugin.go (1 hunks)
  • internal/connectors/plugins/public/wise/plugin_test.go (1 hunks)
  • internal/connectors/plugins/registry/configs.go (1 hunks)
  • internal/connectors/plugins/registry/plugins.go (3 hunks)
  • internal/connectors/plugins/registry/plugins_test.go (1 hunks)
  • test/e2e/api_connectors_test.go (2 hunks)
  • tools/connector-template/template/config.gotpl (2 hunks)
  • tools/connector-template/template/plugin.gotpl (2 hunks)
💤 Files with no reviewable changes (2)
  • Earthfile
  • internal/connectors/plugins/configs.go
🚧 Files skipped from review as they are similar to previous changes (17)
  • internal/connectors/plugins/public/wise/plugin_test.go
  • internal/connectors/plugins/public/moneycorp/plugin_test.go
  • internal/connectors/plugins/public/stripe/plugin_test.go
  • tools/connector-template/template/config.gotpl
  • internal/connectors/plugins/public/dummypay/config.go
  • internal/connectors/plugins/public/mangopay/plugin_test.go
  • internal/connectors/plugins/public/adyen/plugin_test.go
  • internal/connectors/plugins/public/atlar/plugin_test.go
  • internal/connectors/plugins/public/bankingcircle/plugin_test.go
  • internal/connectors/plugins/public/generic/plugin_test.go
  • internal/connectors/plugins/public/stripe/config.go
  • internal/connectors/plugins/public/moneycorp/config.go
  • internal/connectors/plugins/public/adyen/config.go
  • internal/connectors/plugins/public/modulr/plugin_test.go
  • internal/connectors/plugins/public/bankingcircle/config.go
  • internal/connectors/plugins/public/currencycloud/plugin_test.go
  • internal/connectors/plugins/public/wise/config.go
🔇 Additional comments (32)
internal/api/services/connector_configs.go (1)

7-7: LGTM!

The changes correctly update the import to use registry, and the function ConnectorsConfigs now returns registry.Configs, reflecting the updated configuration management.

Also applies to: 11-12

internal/api/v2/handler_connectors_configs.go (1)

9-9: LGTM!

The import path is properly updated to use the registry package. The variable confs is appropriately used to represent the configurations, and the response encoding correctly utilizes api.BaseResponse[registry.Configs].

Also applies to: 18-18, 20-21

internal/connectors/plugins/registry/configs.go (1)

3-11: LGTM! Well-structured type system for configuration parameters.

The type system is clear and provides good type safety for configuration parameters.

internal/api/v3/handler_connectors_configs.go (1)

9-9: LGTM! Clean transition to registry package.

The changes correctly update the import path and type references while maintaining the same functionality.

Also applies to: 18-18, 20-22

internal/api/v3/handler_connectors_configs_test.go (1)

8-8: LGTM! Test updates align with implementation changes.

The test correctly uses the new registry package and maintains test coverage.

Also applies to: 32-32

internal/api/v2/handler_connectors_configs_test.go (1)

8-8: LGTM! Consistent test updates across API versions.

The v2 API test changes mirror the v3 updates, maintaining consistency across API versions.

Also applies to: 32-32

internal/connectors/plugins/public/generic/plugin.go (1)

19-19: LGTM! Config parameter addition aligns with standardization effort.

The addition of Config{} parameter to RegisterPlugin call follows the new pattern for simplified configuration handling.

internal/connectors/plugins/registry/plugins_test.go (1)

49-120: LGTM! Comprehensive test coverage for configuration parsing.

The test suite thoroughly validates:

  • Required vs optional fields
  • Different data types
  • JSON metadata handling
  • Default values
internal/connectors/plugins/public/atlar/plugin.go (1)

20-20: LGTM! Consistent with configuration standardization.

The addition of Config{} parameter aligns with the project-wide standardization of plugin configurations.

internal/connectors/plugins/public/moneycorp/plugin.go (2)

19-19: LGTM! Maintains consistency with configuration changes.

The addition of Config{} parameter follows the standardized approach for plugin configuration handling.


Line range hint 1-1: Verify consistent implementation across all plugins.

Let's ensure all plugins have been updated with the new configuration pattern.

internal/connectors/plugins/public/currencycloud/plugin.go (1)

Line range hint 15-19: LGTM! Consistent with the config simplification initiative.

The addition of Config{} as a parameter to RegisterPlugin aligns with the PR's objective of simplifying connector configuration definitions.

Let's verify this change is consistent across all payment connector plugins:

✅ Verification successful

Verified: Config simplification is consistently implemented across all payment connector plugins

All payment connector plugins in the codebase follow the same pattern, using Config{} as the last parameter in RegisterPlugin calls, which confirms the alignment with the config simplification initiative.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all plugin registration patterns to ensure consistent config usage
ast-grep --pattern 'registry.RegisterPlugin($_, $_, $_, Config{})'

Length of output: 3959

internal/connectors/plugins/public/modulr/plugin.go (1)

Line range hint 15-19: LGTM! Consistent with other plugins.

The change follows the same pattern as other plugins in this PR.

internal/connectors/plugins/public/bankingcircle/plugin.go (1)

Line range hint 15-19: LGTM! Consistent with other plugins.

The change follows the same pattern as other plugins in this PR.

internal/connectors/plugins/public/stripe/plugin.go (2)

Line range hint 15-19: LGTM! Consistent with other plugins.

The change follows the same pattern as other plugins in this PR.


Line range hint 34-34: Verify the nil parameter usage in client initialization.

The client.New function is called with nil as its first parameter. This seems unusual and might indicate a potential issue.

Let's verify the intended usage:

✅ Verification successful

The nil parameter usage in client.New is correct and intentional

The nil backend parameter triggers the creation of a default backend with a metrics-wrapped HTTP client, which is the expected behavior for normal operation. This allows for custom backend injection when needed (e.g., for testing) while providing sensible defaults.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the client.New function signature and usage
ast-grep --pattern 'func New($_, $_, $_) $_ {
  $$$
}'

# Search for other instances of client initialization
rg -A 2 'client.New\('

Length of output: 21743

internal/connectors/plugins/public/adyen/plugin.go (1)

20-20: LGTM! Standardized plugin registration with Config struct.

The addition of Config{} parameter aligns with the PR's objective of simplifying connector configuration handling.

internal/api/backend/backend.go (1)

9-9: Verify the impact of config package migration.

The migration from plugins.Configs to registry.Configs is a breaking change that affects the Backend interface.

Let's verify all usages of the Configs type:

Also applies to: 34-34

✅ Verification successful

✓ Config package migration is complete

The migration from plugins.Configs to registry.Configs has been properly implemented across the codebase. All references to the Configs type consistently use the registry package, and no legacy code using the old type was found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to plugins.Configs
rg "plugins\.Configs" 

# Search for all implementations of the Backend interface
ast-grep --pattern 'type $_ struct {
  $$$
}

var _ Backend = $_'

Length of output: 91


Script:

#!/bin/bash
# Find Backend interface definition
ast-grep --pattern 'type Backend interface {
  $$$
}'

# Search for any references to Configs type
rg -A 2 "Configs"

# Find implementations using composition pattern
ast-grep --pattern 'type $_ struct {
  Backend
  $$$
}'

Length of output: 55271

tools/connector-template/template/plugin.gotpl (1)

19-19: LGTM! Template updated for standardized config handling.

The template now includes Config{} parameter, ensuring all new connectors follow the standardized configuration pattern.

internal/connectors/plugins/public/dummypay/plugin.go (1)

18-18: LGTM! Well-implemented config handling.

The addition of Config{} parameter is consistent with other connectors. The implementation in New function shows proper usage of the config struct for client initialization.

internal/connectors/plugins/public/mangopay/plugin.go (1)

21-21: Verify Config struct definition and validation rules.

The addition of Config{} aligns with the PR's goal of simplifying connector configurations. However, we should ensure that:

  1. The Config struct is properly defined with appropriate validation tags
  2. The validation rules are comprehensive for the mangopay connector requirements
✅ Verification successful

Config struct is properly defined with comprehensive validation rules

The mangopay Config struct has all necessary fields with appropriate required validation tags, following the project's standard pattern.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Config struct definition and validation rules
ast-grep --pattern 'type Config struct {
  $$$
}'

# Check for validation tag usage
rg -A 5 'validate:"[^"]*"'

Length of output: 18079

internal/connectors/plugins/public/wise/plugin.go (1)

20-20: LGTM! Consistent with the standardized configuration approach.

The addition of Config{} follows the same pattern as other plugins, maintaining consistency in the codebase.

internal/api/backend/backend_generated.go (1)

19-19: Verify source file for mock generation.

This is an auto-generated file. Ensure that:

  1. The source file (backend.go) has been updated with the new registry.Configs type
  2. The mockgen command has been run with the latest source

Also applies to: 212-215

✅ Verification successful

Source and generated files are properly aligned

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check source file for registry.Configs usage
rg -l "registry\.Configs" | grep -v "generated"

# Verify mockgen command in source
rg "^//go:generate.*mockgen.*backend\.go"

Length of output: 494


Script:

#!/bin/bash
# Check the exact usage of registry.Configs in the source file
rg "registry\.Configs" internal/api/backend/backend.go -A 2 -B 2

Length of output: 326

internal/connectors/plugins/public/generic/config.go (1)

12-13: LGTM! Validation tags are correctly defined.

The required validation tags on APIKey and Endpoint fields align with the PR's goal of standardizing config validation.

internal/connectors/plugins/public/atlar/config.go (2)

12-14: LGTM! Validation tags are consistent with other connectors.

The required validation tags on BaseURL, AccessKey, and Secret fields maintain consistency across connectors.


22-23: Consider consistent error handling across connectors.

Similar to the generic connector, consider wrapping validation errors with more context.

internal/connectors/plugins/public/modulr/config.go (1)

12-14: LGTM! Changes follow the established pattern.

The implementation maintains consistency with other connectors in both validation tags and error handling.

Also applies to: 22-23

internal/connectors/plugins/public/mangopay/config.go (1)

12-14: LGTM! Changes follow the established pattern.

The implementation maintains consistency with other connectors in both validation tags and error handling.

Also applies to: 22-23

internal/connectors/plugins/public/currencycloud/config.go (1)

12-14: LGTM! Changes follow the established pattern.

The implementation maintains consistency with other connectors in both validation tags and error handling.

Also applies to: 22-23

test/e2e/api_connectors_test.go (1)

89-100: LGTM! Test cases effectively validate directory path requirements.

The test cases comprehensively cover directory validation scenarios for both connector versions:

  • Empty directory validation
  • Invalid directory path validation
  • Consistent error message validation
internal/connectors/engine/engine.go (2)

18-18: LGTM! Import aligns with validation integration.

The addition of the validator package import supports the PR's objective of standardizing configuration validation.


136-138: LGTM! Error handling enhancement improves validation.

The error handling now properly handles both validator errors and invalid config errors, providing consistent error wrapping.

@laouji laouji force-pushed the feat/connector-factory-config branch from 8cb597a to 8057d8b Compare January 16, 2025 20:46
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
internal/connectors/plugins/registry/plugins.go (1)

72-85: ⚠️ Potential issue

Improve type handling in switch statement

The current implementation has limited type support and uses panic for error handling. This is a duplicate of previous review comments but still needs to be addressed.

Previous suggestions included:

  1. Adding support for all integer types
  2. Replacing panic with error return
  3. Adding proper error handling
🧹 Nitpick comments (4)
internal/connectors/plugins/public/adyen/config.go (1)

16-18: Enhance webhook authentication documentation and validation.

While the validation is functionally correct, consider these improvements:

  1. Expand the RFC 7617 comment to clarify why ":" is excluded (it's a delimiter in Basic Auth).
  2. Add omitempty to WebhookPassword for consistency with WebhookUsername.
 // https://datatracker.ietf.org/doc/html/rfc7617
+// The ":" character is excluded from username as it's used as a delimiter in Basic Auth
 WebhookUsername string `json:"webhookUsername" validate:"omitempty,excludes=:"`
-WebhookPassword string `json:"webhookPassword" validate:""`
+WebhookPassword string `json:"webhookPassword" validate:"omitempty"`
internal/connectors/plugins/registry/plugins.go (3)

66-67: Remove debug print statement

Debug print statements should not be in production code.

-			fmt.Printf("CONTINUE: %s\n", fieldName)

86-86: Remove debug print statement

Debug print statements should not be in production code.

-		fmt.Printf("FIELD: %s\n", fieldName)

45-93: Consider caching reflection results

The current implementation uses reflection for every config setup. While this provides flexibility, it can impact performance in high-throughput scenarios where plugins are frequently registered.

Consider caching the reflection results for each config type to improve performance. This could be implemented using a concurrent map to store the processed field information.

Example approach:

var configCache sync.Map // map[reflect.Type]Config

func setupConfig(provider string, conf any) (Config, error) {
    typ := reflect.TypeOf(conf)
    if cached, ok := configCache.Load(typ); ok {
        return cached.(Config).clone(), nil
    }
    // existing implementation
    configCache.Store(typ, config.clone())
    return config, nil
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8cb597a and 8057d8b.

⛔ Files ignored due to path filters (1)
  • internal/connectors/plugins/configs.json is excluded by !**/*.json
📒 Files selected for processing (27)
  • Earthfile (0 hunks)
  • internal/api/backend/backend.go (2 hunks)
  • internal/api/backend/backend_generated.go (2 hunks)
  • internal/api/services/connector_configs.go (1 hunks)
  • internal/api/v2/handler_connectors_configs.go (2 hunks)
  • internal/api/v2/handler_connectors_configs_test.go (2 hunks)
  • internal/api/v3/handler_connectors_configs.go (2 hunks)
  • internal/api/v3/handler_connectors_configs_test.go (2 hunks)
  • internal/connectors/engine/workflow/main_test.go (1 hunks)
  • internal/connectors/plugins/configs.go (0 hunks)
  • internal/connectors/plugins/public/adyen/config.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/atlar/plugin.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/plugin.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/plugin.go (1 hunks)
  • internal/connectors/plugins/public/dummypay/plugin.go (1 hunks)
  • internal/connectors/plugins/public/generic/plugin.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/plugin.go (1 hunks)
  • internal/connectors/plugins/public/modulr/plugin.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/plugin.go (1 hunks)
  • internal/connectors/plugins/public/stripe/plugin.go (1 hunks)
  • internal/connectors/plugins/public/wise/plugin.go (1 hunks)
  • internal/connectors/plugins/registry/configs.go (1 hunks)
  • internal/connectors/plugins/registry/plugins.go (3 hunks)
  • internal/connectors/plugins/registry/plugins_test.go (1 hunks)
  • tools/connector-template/template/plugin.gotpl (2 hunks)
💤 Files with no reviewable changes (2)
  • Earthfile
  • internal/connectors/plugins/configs.go
🚧 Files skipped from review as they are similar to previous changes (23)
  • internal/connectors/plugins/public/bankingcircle/plugin.go
  • internal/connectors/plugins/public/wise/plugin.go
  • internal/connectors/plugins/public/currencycloud/plugin.go
  • internal/connectors/engine/workflow/main_test.go
  • internal/api/services/connector_configs.go
  • internal/api/v2/handler_connectors_configs_test.go
  • tools/connector-template/template/plugin.gotpl
  • internal/connectors/plugins/public/moneycorp/plugin.go
  • internal/api/v3/handler_connectors_configs_test.go
  • internal/connectors/plugins/public/adyen/plugin_test.go
  • internal/connectors/plugins/public/adyen/plugin.go
  • internal/api/backend/backend.go
  • internal/connectors/plugins/registry/plugins_test.go
  • internal/api/v3/handler_connectors_configs.go
  • internal/connectors/plugins/public/dummypay/plugin.go
  • internal/connectors/plugins/public/generic/plugin.go
  • internal/api/backend/backend_generated.go
  • internal/api/v2/handler_connectors_configs.go
  • internal/connectors/plugins/public/stripe/plugin.go
  • internal/connectors/plugins/registry/configs.go
  • internal/connectors/plugins/public/atlar/plugin.go
  • internal/connectors/plugins/public/modulr/plugin.go
  • internal/connectors/plugins/public/mangopay/plugin.go
🔇 Additional comments (3)
internal/connectors/plugins/public/adyen/config.go (2)

7-7: LGTM! Good choice of validation library.

The go-playground/validator is a robust and well-maintained choice for struct validation.


12-14: LGTM! Validation tags correctly reflect field requirements.

The validation tags accurately capture the requirements:

  • Required fields: APIKey, CompanyID
  • Optional LiveEndpointPrefix with alphanumeric validation
internal/connectors/plugins/registry/plugins.go (1)

119-133: LGTM! Well-implemented config retrieval functions

The implementation is clean, consistent with other functions, and has proper error handling.

@laouji laouji force-pushed the feat/connector-factory-config branch from 8057d8b to ea53eaa Compare January 16, 2025 20:52
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (4)
internal/connectors/plugins/registry/plugins.go (4)

7-7: 🛠️ Refactor suggestion

Replace log package with error handling

The log package is imported primarily for log.Panicf, which should be replaced with proper error handling.


32-43: ⚠️ Potential issue

Propagate errors from setupConfig

The function should handle potential errors from setupConfig instead of allowing panics to propagate.

Additionally, consider validating the input parameters:

 func RegisterPlugin(
 	provider string,
 	createFunc PluginCreateFunction,
 	capabilities []models.Capability,
 	conf any,
-) {
+) error {
+	if provider == "" {
+		return fmt.Errorf("provider cannot be empty")
+	}
+	if createFunc == nil {
+		return fmt.Errorf("createFunc cannot be nil")
+	}
+	config, err := setupConfig(provider, conf)
+	if err != nil {
+		return fmt.Errorf("failed to setup config: %w", err)
+	}
 	pluginsRegistry[provider] = PluginInformation{
 		capabilities: capabilities,
 		createFunc:   createFunc,
-		config:       setupConfig(provider, conf),
+		config:       config,
 	}
+	return nil
 }

45-52: ⚠️ Potential issue

Add validation for conf parameter

The function should validate the conf parameter before processing.


72-85: ⚠️ Potential issue

Improve type handling and error management

The type handling is incomplete and uses panic for error handling.

Additionally, consider using a type registry pattern for better maintainability:

type typeHandler func(reflect.Type) (Type, error)

var typeHandlers = map[reflect.Kind]typeHandler{
    reflect.String: func(t reflect.Type) (Type, error) {
        return TypeString, nil
    },
    reflect.Int64: func(t reflect.Type) (Type, error) {
        if t.Name() == "Duration" {
            return TypeDurationNs, nil
        }
        return TypeInteger, nil
    },
    // ... other handlers
}
🧹 Nitpick comments (1)
internal/connectors/plugins/public/adyen/config.go (1)

16-18: Consider making the WebhookPassword validation tag more explicit.

While an empty validation tag (validate:"") effectively makes the field optional, it might be clearer to explicitly state this using validate:"omitempty" for consistency with other optional fields.

-	WebhookPassword string `json:"webhookPassword" validate:""`
+	WebhookPassword string `json:"webhookPassword" validate:"omitempty"`
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8057d8b and ea53eaa.

⛔ Files ignored due to path filters (1)
  • internal/connectors/plugins/configs.json is excluded by !**/*.json
📒 Files selected for processing (27)
  • Earthfile (0 hunks)
  • internal/api/backend/backend.go (2 hunks)
  • internal/api/backend/backend_generated.go (2 hunks)
  • internal/api/services/connector_configs.go (1 hunks)
  • internal/api/v2/handler_connectors_configs.go (2 hunks)
  • internal/api/v2/handler_connectors_configs_test.go (2 hunks)
  • internal/api/v3/handler_connectors_configs.go (2 hunks)
  • internal/api/v3/handler_connectors_configs_test.go (2 hunks)
  • internal/connectors/engine/workflow/main_test.go (1 hunks)
  • internal/connectors/plugins/configs.go (0 hunks)
  • internal/connectors/plugins/public/adyen/config.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin_test.go (1 hunks)
  • internal/connectors/plugins/public/atlar/plugin.go (1 hunks)
  • internal/connectors/plugins/public/bankingcircle/plugin.go (1 hunks)
  • internal/connectors/plugins/public/currencycloud/plugin.go (1 hunks)
  • internal/connectors/plugins/public/dummypay/plugin.go (1 hunks)
  • internal/connectors/plugins/public/generic/plugin.go (1 hunks)
  • internal/connectors/plugins/public/mangopay/plugin.go (1 hunks)
  • internal/connectors/plugins/public/modulr/plugin.go (1 hunks)
  • internal/connectors/plugins/public/moneycorp/plugin.go (1 hunks)
  • internal/connectors/plugins/public/stripe/plugin.go (1 hunks)
  • internal/connectors/plugins/public/wise/plugin.go (1 hunks)
  • internal/connectors/plugins/registry/configs.go (1 hunks)
  • internal/connectors/plugins/registry/plugins.go (3 hunks)
  • internal/connectors/plugins/registry/plugins_test.go (1 hunks)
  • tools/connector-template/template/plugin.gotpl (2 hunks)
💤 Files with no reviewable changes (2)
  • Earthfile
  • internal/connectors/plugins/configs.go
🚧 Files skipped from review as they are similar to previous changes (23)
  • internal/connectors/plugins/public/bankingcircle/plugin.go
  • internal/connectors/plugins/public/adyen/plugin.go
  • internal/connectors/plugins/public/moneycorp/plugin.go
  • internal/connectors/plugins/public/atlar/plugin.go
  • internal/api/backend/backend_generated.go
  • internal/connectors/plugins/public/generic/plugin.go
  • internal/connectors/plugins/public/adyen/plugin_test.go
  • internal/api/v2/handler_connectors_configs_test.go
  • internal/connectors/plugins/public/modulr/plugin.go
  • internal/api/v3/handler_connectors_configs_test.go
  • internal/connectors/engine/workflow/main_test.go
  • internal/api/services/connector_configs.go
  • internal/connectors/plugins/public/stripe/plugin.go
  • internal/connectors/plugins/public/mangopay/plugin.go
  • tools/connector-template/template/plugin.gotpl
  • internal/api/backend/backend.go
  • internal/connectors/plugins/public/dummypay/plugin.go
  • internal/api/v3/handler_connectors_configs.go
  • internal/connectors/plugins/registry/plugins_test.go
  • internal/connectors/plugins/public/currencycloud/plugin.go
  • internal/connectors/plugins/registry/configs.go
  • internal/connectors/plugins/public/wise/plugin.go
  • internal/api/v2/handler_connectors_configs.go
🔇 Additional comments (5)
internal/connectors/plugins/public/adyen/config.go (3)

7-7: LGTM! Good choice of validation library.

The go-playground/validator is a robust and widely-used validation library that will help standardize validation across connectors.


12-14: LGTM! Well-structured validation rules.

The validation tags for APIKey, CompanyID, and LiveEndpointPrefix are appropriately configured based on their requirements.


26-27: Improve validation error handling for better user experience.

While the validation setup is good, consider wrapping validation errors with models.ErrInvalidConfig for consistency with unmarshal errors.

 validate := validator.New(validator.WithRequiredStructEnabled())
-return config, validate.Struct(config)
+if err := validate.Struct(config); err != nil {
+    return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
+}
+return config, nil
internal/connectors/plugins/registry/plugins.go (2)

21-21: LGTM: Config field addition

The addition of the config field to PluginInformation is well-structured and maintains proper encapsulation.


119-133: LGTM: Well-structured config retrieval functions

The implementation of GetConfigs and GetConfig is clean, consistent with existing patterns, and handles error cases appropriately.

@laouji laouji force-pushed the feat/connector-factory-config branch from ea53eaa to f09f9f7 Compare January 17, 2025 09:46
@laouji laouji requested a review from paul-nicolas January 17, 2025 10:01
Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
internal/connectors/plugins/public/adyen/config.go (1)

26-27: 🛠️ Refactor suggestion

Improve validation error handling for better user experience.

Consider wrapping validation errors with models.ErrInvalidConfig for consistency with unmarshal errors.

 validate := validator.New(validator.WithRequiredStructEnabled())
-return config, validate.Struct(config)
+if err := validate.Struct(config); err != nil {
+    return Config{}, errors.Wrap(models.ErrInvalidConfig, err.Error())
+}
+return config, nil
internal/connectors/plugins/registry/plugins.go (1)

31-42: ⚠️ Potential issue

Handle potential errors from setupConfig

The function should handle potential errors from setupConfig to prevent panics from propagating.

This issue was previously raised in past reviews and remains unaddressed.

🧹 Nitpick comments (2)
internal/connectors/plugins/public/adyen/config.go (1)

18-18: Consider adding password validation rules.

While the WebhookPassword is optional, when provided, consider adding basic password validation rules (e.g., minimum length, complexity) to ensure secure webhook authentication.

-	WebhookPassword string `json:"webhookPassword" validate:""`
+	WebhookPassword string `json:"webhookPassword" validate:"omitempty,min=8"`
internal/connectors/plugins/registry/plugins.go (1)

65-94: Enhance validation tag handling

The validation tag parsing is simplistic and only checks for "required". Consider parsing additional validation rules.

Suggestions:

  1. Parse min/max values for numeric fields
  2. Support regex patterns for strings
  3. Add enum validation support
  4. Handle nested struct validation

Example implementation:

type ValidationRules struct {
    Required bool
    Min      *float64
    Max      *float64
    Pattern  *regexp.Regexp
    Enum     []string
}

func parseValidationTag(tag string) ValidationRules {
    // Parse validation rules from tag
    // Example: "required,min=0,max=100,pattern=^[A-Z]+$"
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea53eaa and f09f9f7.

📒 Files selected for processing (5)
  • internal/connectors/plugins/public/adyen/config.go (1 hunks)
  • internal/connectors/plugins/public/adyen/plugin_test.go (1 hunks)
  • internal/connectors/plugins/registry/plugins.go (3 hunks)
  • internal/connectors/plugins/registry/plugins_test.go (1 hunks)
  • tools/connector-template/template/plugin.gotpl (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/connectors/plugins/public/adyen/plugin_test.go
  • tools/connector-template/template/plugin.gotpl
  • internal/connectors/plugins/registry/plugins_test.go
🔇 Additional comments (3)
internal/connectors/plugins/public/adyen/config.go (2)

7-7: LGTM! Good choice of validation library.

The go-playground/validator is a well-maintained and widely used validation library in the Go ecosystem.


12-18: LGTM! Well-structured validation rules and documentation.

The validation tags align with the discussed requirements in the PR comments. Good addition of the RFC reference for webhook authentication.

internal/connectors/plugins/registry/plugins.go (1)

122-136: LGTM! Well-implemented configuration retrieval

The GetConfigs and GetConfig functions are well implemented with:

  • Proper error handling
  • Case-insensitive provider name handling
  • Consistent return types

Comment on lines +6 to +8
"log"
"reflect"
"regexp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using errors instead of log.Panic

The log package is imported primarily for log.Panic calls. This is not recommended for production code as it can cause the application to crash unexpectedly.

Consider using error returns instead of panics for better error handling. This was previously suggested in past reviews but is still relevant for the new code.

Comment on lines +76 to +89
switch vt.Kind() {
case reflect.String:
dataType = TypeString
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
dataType = TypeUnsignedInteger
case reflect.Int64:
if field.Type.Name() == "Duration" {
dataType = TypeDurationNs
break
}
fallthrough
default:
log.Panicf("unhandled type for field %q: %q", val.Type().Field(i).Name, field.Type.Name())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Expand type support in setupConfig

The type switch is incomplete and missing support for common types:

  • float32/float64
  • bool
  • maps
  • slices

Apply this diff to add support for more types:

 switch vt.Kind() {
 case reflect.String:
     dataType = TypeString
+case reflect.Bool:
+    dataType = TypeBool
+case reflect.Float32, reflect.Float64:
+    dataType = TypeFloat
+case reflect.Map:
+    dataType = TypeMap
+case reflect.Slice:
+    dataType = TypeArray
 case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
     dataType = TypeUnsignedInteger
 case reflect.Int64:

Committable suggestion skipped: line range outside the PR's diff.

@laouji laouji merged commit c5af4d5 into main Jan 17, 2025
9 checks passed
@laouji laouji deleted the feat/connector-factory-config branch January 17, 2025 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0