Skip to content

Commit b625a92

Browse files
committed
feat/(token): token endpoint is now configurable
1 parent 41d5c1b commit b625a92

2 files changed

Lines changed: 92 additions & 14 deletions

File tree

openfga_sdk/credentials.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
1010
NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT.
1111
"""
12-
13-
from urllib.parse import urlparse
12+
import re
13+
from urllib.parse import urlparse, urlunparse
1414

1515
from openfga_sdk.exceptions import ApiValueError
1616

@@ -160,6 +160,31 @@ def configuration(self, value):
160160
"""
161161
self._configuration = value
162162

163+
def _parse_issuer(self, issuer: str):
164+
default_endpoint_path = '/oauth/token'
165+
166+
parsed_url = urlparse(issuer.strip())
167+
168+
try:
169+
parsed_url.port
170+
except ValueError as e:
171+
raise ApiValueError(e)
172+
173+
if parsed_url.netloc is None and parsed_url.path is None:
174+
raise ApiValueError(f"Invalid issuer")
175+
176+
if parsed_url.scheme == "":
177+
parsed_url = urlparse(f"https://{issuer}")
178+
elif parsed_url.scheme not in ("http", "https"):
179+
raise ApiValueError(f"Invalid issuer scheme {parsed_url.scheme} must be HTTP or HTTPS")
180+
181+
if parsed_url.path in ("", "/"):
182+
parsed_url = parsed_url._replace(path=default_endpoint_path)
183+
184+
valid_url = urlunparse(parsed_url)
185+
186+
return valid_url
187+
163188
def validate_credentials_config(self):
164189
"""
165190
Check whether credentials configuration is valid
@@ -190,15 +215,6 @@ def validate_credentials_config(self):
190215
"configuration `{}` requires client_id, client_secret, api_audience and api_issuer defined for client_credentials method."
191216
)
192217
# validate token issuer
193-
combined_url = "https://" + self.configuration.api_issuer
194-
parsed_url = None
195-
try:
196-
parsed_url = urlparse(combined_url)
197-
except ValueError:
198-
raise ApiValueError(
199-
f"api_issuer `{self.configuration.api_issuer}` is invalid"
200-
)
201-
if parsed_url.netloc == "":
202-
raise ApiValueError(
203-
f"api_issuer `{self.configuration.api_issuer}` is invalid"
204-
)
218+
219+
parsed_issuer_url = self._parse_issuer(self.configuration.api_issuer)
220+

test/credentials_test.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
from unittest import IsolatedAsyncioTestCase
1414

1515
import openfga_sdk
16+
from openfga_sdk import ApiValueError
1617
from openfga_sdk.credentials import CredentialConfiguration, Credentials
18+
import unittest
1719

1820

1921
class TestCredentials(IsolatedAsyncioTestCase):
@@ -172,3 +174,63 @@ def test_configuration_client_credentials_missing_api_audience(self):
172174
)
173175
with self.assertRaises(openfga_sdk.ApiValueError):
174176
credential.validate_credentials_config()
177+
178+
179+
180+
class TestCredentialsIssuer(unittest.TestCase):
181+
def setUp(self):
182+
# Setup a basic configuration that can be modified per test case
183+
self.configuration = CredentialConfiguration(api_issuer="https://example.com")
184+
self.credentials = Credentials(method="client_credentials", configuration=self.configuration)
185+
186+
def test_valid_issuer_https(self):
187+
# Test a valid HTTPS URL
188+
self.configuration.api_issuer = "issuer.fga.example "
189+
result = self.credentials._parse_issuer(self.configuration.api_issuer)
190+
self.assertEqual(result, "https://issuer.fga.example/oauth/token")
191+
192+
def test_valid_issuer_with_oauth_endpoint_https(self):
193+
# Test a valid HTTPS URL
194+
self.configuration.api_issuer = "https://example.com/oauth/token"
195+
result = self.credentials._parse_issuer(self.configuration.api_issuer)
196+
self.assertEqual(result, "https://example.com/oauth/token")
197+
198+
def test_valid_issuer_with_some_endpoint_https(self):
199+
# Test a valid HTTPS URL
200+
self.configuration.api_issuer = "https://example.com/oauth/some/endpoint"
201+
result = self.credentials._parse_issuer(self.configuration.api_issuer)
202+
self.assertEqual(result, "https://example.com/oauth/some/endpoint")
203+
204+
def test_valid_issuer_http(self):
205+
# Test a valid HTTP URL
206+
self.configuration.api_issuer = "fga.example/some_endpoint"
207+
result = self.credentials._parse_issuer(self.configuration.api_issuer)
208+
self.assertEqual(result, "https://fga.example/some_endpoint")
209+
210+
def test_invalid_issuer_no_scheme(self):
211+
# Test an issuer URL without a scheme
212+
self.configuration.api_issuer = "https://issuer.fga.example:8080/some_endpoint "
213+
result = self.credentials._parse_issuer(self.configuration.api_issuer)
214+
self.assertEqual(result, "https://issuer.fga.example:8080/some_endpoint")
215+
216+
def test_invalid_issuer_bad_scheme(self):
217+
# Test an issuer with an unsupported scheme
218+
self.configuration.api_issuer = "ftp://example.com"
219+
with self.assertRaises(ApiValueError):
220+
self.credentials._parse_issuer(self.configuration.api_issuer)
221+
222+
def test_invalid_issuer_with_port(self):
223+
# Test an issuer with an unsupported scheme
224+
self.configuration.api_issuer = "https://issuer.fga.example:8080 "
225+
result = self.credentials._parse_issuer(self.configuration.api_issuer)
226+
self.assertEqual(result, "https://issuer.fga.example:8080/oauth/token")
227+
228+
# this should raise error
229+
def test_invalid_issuer_bad_hostname(self):
230+
# Test an issuer with an invalid hostname
231+
self.configuration.api_issuer = "https://example?.com"
232+
with self.assertRaises(ApiValueError):
233+
self.credentials._parse_issuer(self.configuration.api_issuer)
234+
235+
if __name__ == "__main__":
236+
unittest.main()

0 commit comments

Comments
 (0)