-
Notifications
You must be signed in to change notification settings - Fork 26
feat: use viewer credentials by default if possible #391
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -965,12 +965,19 @@ | |
#' @export | ||
connect <- function( | ||
server = Sys.getenv(paste0(prefix, "_SERVER"), NA_character_), | ||
api_key = Sys.getenv(paste0(prefix, "_API_KEY"), NA_character_), | ||
api_key, | ||
token, | ||
token_local_testing_key = api_key, | ||
prefix = "CONNECT", | ||
..., | ||
.check_is_fatal = TRUE) { | ||
if (!missing(api_key)) { | ||
api_key_provided <- TRUE | ||
} else { | ||
api_key_provided <- FALSE | ||
api_key <- Sys.getenv(paste0(prefix, "_API_KEY"), NA_character_) | ||
} | ||
|
||
if (is.null(api_key) || is.na(api_key) || nchar(api_key) == 0) { | ||
msg <- "Invalid (empty) API key. Please provide a valid API key" | ||
if (.check_is_fatal) { | ||
|
@@ -981,21 +988,53 @@ | |
} | ||
con <- Connect$new(server = server, api_key = api_key) | ||
|
||
if (api_key_provided) { | ||
return(con) | ||
} | ||
|
||
if (on_connect()) { | ||
comp <- compare_connect_version(con$version, "2025.01.0") | ||
if (comp < 0) { | ||
if (!missing(token)) { | ||
# If running on a too-old version of Connect and token was explicitly | ||
# passed, error. | ||
stop( | ||
"Running content using the viewer's credentials ", | ||
"requires Connect v2025.01.0 or later." | ||
) | ||
} else { | ||
# If running on too-old Connect and no token was explicitly passed, use | ||
# the old behavior (run with publisher creds). | ||
message( | ||
"Content will run using publisher's credentials. ", | ||
"Running content using the viewer's credentials ", | ||
"requires Connect v2025.01.0 or later." | ||
) | ||
} | ||
} else { | ||
if (missing(token) && exists("getDefaultReactiveDomain", mode = "function")) { | ||
# If the session token was not provided, see if we can obtain it from | ||
# the Shiny context. | ||
session <- getDefaultReactiveDomain() | ||
token <- session$request$HTTP_POSIT_CONNECT_USER_SESSION_TOKEN | ||
} | ||
} | ||
} | ||
|
||
if (!missing(token)) { | ||
error_if_less_than(con$version, "2025.01.0") | ||
if (on_connect()) { | ||
visitor_creds <- get_oauth_credentials( | ||
con, | ||
user_session_token = token, | ||
requested_token_type = "urn:posit:connect:api-key" | ||
) | ||
con <- connect(server = server, api_key = visitor_creds$access_token) | ||
con <- Connect$new(server = server, api_key = visitor_creds$access_token) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will fail unless the integration is attached to the content. I dont remember where that landed but will you be using the viewer api key integration or something in the rstudio-credentials header? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The viewer API key for now, as unless I'm mistaken we haven't moved that work forward yet. I'm aware that it'll fail on first deploy in that case, and (cc @jonkeane) I think we're willing to accept that for now? I do think better error messaging in @jonkeane I guess whether to proceed with landing this PR now hinges on whether we think "initial deploy fails to run until you add the integration" or "runs with admin credentials" is the least bad user experience. Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Failing on initial deploy until configuration is correct is (unfortunately) pretty common for Connect today, so this isn't much worse than other cases (e.g. when someone needs to set a specific env var). But it is a poor experience, and yet another toe-stub on not having the visitor API key on automatically. |
||
} else { | ||
con <- connect(server = server, api_key = token_local_testing_key) | ||
message(paste0( | ||
"Called with `token` but not running on Connect. ", | ||
"Continuing with fallback API key." | ||
)) | ||
con <- Connect$new(server = server, api_key = token_local_testing_key) | ||
} | ||
} | ||
|
||
|
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.
This seems equivalent to the original implementation, plus checking if the
api_key
isNA_character_
. If it'sNA_character_
, it wasn't provided as a function argument or an environment variable.Am I missing something?
Uh oh!
There was an error while loading. Please reload this page.
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.
Yeah — in the original implementation plus checking to see if the key is
NA_character_
, we can't tell the difference between a key being explicitly provided (connect(api_key=my_api_key)
) vs the function being called with no args (connect()
). That led to a bug where we always used the viewer token, even if the code explicitly tried to pass in the API key they wanted to use.It feels a bit more idiomatically R to set optional default values to
NULL
and check for them withis.null
. However, this doesn't work for thetoken
argument, because that isNULL
when running locally. I think the function should at least be internally consistent with how it specifies optional vs required args. However this change will make the function signature less informative than the original.