Skip to content

Commit 7f22ac8

Browse files
Merchant-specific DNS names Support for access (#198)
* Subdomain added for access validation endpoint * fix: clean up whitespace in multiple files and update test assertion formatting --------- Co-authored-by: david ruiz <david.ruiz@checkout.com>
1 parent d96f5a1 commit 7f22ac8

4 files changed

Lines changed: 75 additions & 8 deletions

File tree

checkout_sdk/environment_subdomain.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,30 @@
66

77
class EnvironmentSubdomain:
88
def __init__(self, environment: Environment, subdomain: str):
9-
self.base_uri = self.add_subdomain_to_api_url_environment(environment, subdomain)
9+
self.base_uri = self.create_url_with_subdomain(environment.base_uri, subdomain)
10+
self.authorization_uri = self.create_url_with_subdomain(environment.authorization_uri, subdomain)
1011

1112
@staticmethod
12-
def add_subdomain_to_api_url_environment(environment: Environment, subdomain: str):
13-
api_url = environment.base_uri
14-
new_environment = api_url
13+
def create_url_with_subdomain(original_url: str, subdomain: str):
14+
"""
15+
Applies subdomain transformation to any given URL.
16+
If the subdomain is valid (alphanumeric pattern), prepends it to the host.
17+
Otherwise, returns the original URL unchanged.
18+
19+
Args:
20+
original_url: the original URL to transform
21+
subdomain: the subdomain to prepend
22+
23+
Returns:
24+
the transformed URL with subdomain, or original URL if subdomain is invalid
25+
"""
26+
new_environment = original_url
1527

1628
regex = r'^[0-9a-z]+$'
1729
if re.match(regex, subdomain):
18-
url_parts = urlparse(api_url)
30+
url_parts = urlparse(original_url)
1931
if url_parts.port:
20-
new_host = subdomain + '.' + url_parts.hostname + ':' + url_parts.port
32+
new_host = subdomain + '.' + url_parts.hostname + ':' + str(url_parts.port)
2133
else:
2234
new_host = subdomain + '.' + url_parts.hostname
2335

checkout_sdk/oauth_sdk.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,24 @@ def scopes(self, scopes: list):
3131
return self
3232

3333
def build(self):
34+
# Determine the authorization URI based on subdomain configuration
35+
if self._environment_subdomain is not None:
36+
authorization_uri = self._environment_subdomain.authorization_uri
37+
else:
38+
authorization_uri = self._environment.authorization_uri
39+
40+
# Use custom authorization URI if explicitly provided
41+
if self._authorization_uri:
42+
authorization_uri = self._authorization_uri
43+
3444
if self._environment_subdomain is not None:
3545
configuration = CheckoutConfiguration(
3646
credentials=OAuthSdkCredentials.init(http_client=self._http_client,
3747
environment=self._environment,
3848
client_id=self._client_id,
3949
client_secret=self._client_secret,
4050
scopes=self._scopes,
41-
authorization_uri=self._authorization_uri),
51+
authorization_uri=authorization_uri),
4252
environment=self._environment,
4353
http_client=self._http_client,
4454
environment_subdomain=self._environment_subdomain)
@@ -49,7 +59,7 @@ def build(self):
4959
client_id=self._client_id,
5060
client_secret=self._client_secret,
5161
scopes=self._scopes,
52-
authorization_uri=self._authorization_uri),
62+
authorization_uri=authorization_uri),
5363
environment=self._environment,
5464
http_client=self._http_client)
5565
return CheckoutApi(configuration)

tests/checkout_configuration_test.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ def test_should_create_configuration_with_subdomain(subdomain, expected_url):
6161
assert configuration.environment.base_uri == Environment.sandbox().base_uri
6262
assert configuration.http_client == http_client
6363
assert configuration.environment_subdomain.base_uri == expected_url
64+
assert configuration.environment_subdomain.authorization_uri == (
65+
f"https://{subdomain}.access.sandbox.checkout.com/connect/token"
66+
)
6467

6568

6669
@pytest.mark.parametrize(
@@ -94,3 +97,30 @@ def test_should_create_configuration_with_bad_subdomain(subdomain, expected_url)
9497
assert configuration.environment.base_uri == Environment.sandbox().base_uri
9598
assert configuration.http_client == http_client
9699
assert configuration.environment_subdomain.base_uri == expected_url
100+
assert configuration.environment_subdomain.authorization_uri == "https://access.sandbox.checkout.com/connect/token"
101+
102+
103+
def test_should_create_configuration_with_subdomain_for_production():
104+
subdomain = "1234prod"
105+
credentials = DefaultKeysSdkCredentials(
106+
os.environ.get("CHECKOUT_DEFAULT_SECRET_KEY"),
107+
os.environ.get("CHECKOUT_DEFAULT_PUBLIC_KEY")
108+
)
109+
http_client = Mock(spec=HttpClientBuilderInterface)
110+
111+
environment_subdomain = EnvironmentSubdomain(Environment.production(), subdomain)
112+
113+
configuration = CheckoutConfiguration(
114+
credentials=credentials,
115+
environment=Environment.production(),
116+
http_client=http_client,
117+
environment_subdomain=environment_subdomain
118+
)
119+
120+
assert configuration.credentials == credentials
121+
assert configuration.environment.base_uri == Environment.production().base_uri
122+
assert configuration.http_client == http_client
123+
assert configuration.environment_subdomain.base_uri == f"https://{subdomain}.api.checkout.com/"
124+
assert configuration.environment_subdomain.authorization_uri == (
125+
f"https://{subdomain}.access.checkout.com/connect/token"
126+
)

tests/oauth_integration_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,18 @@ def test_should_fail_init_authorization_invalid_credentials_and_host():
4343
.build()
4444
except CheckoutException as err:
4545
assert err.args[0] == 'Unable to establish connection to host: (https://test.checkout.com)'
46+
47+
48+
def test_should_fail_oauth_with_subdomain_invalid_credentials():
49+
try:
50+
CheckoutSdk \
51+
.builder() \
52+
.oauth() \
53+
.client_credentials(client_id='fake_id',
54+
client_secret='fake_secret') \
55+
.environment(Environment.sandbox()) \
56+
.environment_subdomain('1234doma') \
57+
.scopes([OAuthScopes.GATEWAY, OAuthScopes.VAULT]) \
58+
.build()
59+
except CheckoutException as err:
60+
assert err.args[0] == 'OAuth client_credentials authentication failed with error: (invalid_client)'

0 commit comments

Comments
 (0)