-
Notifications
You must be signed in to change notification settings - Fork 26
feat: added support for optional audience param #423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can chat about testing when you're back if you like. I think the approach will be to just assert that we're making the expected POST requests.
) { | ||
validate_R6_class(connect, "Connect") | ||
url <- v1_url("oauth", "integrations", "credentials") | ||
body <- list( | ||
grant_type = "urn:ietf:params:oauth:grant-type:token-exchange", | ||
subject_token_type = "urn:posit:connect:user-session-token", | ||
subject_token = user_session_token, | ||
requested_token_type = requested_token_type | ||
requested_token_type = requested_token_type, | ||
audience = audience, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
audience = audience, | |
audience = audience |
@@ -745,7 +754,8 @@ get_oauth_content_credentials <- function( | |||
grant_type = "urn:ietf:params:oauth:grant-type:token-exchange", | |||
subject_token_type = "urn:posit:connect:content-session-token", | |||
subject_token = content_session_token, | |||
requested_token_type = requested_token_type | |||
requested_token_type = requested_token_type, | |||
audience = audience, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
audience = audience, | |
audience = audience |
error_if_less_than(connect$version, "2025.03.0") | ||
response <- get_oauth_credentials( | ||
connect, | ||
user_session_token, | ||
requested_token_type = "urn:ietf:params:aws:token-type:credentials" | ||
requested_token_type = "urn:ietf:params:aws:token-type:credentials", | ||
audience = audience, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
audience = audience, | |
audience = audience |
@@ -1017,7 +1021,8 @@ connect <- function( | |||
visitor_creds <- get_oauth_credentials( | |||
con, | |||
user_session_token = token, | |||
requested_token_type = "urn:posit:connect:api-key" | |||
requested_token_type = "urn:posit:connect:api-key", | |||
audience = audience, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
audience = audience, | |
audience = audience |
@@ -745,7 +754,8 @@ get_oauth_content_credentials <- function( | |||
grant_type = "urn:ietf:params:oauth:grant-type:token-exchange", | |||
subject_token_type = "urn:posit:connect:content-session-token", | |||
subject_token = content_session_token, | |||
requested_token_type = requested_token_type | |||
requested_token_type = requested_token_type, | |||
audience = audience, | |||
) | |||
connect$POST( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two questions:
- Should we check that the connect server version is new enough if
!is.null(audience)
? I'm guessing that if you want to specify audience and you're on Connect older than the upcoming release, you won't get back what you're asking for. - Does the
POST
handler on the server ignore unknown body fields? Like, if you were to includeaudience
in the payload for an older Connect.
Assuming that the answers are "yes" and "no", respectively, I think we handle this like this here, instead of adding it in the body
definition above:
if (!is.null(audience)) {
if (connect$version < something) {
stop(helpful message that this is not supported)
}
body$audience <- audience
}
Note that the tests in tests/testthat/
don't test against real Connect servers, so they won't give us any assurance about how older versions of Connect respond if you include this parameter. There is an integration test suite that runs against a range of Connect versions but IDK how feasible it would be to set them up with integrations to test this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feedback in two major categories:
- Thoughts on the workflow generating a publisher-scoped client object, which depend upon how the
audience
parameter interacts withrequested-token-type
(which I'm not 100% sure about). - Comments on documentation / how we communicate the parameter.
I realize now in your Slack comment about the testing framework — the easiest way to bootstrap those responses you need is to capture them from a Connect server. Happy to pair on that if you want. When you capture them from a server, appropriately-named .json
files are created.
#' @param audience Optional. The audience field used for credential exchange. | ||
#' This must be a valid integration GUID. When provided in conjunction with the | ||
#' token field, it will use the Connect API integation based on the specified GUID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, thinking this through now, I feel like this change makes the process of creating a visitor-scoped client a lot more fiddly. I don't think we should hold up the PR over that, but I might advocate for making the default behavior be smarter.
[Edit — Perhaps I'm misunderstanding how the field works. Perhaps when it's NULL
the requested_token_type
field still works as before! If that's the case, ignore at least some of this comment. 🙂]
I think a much better user experience would be to be smart about automatically selecting a Connect API integration's has been associated with the current piece of content — that has been how our users telling the content what integrations to use. We should probably (1) find our current content item, (2) get integrations associated with it, (3) if there is a Connect API integration associated with it, use that automatically. Use this GUID if provided.
Perhaps it's worth merging this PR as-is but doing the above in a follow-on PR (maybe when we add native functions to do the lookup) before a connectapi
release? Because if we don't add some kind of automated behavior, this'll be a pretty significant breaking change for anyone using visitor-scoped clients.
I think we should explain it differently, and maybe even name it differently — audience
is a pretty jargony term that I only figured out the meaning of fairly recently. Maybe integration_guid
?
#' @param audience Optional. The audience field used for credential exchange. | |
#' This must be a valid integration GUID. When provided in conjunction with the | |
#' token field, it will use the Connect API integation based on the specified GUID. | |
#' @param integration_guid Optional. The GUID of a Connect API integration associated with this piece of content. |
#' @param audience Optional. The audience field used for credential exchange. | ||
#' This must be a valid integration GUID. When provided, the specified requested | ||
#' token type will be ignored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The audience field used for credential exchange" is a little tautological with the parameter name. Perhaps better combine that and the second sentence, something like: "The GUID of an integration associated with this piece of content." (I'm assuming that it has to be the GUID of an integration that is associated with this content, right? Not any on the server.)
It's optional — what happens when it's not provided?
Intent
Adds optional audience parameter to our oauth creds helpers. Unclear how to handle connect versions constraint since that relies on the oauth feature being there but this is an added param not a new function.
Need to address parity the python sdk through additional integration and association helpers as a follow up.
Approach
Add optional param
Checklist
NEWS.md
(referencing the connected issue if necessary)?devtools::document()
?