inbo / etn

R package to access data from the European Tracking Network
https://inbo.github.io/etn/
MIT License
6 stars 5 forks source link

Store credentials in `.Renviron`, or switch to `keyring`? #335

Open PietrH opened 2 weeks ago

PietrH commented 2 weeks ago
2.  When not inputting the userid correctly (happened to me that I was running several lines of code quickly after each other, and the next line was taken as input), is there a way to make the prompt for userid and pwd reappear? Or is it maybe also possible to store userid and pwd somewhere? (.Renviron does not work, which was expected).

Originally posted by @lottepohl in https://github.com/inbo/etn/issues/318#issuecomment-2447216295

{rgbif} stores user credentials in .Renviron, however, making changes automatically to this file could cause unexpected results for users. It is making a change outside of the environment of the package, same with Sys.setenv() really. I'm thinking about this section in the R Packages book 2nd edition: https://r-pkgs.org/code.html#sec-code-r-landscape

Storing information here is simple enough: usethis::edit_r_environ(), but is this a better solution than Sys.setenv() on the long term?

{keyring} is used by {move2}: https://gitlab.com/bartk/move2/-/blob/main/R/movebank_credentials.R and is something I had in mind on the long run

  keyring::key_set_with_value(
    username = username, password = password,
    service = key_name, keyring = getOption("move2_movebank_keyring")
  )

The working of usethis::edit_r_environ() isn't too complex internally:

function (scope = c("user", "project")) 
{
    path <- scoped_path_r(scope, ".Renviron", envvar = "R_ENVIRON_USER")
    edit_file(path)
    ui_bullets(c(`_` = "Restart R for changes to take effect."))
    invisible(path)
}

With helper:

function (scope = c("user", "project"), ..., envvar = NULL) 
{
    scope <- match.arg(scope)
    if (scope == "user" && !is.null(envvar)) {
        env <- Sys.getenv(envvar, unset = "")
        if (!identical(env, "")) {
            return(user_path_prep(env))
        }
    }
    root <- switch(scope, user = path_home_r(), project = proj_get())
    path(root, ...)
}

And cascades into more and more helpers... But it could be done