Skip to content
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

Tokenized login support #314

Merged
merged 37 commits into from
Dec 19, 2023
Merged

Tokenized login support #314

merged 37 commits into from
Dec 19, 2023

Conversation

dblodgett-usgs
Copy link
Collaborator

@dblodgett-usgs dblodgett-usgs commented Nov 20, 2023

fixes #311 fixes #313

This is a fairly major update to the package. It includes a pkgdown site and a considerable amount of change in the authentication system under the covers. The package no longer relies on a session object, but rather stores a keycloak token and token expiration information in a session environment. This may not be the best way to handle the token in the long run, but it works for the time being.

Am seeking review but this needs to be done for a pending change on sciencebase so we may merge sooner than later to get on cran in time for the changes occurring upstream.

@dblodgett-usgs
Copy link
Collaborator Author

sbtools-coverage.zip
for the record -- coverage report with login generated locally.

@gregor-fausto
Copy link

I installed the token branch and confirmed that I installed the correct branch. I first checked whether I was still able to authenticate with authenticate_sb and it looks like it still works. I then ran initialize_sciencebase_session(), which did open a browser window that prompted a login, as described

The new way uses `initialize_sciencebase_session()` to open a browser window. Once logged in, you can get a token from the user drop down in the upper right. For this example, that token has been saved as an environment variable.
. When I log in, I get taken to https://sciencebase.usgs.gov/manager/ but don't see a token.

# install branch for testing authentication via token
remotes::install_github("DOI-USGS/sbtools",force=TRUE,ref='token')

# check to make sure I've installed the right branch
# https://stackoverflow.com/questions/60982775/r-check-which-branch-of-a-package-was-installed-with-install-git
packageDescription('sbtools')

library(sbtools)
# authenticate_sb(username="...")
initialize_sciencebase_session()

@dblodgett-usgs
Copy link
Collaborator Author

Thanks @gregor-fausto do you see the copy button in the upper right as in:
image

@gregor-fausto
Copy link

Yes, I do and see now that this is what the help file for initialize_sciencebase_session() describes. I also had to make sure that I supplied initialize_sciencebase_session with my username. After that, https://github.com/DOI-USGS/sbtools/blob/fa90d6b38a2430f7f03a6989dc1f01587163d43b/vignettes/sbtools.Rmd#L94C1-L108C17 run for me. Session info:

R version 4.2.2 (2022-10-31)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Ventura 13.6.1

@dblodgett-usgs
Copy link
Collaborator Author

Great - what do you think would be helpful in terms of documenting how this is supposed to work?

@gregor-fausto
Copy link

gregor-fausto commented Nov 20, 2023

For context, I'm a new user to ScienceBase and sbtools. Here are some things that come to mind:

  • The documentation for authenticate_sb has the following statement: "If you do not supply a username or password, you will be prompted to enter them." It may be useful to do something similar for initialize_sciencebase_session (prompt a user for a username if they do not enter one), or include something in the documentation along the lines of 'Users need to provide a username.'
  • This might be too verbose/descriptive but the second sentence in the initialize_sciencebase_session could specify "Once logged in, retrieve the token from the user drop down in the upper right hand corner of the browser. Click the icon with the silhouette of a person, and select 'Copy API Token.'"
  • Do you plan to deprecate authenticate_sb, or keep both it and the new authentication method? If the latter, or if you're planning for a transition period, you may want to steer users to your preferred approach by including something a warning when someone runs authenticate_sb and/or updating the help file.

@dblodgett-usgs
Copy link
Collaborator Author

Great -- thanks for that. Will do all three.

@jesse-ross
Copy link
Contributor

I also found the documentation a little bit confusing. I initially used the token_text environment variable to define the name of a file I wanted my credentials to be put in, and of course initialize_sciencebase_session() then freaked out because that string wasn't JSON. So I think it could be made clearer that token_text is meant to be the JSON token itself.

Once I figured that out, I was able to trigger the login window both on Windows (RStudio 2023.06.0, R 4.2.3) and on WSL/Ubuntu (RStudio 2023.09.0, R 4.3.2). And storing the token and my username in my .Renviron meant that I could start a fresh R session, invoke initialize_sciencebase_session(Sys.getenv("sb_user"), Sys.getenv("token_text")), and interact with SB without any prompts. 👌

I ran into one other awkward thing when I tried running this in plain R, outside of RStudio. When we're outside of the RStudio context, readPassword() just uses readline() to read a single line. But the auth token from sciencebase has several lines. I had to manually serialize it down to a single line to be able to enter it. A couple possible approaches for fixing this:

  1. Document that it has to be done
  2. Get the SB folks to serialize the JSON before the user copies it
  3. Replace this line with something like pass <- readLines(n = 4) (but this depends on the SB folks not changing the number of lines in the token)

I'm curious what the effect here will be on unattended workflows. Do you know how long the token lasts? I have some SB workflows which take many hours.

@dblodgett-usgs
Copy link
Collaborator Author

I had the same thought about the multi-line token text that you copy from the manager app. I'll ask them about just making it a single line of json.

@dblodgett-usgs
Copy link
Collaborator Author

Based on this review and further work to clean this all up -- I've decided to use a different approach to saving the token. There's now a very simple cache in a temp file at file.path(tools::R_user_dir(package = "sbtools"), "token")

I have a function that pulls from that path:

> sbtools:::grab_token
function() {
	if(file.exists(pkg.env$token_stache)) {
		readChar(pkg.env$token_stache, file.info(pkg.env$token_stache)$size)
	} else {
		""
	}
}

When you call initialize_sciencebase_session() it not checks for an sb_user environment variable and prompts if one is not found.

It then calls grab_token() and tries to initialize a session with the token if one is retrieved. If that fails, it prompts for a new token and updates the one in the cache.

The affect is that if you have an sb_user environment variable you only have to call initialize_sciencebase_session() and enter a token once. I hope to figure out how to keep the cached token alive by continually refreshing it as long as an interactive or long running session is running, but that will be future work at this point.

@dblodgett-usgs
Copy link
Collaborator Author

Per #316

image test coverage when logged in is doing good.

@dblodgett-usgs
Copy link
Collaborator Author

CRAN submission is in -- will merge once accepted.

@dblodgett-usgs dblodgett-usgs merged commit a107d84 into main Dec 19, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

POSTing a new file fails with token authentication. Support token based authentication instead of password.
3 participants