Skip to content

Commit

Permalink
Merge pull request #314 from DOI-USGS/token
Browse files Browse the repository at this point in the history
Tokenized login support
  • Loading branch information
dblodgett-usgs authored Dec 19, 2023
2 parents 8a2d000 + 3c06b44 commit a107d84
Show file tree
Hide file tree
Showing 280 changed files with 23,031 additions and 2,251 deletions.
6 changes: 5 additions & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ code.json
.Renviron
README.Rmd
^CRAN-SUBMISSION$
cran-comments.md
cran-comments.md
^_pkgdown\.yml$
^docs$
^pkgdown$
^\.github$
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ manuscript/RJwrapper.aux
manuscript/RJwrapper.out
manuscript/RJwrapper.pdf
cran-comments.md
CRAN-SUBMISSION
CRAN-SUBMISSION
12 changes: 8 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: sbtools
Title: USGS ScienceBase Tools
Maintainer: David Blodgett <dblodgett@usgs.gov>
Version: 1.2.0
Version: 1.3.0
Authors@R: c(person("David", "Blodgett", role=c("cre"),
email = "dblodgett@usgs.gov"),
person("Luke", "Winslow", role = c("aut"),
Expand All @@ -24,15 +24,19 @@ Imports:
mime,
utils,
cli,
keyring
keyring,
tools
Suggests:
testthat,
xml2,
sf,
sp,
tools
knitr,
rmarkdown
License: CC0
URL: https://github.com/DOI-USGS/sbtools
BugReports: https://github.com/DOI-USGS/sbtools/issues
RoxygenNote: 7.2.3
VignetteBuilder: knitr
Config/testthat/parallel: true
Config/testthat/edition: 3
Encoding: UTF-8
7 changes: 1 addition & 6 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export(authenticate_sb)
export(current_session)
export(folder_create)
export(identifier_exists)
export(initialize_sciencebase_session)
export(is.sbitem)
export(is_logged_in)
export(item_append_files)
Expand Down Expand Up @@ -47,27 +48,21 @@ export(query_sb_spatial)
export(query_sb_text)
export(sb_datatypes)
export(sb_ping)
export(sbtools_DELETE)
export(sbtools_GET)
export(sbtools_POST)
export(sbtools_PUT)
export(session_age)
export(session_age_reset)
export(session_details)
export(session_expired)
export(session_logout)
export(session_renew)
export(session_validate)
export(set_endpoint)
export(set_expiration)
export(user_id)
import(httr)
import(jsonlite)
importFrom(curl,curl_version)
importFrom(methods,is)
importFrom(methods,new)
importFrom(mime,guess_type)
importFrom(stats,setNames)
importFrom(utils,globalVariables)
importFrom(utils,packageVersion)
importFrom(utils,setTxtProgressBar)
Expand Down
17 changes: 16 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# version 1.3.0

In this release, sbtools underwent a significant migration from `josso` login to `keycloak`-based two factor authentication. See #314 for details of the changes.

A vignette showing the old and new login methods is now included see: `vignette("sbtools")`

In addition to login modifications, a pkgdown site was created, and the package code was reorganized significantly.

- Added `initialize_sciencebase_session()` to support tokenized login.
- Sciencebase `session` object no longer returned by `authenticate_sb()`
- `current_session()` now returns the active login token.
- Removed `session_logout()` and `session_age_reset()` there is now an internal function `sbtools:::clean_session()` to accomplish the same goal.
- Removed `sbtools_DELETE()` as the method is no longer the accepted way to delete sciencebase items.
- Modified item deletion functions to use a delete helper that ensures files are removed from all locations.

# Version 1.2.0 (2023-04-28)

- added `item_publish_cloud()` to push files to S3 public cloud storage. #302
Expand All @@ -8,7 +23,7 @@
# Version 1.1.21 (2022-11-03)

- All web calls now use `httr::RETRY()` to be a bit more robust. #213
- Password management can now be done with the [`keyring` package.](https://r-lib.github.io/keyring/index.html)
- Password management can now be done with the `keyring`
- File uploads for very large files should now be more robust with longer time out tolerances.

# Version 1.1.20 (2022-10-27)
Expand Down
143 changes: 119 additions & 24 deletions R/AAA.R
Original file line number Diff line number Diff line change
@@ -1,52 +1,147 @@

#for storing session state and service URLs
pkg.env <- new.env()
pkg.env$session = NULL
pkg.env$username = ""

pkg.env$token_stache <- file.path(tools::R_user_dir(package = "sbtools"), "token")

.onLoad = function(libname, pkgname){
set_endpoint()
}

#' Set the expiration
#'
#' Called on package build
#'
#' @param expiration_age a difftime describing the length of a session
#' @export
#' @keywords internal
set_expiration <- function(expiration_age = as.difftime("00:59:00")){
if (!is(expiration_age, 'difftime') | length(expiration_age) != 1)
stop('expiration_age must be a difftime vector of length 1')
pkg.env$session_expires = expiration_age
}

default_timeout <- function(){
return(10) #seconds
}

set_expiration()

check_session <- function(x) {
if (!session_authorized(x)) {
check_session <- function(check_logged_in = FALSE) {
check <- !session_validate()

if(check_logged_in) check <- !(session_validate() & is_logged_in())

if (check) {
warning('session is not authorized. See ?authenticate_sb')
FALSE
} else {
TRUE
}
}

session_authorized <- function(session){
#' Ping ScienceBase to see if it's available
#'
#' @export
#' @param ... Additional parameters are passed on to \code{\link[httr]{GET}}
#' @return Boolean (TRUE) indicating if a connection to ScienceBase can be established
#' and if it is responding as expected. FALSE otherwise.
#' @examples \donttest{
#' #TRUE if all is well and SB can be contacted
#' sb_ping()
#' }
sb_ping <- function(...) {

return(session_validate(session) && !is.null(session))
tryCatch({
x <- GET(paste0(pkg.env$url_item, 'ping'),
timeout = httr::timeout(default_timeout()),
...)
res = jsonlite::fromJSON(content(x, "text"))
if(is(res, 'list') & !is.null(res$result) & res$result == 'OK'){
return(TRUE)
}
}, error=function(e){
return(FALSE)
})

return(FALSE)
}

session_val <- function(x) {
if (!session_validate(x)) {
stop('Session state is invalid, please re-authenticate', call. = FALSE)
#'@title Set SB endpoint
#'
#'@param endpoint Indicate which SB endpoint
#' you want to use options: \code{c('production','development')}
#'
#'@description Sets the internal URLS used to either the production
#' or development (beta) SB server. URLS are stored internally to the package
#'
#'@author Luke Winslow
#'
#'@examples \donttest{
#'set_endpoint('prod')
#'
#'# getting item from production SB servers
#'item_get('5060b03ae4b00fc20c4f3c8b')
#'
#'set_endpoint('dev')
#'# getting item from beta SB servers
#'item_get('521e4686e4b051c878dc35d0')
#'
#'}
#'
#'@export
set_endpoint = function(endpoint=c("production", "development")){

endpoint = match.arg(endpoint)

if(endpoint=="production"){
pkg.env$domain = "https://www.sciencebase.gov/"
pkg.env$graphql_url = "https://api.sciencebase.gov/graphql"
pkg.env$manager_app = "https://sciencebase.usgs.gov/manager/"
pkg.env$keycloak_client_id = "catalog"

}else if(endpoint=="development"){
pkg.env$domain = "https://beta.sciencebase.gov/"
pkg.env$graphql_url = "https://api-beta.staging.sciencebase.gov/graphql"
pkg.env$manager_app = "https://beta.staging.sciencebase.gov/manager/"
pkg.env$keycloak_client_id = "catalog"
}

pkg.env$url_base = paste0(pkg.env$domain, "catalog/")
pkg.env$url_items = paste0(pkg.env$url_base, "items/")
pkg.env$url_item = paste0(pkg.env$url_base, "item/")
pkg.env$url_upsert = paste0(pkg.env$url_base, "item/upsert")
pkg.env$url_upload = paste0(pkg.env$url_base, 'file/uploadAndUpsertItem/')
pkg.env$url_upload_create = paste0(pkg.env$url_base, 'file/uploadAndCreateItem/')
pkg.env$url_upload_update = paste0(pkg.env$url_base, 'file/uploadAndUpdateItem/')
pkg.env$url_download = paste0(pkg.env$url_base, 'file/get/')
pkg.env$url_upload_file = paste0(pkg.env$url_base, 'file/upload')
pkg.env$url_scrape = paste0(pkg.env$url_base, 'file/scrape')
pkg.env$url_login = 'https://my.usgs.gov/josso/signon/usernamePasswordLogin.do'
pkg.env$auth_server_url = paste0(pkg.env$domain, "auth")
if(endpoint == "production") {
pkg.env$token_url = paste0("https://www.sciencebase.gov/",
"auth/realms/ScienceBase/protocol/openid-connect/token")
} else if(endpoint == "development") {
pkg.env$token_url = paste0("https://www.sciencebase.gov/",
"auth/realms/ScienceBase-B/protocol/openid-connect/token")
}

pkg.env$chunk_size_bytes = 104857600 # 104857600 == 100MB

}

#' Get your parent ID
#'
#' Required for creating items
#'
#' @export
#' @param ... Additional parameters are passed on to \code{\link[httr]{POST}}
#' @return A single character string, your user id
#' @examples \dontrun{
#' user_id()
#' }
user_id <- function(...) {
if(!is.null(pkg.env$uid)) return(pkg.env$uid)

if (is.null(current_session())) stop("Please authenticate first. See ?initialize_sciencebase_session", call. = FALSE)
args <- list(s = "Search",
parentId = "4f4e4772e4b07f02db47e231",
lq = paste0("title.untouched:", pkg.env$username),
format = "json")
res <- content(query_items(args, ...))
url <- res$items[[1]]$link$url

out <- basename(url)

pkg.env$uid <- out

out
}

comp <- function(l) Filter(Negate(is.null), l)
Loading

0 comments on commit a107d84

Please sign in to comment.