Skip to content

Commit 973f576

Browse files
feat: auto discover audience for token exchange when multiple associations exist for connect api integrations
1 parent e4db4fa commit 973f576

File tree

4 files changed

+329
-8
lines changed

4 files changed

+329
-8
lines changed

src/posit/connect/client.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from .groups import Groups
1313
from .metrics.metrics import Metrics
1414
from .oauth.oauth import OAuth
15-
from .oauth.types import OAuthTokenType
15+
from .oauth.types import OAuthIntegrationType, OAuthTokenType
1616
from .resources import _PaginatedResourceSequence, _ResourceSequence
1717
from .sessions import Session
1818
from .system import System
@@ -198,6 +198,10 @@ def with_user_session_token(
198198
----------
199199
token : str
200200
The user session token.
201+
audience : str, optional
202+
The audience for the token exchange. This is the integration GUID of the Connect API integration
203+
that is associate with the content. If not provided when there are multiple integrations, the
204+
function will attempt to determine the audience from the current content associations.
201205
202206
Returns
203207
-------
@@ -260,6 +264,18 @@ def user_profile():
260264
if token is None or token == "":
261265
raise ValueError("token must be set to non-empty string.")
262266

267+
# If the audience is not provided and there are multiple associations,
268+
# we will try to find the Connect API integration GUID from the content resource.
269+
current_content_associations = self.content.get().oauth.associations.find()
270+
if audience is None and len(current_content_associations) > 1:
271+
connect_api_integration_guids = [
272+
a["oauth_integration_guid"]
273+
for a in current_content_associations
274+
if a.get("oauth_integration_template") == OAuthIntegrationType.CONNECT
275+
]
276+
if len(connect_api_integration_guids) == 1:
277+
audience = connect_api_integration_guids[0]
278+
263279
visitor_credentials = self.oauth.get_credentials(
264280
token,
265281
requested_token_type=OAuthTokenType.API_KEY,

tests/posit/connect/__api__/v1/content/f2f37341-e21d-3d80-c698-a935ad614066/oauth/integrations/associations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"oauth_integration_guid": "00000000-a27b-4118-ad06-e24459b05126",
1313
"oauth_integration_name": "another integration",
1414
"oauth_integration_description": "another description",
15-
"oauth_integration_template": "custom",
15+
"oauth_integration_template": "connect",
1616
"created_time": "2024-10-02T18:16:09Z"
1717
}
1818
]

tests/posit/connect/oauth/test_associations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ def test(self):
220220
assert found["oauth_integration_name"] == "keycloak integration" # first one
221221

222222
# by multiple criteria
223-
found = associations.find_by(integration_type="custom", name="another integration")
223+
found = associations.find_by(integration_type="connect", name="another integration")
224224
assert found is not None
225-
assert found["oauth_integration_template"] == "custom"
225+
assert found["oauth_integration_template"] == "connect"
226226
assert found["oauth_integration_name"] == "another integration"
227227

228228
# no match

0 commit comments

Comments
 (0)