Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions descope/management/tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,27 +329,36 @@ def search_all(
def generate_sso_configuration_link(
self,
tenant_id: str,
expire_time: int,
expire_time: Optional[int] = None,
Comment thread
dorsha marked this conversation as resolved.
email: Optional[str] = None,
sso_id: Optional[str] = None,
) -> str:
"""
Generate a tenant admin self-service link for SSO configuration.

Args:
tenant_id (str): The ID of the tenant to generate the link for.
expire_time (int): The expiration duration in seconds. For a link valid for 6 hours, use 21600.
tenant_id (str): Tenant ID to generate the link for.
expire_time (int): Optional expiration duration in seconds. For a link valid for 6 hours, use 21600.
email (str): Optional email address associated with the admin.
sso_id (str): Optional SSO identifier for the tenant.

Return value (str):
Returns the admin SSO configuration link as a string.

Raise:
AuthException: raised if generation operation fails
"""
body: dict[str, Any] = {"tenantId": tenant_id}
if expire_time is not None:
body["expireTime"] = expire_time
if email is not None:
body["email"] = email
if sso_id is not None:
body["ssoId"] = sso_id

response = self._http.post(
MgmtV1.tenant_generate_sso_configuration_link_path,
body={
"tenantId": tenant_id,
"expireTime": expire_time,
},
body=body,
)
result = response.json()
return result.get("adminSSOConfigurationLink", "")
Expand Down
74 changes: 74 additions & 0 deletions tests/management/test_tenant.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,3 +663,77 @@ def test_generate_sso_configuration_link_failed(self):
"t1",
21600,
)

def test_generate_sso_configuration_link_with_all_params(self):
client = DescopeClient(
self.dummy_project_id,
self.public_key_dict,
False,
self.dummy_management_key,
)

# Test success flow with all parameters
with patch("httpx.post") as mock_post:
network_resp = mock.Mock()
network_resp.is_success = True
network_resp.json.return_value = json.loads(
"""{"adminSSOConfigurationLink": "https://example.com/sso-config-link"}"""
)
mock_post.return_value = network_resp
link = client.mgmt.tenant.generate_sso_configuration_link(
tenant_id="t1",
expire_time=21600,
email="admin@example.com",
sso_id="sso123",
)
self.assertEqual(link, "https://example.com/sso-config-link")
mock_post.assert_called_with(
f"{common.DEFAULT_BASE_URL}{MgmtV1.tenant_generate_sso_configuration_link_path}",
headers={
**common.default_headers,
"Authorization": f"Bearer {self.dummy_project_id}:{self.dummy_management_key}",
"x-descope-project-id": self.dummy_project_id,
},
params=None,
json={
"tenantId": "t1",
"expireTime": 21600,
"email": "admin@example.com",
"ssoId": "sso123",
},
follow_redirects=False,
verify=SSLMatcher(),
timeout=DEFAULT_TIMEOUT_SECONDS,
)

def test_generate_sso_configuration_link_minimal_params(self):
client = DescopeClient(
self.dummy_project_id,
self.public_key_dict,
False,
self.dummy_management_key,
)

# Test success flow with only required parameter
with patch("httpx.post") as mock_post:
network_resp = mock.Mock()
network_resp.is_success = True
network_resp.json.return_value = json.loads(
"""{"adminSSOConfigurationLink": "https://example.com/sso-config-link"}"""
)
mock_post.return_value = network_resp
link = client.mgmt.tenant.generate_sso_configuration_link("t1")
self.assertEqual(link, "https://example.com/sso-config-link")
mock_post.assert_called_with(
f"{common.DEFAULT_BASE_URL}{MgmtV1.tenant_generate_sso_configuration_link_path}",
headers={
**common.default_headers,
"Authorization": f"Bearer {self.dummy_project_id}:{self.dummy_management_key}",
"x-descope-project-id": self.dummy_project_id,
},
params=None,
json={"tenantId": "t1"},
follow_redirects=False,
verify=SSLMatcher(),
timeout=DEFAULT_TIMEOUT_SECONDS,
)
Loading