httr2 icon indicating copy to clipboard operation
httr2 copied to clipboard

Enable user response when `oauth_flow_auth_code()` is called indirectly

Open fh-mthomson opened this issue 1 year ago • 1 comments

While using oauth_token_cached() with flow = oauth_flow_auth_code and cache_disk = TRUE (as added in #349):

  1. ~99% of calls successfully leverage the cache (or reauthenticate in the background)
  2. ~ 1% of calls trigger a new prompt

Each are the expected behavior, which has been immensely helpful!

But, a nuance we've since realized is that if (2) happens when called indirectly:

  1. sequential R chunks run in .Rmd: doesn't always wait for the user to enter a code before trying to run the subsequent code. FWIW I've noticed the same in gargle per https://github.com/r-lib/gargle/blob/main/R/oauth-init.R#L133
  2. knitted .Rmd: won't run, since it's non-interactive

(1) is a side effect of the expected and well-documented behavior of readline() that it doesn't necessarily wait for use input at all costs.

One option could be using an rstudioapi alternate in oauth_flow_auth_code_read(), but that's not as generalizable:

oauth_flow_auth_code_read <- function(state) {
  prompt <- "Enter authorization code or URL: "
  code <- rstudioapi::askForPassword(prompt)
  code <- trimws(code)
...
}

(2) Could likely be offset by changing https://github.com/r-lib/httr2/blob/main/R/oauth-flow-auth-code.R#L145, akin to #171

Here's one way to reproduce (1), to start:

  1. Creating a new .Rmd file with two chunks:
# googlesheets4::gs4_auth()
# or
httr2:::oauth_flow_auth_code_read("state")
summary(cars)
  1. Run All (not knit) image

Sends to the R Console:

> # Chunk 1
> # googlesheets4::gs4_auth()
> # or
> httr2:::oauth_flow_auth_code_read("state")
Enter authorization code or URL: 
Enter state parameter: # Chunk 2
Error in `httr2:::oauth_flow_auth_code_read()`:
! Authentication failure: state does not match
Run `rlang::last_trace()` to see where the error occurred.

fh-mthomson avatar Dec 07 '23 02:12 fh-mthomson