Skip to content

Commit

Permalink
#4 new http request token requirements (CSRF)
Browse files Browse the repository at this point in the history
  • Loading branch information
eblondel committed Jul 13, 2018
1 parent c5f498e commit 41c835d
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 51 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: geonapi
Type: Package
Title: 'GeoNetwork' API R Interface
Version: 0.1-0
Date: 2018-04-27
Version: 0.2-0
Date: 2018-07-13
Authors@R: c(person("Emmanuel", "Blondel", role = c("aut", "cre"), email = "[email protected]", comment = c(ORCID = "0000-0002-5870-5762")))
Maintainer: Emmanuel Blondel <[email protected]>
Description: Provides an R interface to the 'GeoNetwork' API (<https://geonetwork-opensource.org/#api>) allowing to upload and publish metadata in a 'GeoNetwork' web-application and exposte it to OGC CSW.
Expand Down
53 changes: 34 additions & 19 deletions R/GNManager.R
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ GNManager <- R6Class("GNManager",
user = NULL,
pwd = NULL,
token = NULL,
cookies = NULL,

#getEditingMetadataVersion
#---------------------------------------------------------------------------
Expand Down Expand Up @@ -216,19 +217,23 @@ GNManager <- R6Class("GNManager",
#---------------------------------------------------------------------------
login = function(user, pwd){

if(self$basicAuth){
private$user = user
private$pwd = pwd
req <- NULL
if(!self$basicAuth){
gnRequest <- GNRESTRequest$new(username = user, password = pwd)
req <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.user.login",
content = GNUtils$getPayloadXML(gnRequest),
contentType = "text/xml",
verbose = self$verbose.debug
)
}else{
req <- GNUtils$GET(
url = self$getUrl(), path = NULL,
user = user, pwd = pwd, verbose = self$verbose.debug
)
}

gnRequest <- GNRESTRequest$new(username = user, password = pwd)
req <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.user.login",
content = GNUtils$getPayloadXML(gnRequest),
contentType = "text/xml",
verbose = self$verbose.debug
)
if(status_code(req) == 401){
err <- "Impossible to login to GeoNetwork: Wrong credentials"
self$ERROR(err)
Expand All @@ -244,7 +249,10 @@ GNManager <- R6Class("GNManager",
self$ERROR(err)
stop(err)
}else{
if(!self$basicAuth) private$token <- cookies(req)$value
req_cookies <- cookies(req)
cookies <- req_cookies$value
names(cookies) <- req_cookies$name
private$cookies <- cookies
self$INFO("Successfully authenticated to GeoNetwork!\n")
}
return(TRUE)
Expand Down Expand Up @@ -291,7 +299,8 @@ GNManager <- R6Class("GNManager",
req <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.metadata.insert",
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
content = GNUtils$getPayloadXML(gnRequest),
contentType = "text/xml",
verbose = self$verbose.debug
Expand Down Expand Up @@ -331,7 +340,8 @@ GNManager <- R6Class("GNManager",
req <- GNUtils$GET(
url = self$getUrl(),
path = ifelse(self$version$value$major < 3, "/metadata.admin", "md.privileges.update"),
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
query = queryParams,
verbose = self$verbose.debug
)
Expand Down Expand Up @@ -368,7 +378,8 @@ GNManager <- R6Class("GNManager",
req <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.metadata.get",
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
content = GNUtils$getPayloadXML(gnRequest),
contentType = "text/xml",
verbose = self$verbose.debug
Expand Down Expand Up @@ -465,7 +476,8 @@ GNManager <- R6Class("GNManager",
req <- GNUtils$POST(
url = self$getUrl(),
path = "/metadata.update.finish",
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
content = GNUtils$getPayloadXML(gnRequest),
contentType = "text/xml",
verbose = self$verbose.debug
Expand All @@ -490,7 +502,8 @@ GNManager <- R6Class("GNManager",
req <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.metadata.delete",
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
content = GNUtils$getPayloadXML(gnRequest),
contentType = "text/xml",
verbose = self$verbose.debug
Expand Down Expand Up @@ -520,7 +533,8 @@ GNManager <- R6Class("GNManager",
selectReq <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.metadata.select",
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
content = GNUtils$getPayloadXML(gnSelectRequest),
contentType = "text/xml",
verbose = self$verbose.debug
Expand All @@ -530,7 +544,8 @@ GNManager <- R6Class("GNManager",
deleteReq <- GNUtils$POST(
url = self$getUrl(),
path = "/xml.metadata.batch.delete",
token = private$token, user = private$user, pwd = private$pwd,
token = private$token, cookies = private$cookies,
user = private$user, pwd = private$pwd,
content = GNUtils$getPayloadXML(gnDeleteRequest),
contentType = "text/xml",
verbose = self$verbose.debug
Expand Down
69 changes: 44 additions & 25 deletions R/GNUtils.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#' Convenience method to parse XML response from GeoNetwork REST API. Although package \pkg{httr}
#' suggests the use of \pkg{xml2} package for handling XML, \pkg{geonapi} still relies
#' on the package \pkg{XML}. Response from \pkg{httr} is retrieved as text, and then parsed as
#' XML using \code{\link[XML]{xmlParse}} function.
#' XML 'xmlParse' function.
#' }
#' \item{\code{getPayloadXML(obj)}}{
#' Convenience method to create payload XML to send to GeoNetwork.
Expand All @@ -51,31 +51,36 @@ GNUtils$getUserAgent <- function(){
return(paste("geonapi", packageVersion("geonapi"), sep="-"))
}

GNUtils$GET <- function(url, path, token = NULL, user = NULL, pwd = NULL,
GNUtils$GET <- function(url, path = NULL, token = NULL, cookies = NULL,
user = NULL, pwd = NULL,
query = NULL, verbose = FALSE){
if(verbose){
req <- with_verbose(GNUtils$GET(url, path, token, user, pwd, query))
req <- with_verbose(GNUtils$GET(url, path, token, cookies, user, pwd, query))
}else{
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
if(!is.null(path)){
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
}
if(!is.null(user) && !is.null(pwd)){
req <- httr::GET(
url = url,
query = query,
add_headers(
"User-Agent" = GNUtils$getUserAgent(),
"Authorization" = paste("Basic", GNUtils$getUserToken(user, pwd))
"Authorization" = paste("Basic", GNUtils$getUserToken(user, pwd)),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),"")
)
)
}else{
req <- httr::GET(
url = url,
query = query,
add_headers(
"User-Agent" = GNUtils$getUserAgent()
"User-Agent" = GNUtils$getUserAgent(),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),"")
),
set_cookies(
JSESSIONID = token
cookies
)
)
}
Expand All @@ -84,11 +89,12 @@ GNUtils$GET <- function(url, path, token = NULL, user = NULL, pwd = NULL,
return(req)
}

GNUtils$PUT <- function(url, path, token = NULL, user = NULL, pwd = NULL,
GNUtils$PUT <- function(url, path = NULL, token = NULL, cookies = NULL,
user = NULL, pwd = NULL,
content = NULL, filename = NULL,
contentType, verbose = FALSE){
if(verbose){
req <- with_verbose(GNUtils$PUT(url, path, token, user, pwd, content, filename, contentType))
req <- with_verbose(GNUtils$PUT(url, path, token, cookies, user, pwd, content, filename, contentType))
}else{
body <- NULL
if(missing(content) | is.null(content)){
Expand All @@ -100,14 +106,17 @@ GNUtils$PUT <- function(url, path, token = NULL, user = NULL, pwd = NULL,
body <- content
}

if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
if(!is.null(path)){
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
}
if(!is.null(user) && !is.null(pwd)){
req <- httr::PUT(
url = url,
add_headers(
"User-Agent" = GNUtils$getUserAgent(),
"Authorization" = paste("Basic", GNUtils$getUserToken(user, pwd)),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),""),
"Content-type" = contentType
),
body = body
Expand All @@ -117,10 +126,11 @@ GNUtils$PUT <- function(url, path, token = NULL, user = NULL, pwd = NULL,
url = url,
add_headers(
"User-Agent" = GNUtils$getUserAgent(),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),""),
"Content-type" = contentType
),
set_cookies(
JSESSIONID = token
cookies
),
body = body
)
Expand All @@ -129,19 +139,23 @@ GNUtils$PUT <- function(url, path, token = NULL, user = NULL, pwd = NULL,
return(req)
}

GNUtils$POST <- function(url, path, token = NULL, user = NULL, pwd = NULL,
GNUtils$POST <- function(url, path = NULL, token = NULL, cookies = NULL,
user = NULL, pwd = NULL,
content, contentType, verbose = FALSE){
if(verbose){
req <- with_verbose(GNUtils$POST(url, path, token, user, pwd, content, contentType))
req <- with_verbose(GNUtils$POST(url, path, token, cookies, user, pwd, content, contentType))
}else{
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
if(!is.null(path)){
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
}
if(!is.null(user) && !is.null(pwd)){
req <- httr::POST(
url = url,
add_headers(
"User-Agent" = GNUtils$getUserAgent(),
"Authorization" = paste("Basic", GNUtils$getUserToken(user, pwd)),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),""),
"Content-type" = contentType
),
body = content
Expand All @@ -151,10 +165,11 @@ GNUtils$POST <- function(url, path, token = NULL, user = NULL, pwd = NULL,
url = url,
add_headers(
"User-Agent" = GNUtils$getUserAgent(),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),""),
"Content-type" = contentType
),
set_cookies(
JSESSIONID = token
cookies
),
body = content
)
Expand All @@ -163,28 +178,32 @@ GNUtils$POST <- function(url, path, token = NULL, user = NULL, pwd = NULL,
return(req)
}

GNUtils$DELETE <- function(url, path, token = NULL, user = NULL, pwd = NULL, verbose = FALSE){
GNUtils$DELETE <- function(url, path = NULL, token = NULL, cookies = NULL, user = NULL, pwd = NULL, verbose = FALSE){
if(verbose){
req <- with_verbose(GNUtils$DELETE(url, path, token, user, pwd))
req <- with_verbose(GNUtils$DELETE(url, path, token, cookies, user, pwd))
}else{
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
if(!is.null(path)){
if(!grepl("^/", path)) path = paste0("/", path)
url <- paste0(url, path)
}
if(!is.null(user) && !is.null(pwd)){
req <- httr::DELETE(
url = url,
add_headers(
"User-Agent" = GNUtils$getUserAgent(),
"Authorization" = paste("Basic", GNUtils$getUserToken(user, pwd))
"Authorization" = paste("Basic", GNUtils$getUserToken(user, pwd)),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),"")
)
)
}else{
req <- httr::DELETE(
url = url,
add_headers(
"User-Agent" = GNUtils$getUserAgent()
"User-Agent" = GNUtils$getUserAgent(),
"X-XSRF-TOKEN" = ifelse(!is.null(cookies), as.character(cookies["XSRF-TOKEN"]),"")
),
set_cookies(
JSESSIONID = token
cookies
)
)
}
Expand Down
4 changes: 2 additions & 2 deletions R/geonapi.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#' \tabular{ll}{
#' Package: \tab geonapi\cr
#' Type: \tab Package\cr
#' Version: \tab 0.1-0\cr
#' Date: \tab 2018-04-27\cr
#' Version: \tab 0.2-0\cr
#' Date: \tab 2018-07-13\cr
#' License: \tab MIT\cr
#' LazyLoad: \tab yes\cr
#' }
Expand Down
2 changes: 1 addition & 1 deletion man/GNUtils.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/geonapi.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 41c835d

Please sign in to comment.