Skip to content

Conversation

ThisIsMani
Copy link
Contributor

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

This branch primarily introduces the Connector Cloning feature. Key changes include:

  • API: Added new API models (CloneConnectorRequest, CloneConnectorSource, CloneConnectorDestination) and a new API endpoint (/user/clone_connector).
  • Core Logic: Implemented the clone_connector function in crates/router/src/core/user.rs to handle the cloning process, supported by a helper function build_cloned_connector_create_request in crates/router/src/utils/user.rs.
  • Configuration: Introduced a clone_connector_whitelist configuration section in settings.rs and added it to example/deployment config files (config.example.toml, development.toml, etc.) to control which merchants and connectors are allowed for cloning.
  • Authorization & Roles:
    • Added new internal permission group (InternalManage), parent group (Internal), and resource (InternalConnector).
    • Added a new predefined internal role (internal_demo) possibly for demonstrating or testing the clone feature.
    • Updated authorization info functions (get_group_authorization_info, get_parent_group_description, get_resource_name) to handle internal groups/resources gracefully (returning None for user-facing descriptions).
    • Updated role validation to prevent adding InternalManage to custom roles.
  • Internal User Creation: Added role_id field to CreateInternalUserRequest.

Additional Changes

  • This PR modifies the API contract (new endpoint and models for cloning).
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables (new clone_connector_whitelist section).
  • config/config.example.toml
  • config/deployments/env_specific.toml
  • config/development.toml
  • config/docker_compose.toml
  • crates/router/src/configs/settings.rs

Motivation and Context

Closes juspay/hyperswitch-control-center#2921

How did you test it?

  1. Clone Connector API
  • Request
    curl --location '<YOUR_BASE_URL>/user/clone_connector' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <INTERNAL_DEMO_USER_AUTH_TOKEN>' \
    --data '{
      "source": {
        "mca_id": "<SOURCE_MCA_ID>",
        "profile_id": "<SOURCE_PROFILE_ID>",
        "merchant_id": "<SOURCE_MERCHANT_ID>"
      },
      "destination": {
        "connector_label": "Cloned Stripe Connector",
        "profile_id": "<DESTINATION_PROFILE_ID>",
        "merchant_id": "<DESTINATION_MERCHANT_ID>"
      }
    }'
  • Response: Same as Connector Create response
    {
      "connector_type": "processor",
      "connector_name": "stripe",
      "connector_label": "Cloned Stripe Connector",
      "merchant_connector_id": "mca_xxxxxxxxxxxxxxxx",
      "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "sk_test_****************************************xyz"
      },
      "test_mode": true,
      "disabled": false,
      "payment_methods_enabled": [
        {
          "payment_method": "card",
          "payment_method_types": [
            {
              "payment_method_type": "credit",
              "card_networks": ["Visa", "Mastercard"],
              "minimum_amount": 1,
              "maximum_amount": 68607706,
              "recurring_enabled": true,
              "installment_payment_enabled": true
            },
            {
              "payment_method_type": "debit",
              "card_networks": ["Visa", "Mastercard"],
              "minimum_amount": 1,
              "maximum_amount": 68607706,
              "recurring_enabled": true,
              "installment_payment_enabled": true
            }
          ],
          "payment_experience": "redirect_to_url",
          "accepted_currencies": ["USD", "EUR", "GBP"],
          "accepted_countries": ["US", "GB", "FR"]
        }
      ],
      "metadata": null,
      "business_country": ["US"],
      "business_label": "default",
      "business_sub_label": null,
      "frm_configs": null,
      "connector_webhook_details": {
        "merchant_secret": "whsec_*************************"
      },
      "profile_id": "<DESTINATION_PROFILE_ID>",
      "applepay_verified_domains": null,
      "pm_auth_config": null,
      "status": "active",
      "connector_wallets_details": null,
      "additional_merchant_data": null
    }
  1. Creating Internal Demo User
  • Request
    curl --location '<YOUR_BASE_URL>/user/internal_signup' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <ADMIN_API_KEY>' \
    --data-raw '{
      "name": "Demo User",
      "email": "[email protected]",
      "password": "<USER_PASSWORD>",
      "role_id": "internal_demo"
    }'
  • Response: 200 OK

Checklist

  • I formatted the code cargo +nightly fmt --all
  • I addressed lints thrown by cargo clippy
  • I reviewed the submitted code
  • I added unit tests for my changes where possible

@ThisIsMani ThisIsMani added C-feature Category: Feature request or enhancement S-waiting-on-review Status: This PR has been implemented and needs to be reviewed A-users Area: Users labels May 2, 2025
@ThisIsMani ThisIsMani self-assigned this May 2, 2025
@ThisIsMani ThisIsMani requested review from a team as code owners May 2, 2025 13:56
Copy link

semanticdiff-com bot commented May 2, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/services/authorization/info.rs  86% smaller
  crates/router/src/services/authorization/permissions.rs  86% smaller
  crates/router/src/routes/lock_utils.rs  86% smaller
  crates/router/src/core/user_role.rs  73% smaller
  crates/api_models/src/events/user.rs  61% smaller
  crates/router/src/utils/user_role.rs  58% smaller
  crates/router/src/services/authorization/permission_groups.rs  32% smaller
  crates/router/src/core/user.rs  6% smaller
  config/config.example.toml Unsupported file format
  config/deployments/env_specific.toml Unsupported file format
  config/development.toml Unsupported file format
  config/docker_compose.toml Unsupported file format
  crates/api_models/src/user.rs  0% smaller
  crates/common_enums/src/enums.rs  0% smaller
  crates/common_utils/src/consts.rs  0% smaller
  crates/router/src/configs/secrets_transformers.rs  0% smaller
  crates/router/src/configs/settings.rs  0% smaller
  crates/router/src/core/errors/user.rs  0% smaller
  crates/router/src/core/user_role/role.rs  0% smaller
  crates/router/src/routes/app.rs  0% smaller
  crates/router/src/routes/user.rs  0% smaller
  crates/router/src/services/authorization/roles.rs  0% smaller
  crates/router/src/services/authorization/roles/predefined_roles.rs  0% smaller
  crates/router/src/utils/user.rs  0% smaller
  crates/router_env/src/logger/types.rs  0% smaller

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces the Connector Cloning feature along with a new API endpoint and supporting configuration changes as well as associated updates to internal authorization and permission mappings. In addition, new error variants for cloning operations and updates in user role and configuration modules have been included.

  • New API endpoint (/user/clone_connector) and associated models for cloning connectors between merchants and profiles.
  • Updates to authorization logic and permission groups to support internal operations.
  • Extended configuration settings to include a whitelist for clone connector operations.

Reviewed Changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated no comments.

Show a summary per file
File Description
crates/router/src/services/authorization/permission_groups.rs Added support for InternalManage and updated mapping logic in several permission group functions.
crates/router/src/services/authorization/info.rs Refactored functions to return Options for group descriptions, especially for internal groups.
crates/router/src/routes/user.rs Introduced the clone_connector endpoint in the user module.
crates/router/src/routes/payments.rs Updated permission from ProfileAccountWrite to ProfilePaymentRead in payment capture.
crates/router/src/routes/lock_utils.rs Mapped Flow::CloneConnector to the correct API-level locking identifier.
crates/router/src/core/user.rs Added core logic to support the new clone_connector flow including whitelist validation and connector creation.
crates/router/src/configs/settings.rs Introduced CloneConnectorWhitelistConfig and updated settings to include new whitelist options.
crates/common_utils/src/consts.rs and crates/common_enums/src/enums.rs Added new constants and enum variants for internal demo roles and internal connector related operations.
crates/api_models/src/user.rs Added new API models for cloning connectors and updated internal user creation model to support role_id.
Comments suppressed due to low confidence (6)

crates/router/src/services/authorization/permission_groups.rs:160

  • [nitpick] Consider replacing the chained use of 'is_empty().not().then_some(...)' with a more explicit if/else statement for improved readability.
descriptions_map.is_empty().not().then_some(descriptions_map)

crates/router/src/services/authorization/info.rs:23

  • Ensure that all call-sites of 'get_group_description' properly handle a 'None' return value for internal groups (e.g. InternalManage) to avoid unintended behavior.
fn get_group_description(group: PermissionGroup) -> Option<&'static str> {

crates/router/src/routes/payments.rs:3075

  • Verify that updating the permission from 'ProfileAccountWrite' to 'ProfilePaymentRead' accurately reflects the intended access control changes for payment capture operations.
permission: Permission::ProfilePaymentRead,

crates/router/src/routes/lock_utils.rs:291

  • Confirm that mapping 'Flow::CloneConnector' to 'Self::User' in the locking mechanism is correct and meets the intended security and concurrency requirements.
| Flow::CloneConnector => Self::User,

crates/router/src/configs/settings.rs:162

  • Verify that the custom deserializers 'deserialize_merchant_ids' and 'deserialize_hashset' are properly handling the comma‐separated configuration values for merchant IDs and connector names.
pub struct CloneConnectorWhitelistConfig {

crates/common_enums/src/enums.rs:7217

  • Double-check that the new 'InternalManage' variant (and related 'Internal' and 'InternalConnector' variants) is fully integrated with existing permission logic without conflicts.
InternalManage,

@ThisIsMani ThisIsMani dismissed stale reviews from SanchithHegde, jarnura, and tsdk02 via 3023974 May 13, 2025 09:34
SanchithHegde
SanchithHegde previously approved these changes May 13, 2025
tsdk02
tsdk02 previously approved these changes May 13, 2025
tsdk02
tsdk02 previously approved these changes May 13, 2025
SanchithHegde
SanchithHegde previously approved these changes May 13, 2025
jarnura
jarnura previously approved these changes May 13, 2025
@ThisIsMani ThisIsMani dismissed stale reviews from jarnura, SanchithHegde, and tsdk02 via 52a55f8 May 14, 2025 13:29
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue May 14, 2025
Merged via the queue into main with commit 82f15e9 May 14, 2025
14 of 20 checks passed
@Gnanasundari24 Gnanasundari24 deleted the clone-connector branch May 14, 2025 15:35
@hyperswitch-bot hyperswitch-bot bot removed the S-waiting-on-review Status: This PR has been implemented and needs to be reviewed label May 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-users Area: Users C-feature Category: Feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Backend changes for clone connector API
9 participants