Skip to content

Commit 40d022f

Browse files
added aws helper for content session token exchange
1 parent 20a3908 commit 40d022f

File tree

3 files changed

+82
-18
lines changed

3 files changed

+82
-18
lines changed

src/posit/connect/external/aws.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def get_aws_credentials(client: Client, user_session_token: str) -> Dict[str, st
3030
client = Client()
3131
session_token = session.http_conn.headers.get("Posit-Connect-User-Session-Token")
3232
credentials = get_aws_credentials(client, user_session_token)
33+
aws_session_expiration = credentials["expiration"]
3334
aws_session = boto3.Session(
3435
aws_access_key_id=credentials["accessKeyId"],
3536
aws_secret_access_key=credentials["secretAccessKey"],
@@ -85,6 +86,7 @@ def get_aws_content_credentials(
8586
8687
client = Client()
8788
credentials = get_aws_content_credentials(client)
89+
session_expiration = credentials["expiration"]
8890
session = boto3.Session(
8991
aws_access_key_id=credentials["accessKeyId"],
9092
aws_secret_access_key=credentials["secretAccessKey"],

tests/posit/connect/external/test_aws.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
import responses
33

44
from posit.connect import Client
5-
from posit.connect.external.aws import get_aws_credentials
5+
from posit.connect.external.aws import (
6+
_decode_access_token,
7+
get_aws_content_credentials,
8+
get_aws_credentials,
9+
)
610

711
aws_creds = {
812
"accessKeyId": "abc123",
@@ -66,3 +70,59 @@ def test_get_aws_credentials_no_token(self):
6670
get_aws_credentials(c, "cit")
6771

6872
assert e.match("No access token found in credentials")
73+
74+
@responses.activate
75+
def test_get_aws_content_credentials(self):
76+
responses.post(
77+
"https://connect.example/__api__/v1/oauth/integrations/credentials",
78+
match=[
79+
responses.matchers.urlencoded_params_matcher(
80+
{
81+
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
82+
"subject_token_type": "urn:posit:connect:content-session-token",
83+
"subject_token": "cit",
84+
"requested_token_type": "urn:ietf:params:aws:token-type:credentials",
85+
}
86+
)
87+
],
88+
json={
89+
"access_token": encoded_aws_creds,
90+
"issued_token_type": "urn:ietf:params:aws:token-type:credentials",
91+
"token_type": "aws_credentials",
92+
},
93+
)
94+
95+
c = Client(api_key="12345", url="https://connect.example/")
96+
c._ctx.version = None
97+
response = get_aws_content_credentials(c, "cit")
98+
99+
assert response == aws_creds
100+
101+
@responses.activate
102+
def test_get_aws_content_credentials_no_token(self):
103+
responses.post(
104+
"https://connect.example/__api__/v1/oauth/integrations/credentials",
105+
match=[
106+
responses.matchers.urlencoded_params_matcher(
107+
{
108+
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
109+
"subject_token_type": "urn:posit:connect:content-session-token",
110+
"subject_token": "cit",
111+
"requested_token_type": "urn:ietf:params:aws:token-type:credentials",
112+
}
113+
)
114+
],
115+
json={},
116+
)
117+
118+
c = Client(api_key="12345", url="https://connect.example/")
119+
c._ctx.version = None
120+
121+
with pytest.raises(ValueError) as e:
122+
get_aws_content_credentials(c, "cit")
123+
124+
assert e.match("No access token found in credentials")
125+
126+
def test_decode_access_token(self):
127+
decoded_creds = _decode_access_token(encoded_aws_creds)
128+
assert decoded_creds == aws_creds

tests/posit/connect/oauth/test_oauth.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def test_get_credentials(self):
2626
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
2727
"subject_token_type": "urn:posit:connect:user-session-token",
2828
"subject_token": "cit",
29+
# no requested token type set
2930
},
3031
),
3132
],
@@ -41,7 +42,7 @@ def test_get_credentials(self):
4142
assert creds.get("access_token") == "viewer-token"
4243

4344
@responses.activate
44-
def test_get_credentials_api_key(self):
45+
def test_get_credentials_with_requested_token_type(self):
4546
responses.post(
4647
"https://connect.example/__api__/v1/oauth/integrations/credentials",
4748
match=[
@@ -68,34 +69,32 @@ def test_get_credentials_api_key(self):
6869
assert creds.get("token_type") == "Key"
6970

7071
@responses.activate
71-
def test_get_credentials_aws(self):
72+
def test_get_content_credentials(self):
7273
responses.post(
7374
"https://connect.example/__api__/v1/oauth/integrations/credentials",
7475
match=[
7576
responses.matchers.urlencoded_params_matcher(
7677
{
7778
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
78-
"subject_token_type": "urn:posit:connect:user-session-token",
79+
"subject_token_type": "urn:posit:connect:content-session-token",
7980
"subject_token": "cit",
80-
"requested_token_type": "urn:ietf:params:aws:token-type:credentials",
81+
# no requested token type set
8182
},
8283
),
8384
],
8485
json={
85-
"access_token": "encoded-aws-creds",
86-
"issued_token_type": "urn:ietf:params:aws:token-type:credentials",
87-
"token_type": "aws_credentials",
86+
"access_token": "content-token",
87+
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
88+
"token_type": "Bearer",
8889
},
8990
)
9091
c = Client(api_key="12345", url="https://connect.example/")
9192
c._ctx.version = None
92-
creds = c.oauth.get_credentials("cit", OAuthTokenType.AWS_CREDENTIALS)
93-
assert creds.get("access_token") == "encoded-aws-creds"
94-
assert creds.get("issued_token_type") == "urn:ietf:params:aws:token-type:credentials"
95-
assert creds.get("token_type") == "aws_credentials"
93+
creds = c.oauth.get_content_credentials("cit")
94+
assert creds.get("access_token") == "content-token"
9695

9796
@responses.activate
98-
def test_get_content_credentials(self):
97+
def test_get_content_credentials_with_requested_token_type(self):
9998
responses.post(
10099
"https://connect.example/__api__/v1/oauth/integrations/credentials",
101100
match=[
@@ -104,19 +103,22 @@ def test_get_content_credentials(self):
104103
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
105104
"subject_token_type": "urn:posit:connect:content-session-token",
106105
"subject_token": "cit",
106+
"requested_token_type": "urn:ietf:params:aws:token-type:credentials",
107107
},
108108
),
109109
],
110110
json={
111-
"access_token": "content-token",
112-
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
113-
"token_type": "Bearer",
111+
"access_token": "encoded-aws-creds",
112+
"issued_token_type": "urn:ietf:params:aws:token-type:credentials",
113+
"token_type": "aws_credentials",
114114
},
115115
)
116116
c = Client(api_key="12345", url="https://connect.example/")
117117
c._ctx.version = None
118-
creds = c.oauth.get_content_credentials("cit")
119-
assert creds.get("access_token") == "content-token"
118+
creds = c.oauth.get_content_credentials("cit", OAuthTokenType.AWS_CREDENTIALS)
119+
assert creds.get("access_token") == "encoded-aws-creds"
120+
assert creds.get("issued_token_type") == "urn:ietf:params:aws:token-type:credentials"
121+
assert creds.get("token_type") == "aws_credentials"
120122

121123
@patch.dict("os.environ", {"CONNECT_CONTENT_SESSION_TOKEN": "cit"})
122124
@responses.activate

0 commit comments

Comments
 (0)