Skip to content

Commit

Permalink
autodetect oidc clients containing openeo in id (#146)
Browse files Browse the repository at this point in the history
* autodetect default oidc client which contain "openeo" in its client_id
* renamed an internal print function for debugging
  • Loading branch information
flahn committed Feb 15, 2024
1 parent 9e50642 commit 9a159fd
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 24 deletions.
32 changes: 25 additions & 7 deletions R/authentication.R
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ BasicAuth <- R6Class(
res = req_perform(req)

if (is.debugging()) {
print(res)
print_response(res)
}

if (res$status_code == 200) {
Expand Down Expand Up @@ -662,13 +662,31 @@ OIDCAuthCodeFlow <- R6Class(
}

.get_client = function(clients, grant, config) {
if (length(clients) == 0) return(NULL)

supported = which(sapply(clients, function(p) grant %in% p$grant_types))
if (length(supported) > 0) {
config$client_id = clients[[supported[[1]]]]$id
config$grant_type = grant
return(config)

if (length(supported) == 0) return(NULL)

if (length(supported) > 1) {
# screen the ids for containment of something with openeo before selecting the first
client_ids = sapply(clients[supported], function(c)c$id)
openeo_named = which(grepl(x = tolower(client_ids),pattern = "openeo"))

if (length(openeo_named) == 1) {
supported = supported[openeo_named]
}
}
else {
return (NULL)

if (length(supported) > 1) {
message("Multiple default clients detected for this authentication provider. You might need to login with a custom configuration for `client_id`.")
}

config$client_id = clients[[supported[[1]]]]$id
config$grant_type = grant
return(config)
}

.get_default_client_ids = function(provider) {
client_ids = sapply(provider$default_clients, function(x) x$id)
}
10 changes: 5 additions & 5 deletions R/client.R
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ OpenEOClient <- R6Class(
response = req_perform(req)

if (is.debugging()) {
print(response)
print_response(response)
}

if (response$status_code < 400) {
Expand Down Expand Up @@ -575,7 +575,7 @@ OpenEOClient <- R6Class(
# response = DELETE(url=url, config = header, ...)

if (is.debugging()) {
print(response)
print_response(response)
}

# message = content(response)
Expand Down Expand Up @@ -629,7 +629,7 @@ OpenEOClient <- R6Class(
response = req_perform(req)

if (is.debugging()) {
print(response)
print_response(response)
}

if (response$status_code < 400) {
Expand Down Expand Up @@ -687,7 +687,7 @@ OpenEOClient <- R6Class(
response = req_perform(req)

if (is.debugging()) {
print(response)
print_response(response)
}

if (response$status_code < 400) {
Expand Down Expand Up @@ -732,7 +732,7 @@ OpenEOClient <- R6Class(
response = req_perform(req)

if (is.debugging()) {
print(response)
print_response(response)
}

if (response$status_code < 400) {
Expand Down
22 changes: 11 additions & 11 deletions R/debugging.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,44 +23,44 @@ is.debugging = function() {
return(get(x = "DEBUG_MODE", envir = pkgEnvironment))
}

print.response = function(x) {
print_response = function(x) {
print(x$request)

cat("\n*** Response ***", paste("Status:", x$status_code), "Headers:", sep = "\n")

headers = as.data.frame(cbind(resp_headers(x)))
names(headers) = NULL

print(headers)

if (!is.null(headers["content-length", ]) && unlist(headers["content-length", ]) != "0") {
cat("\nBody:", sep = "\n")

if ("content-disposition" %in% rownames(headers)) {
cat(paste("File attachment:", unlist(strsplit(x = unlist(headers["content-disposition", ]), split = "filename=")))[2], sep = "\n")
}

if ("content-type" %in% rownames(headers) && unlist(headers["content-type", ]) == "application/json") {
print(jsonlite::toJSON(resp_body_json(x), auto_unbox = TRUE, pretty = TRUE, digits = NA))
} else {
print("Other formats not yet implemented.")
}

}
}

print.request = function(x) {
print_request = function(x) {
call = paste(x$method, x$url)
headers = x$headers
if (!is.null(x$options$httpauth) && x$options$httpauth == 1 && !is.null(x$options$userpwd)) {
headers = c(headers, Authorization = paste("Basic", base64_enc(x$options$userpwd)))
}
headers = as.data.frame(headers)
names(headers) = NULL

cat("*** Request ***", call, "Headers:", sep = "\n")
print(headers)

if (!is.null(x$options$postfields)) {
cat("Body:", sep = "\n")
print(prettify(rawToChar(x$options$postfields)))
Expand Down
6 changes: 5 additions & 1 deletion R/print-functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,11 @@ print.Provider = function(x, ...) {

if ("default_clients" %in% names(x) && length(x$default_clients) > 0) {
cat("\n")
cat("Default client configurations provided.")
cat("Default client configurations provided.\n")
client_id = .get_default_client_ids(x)
if (length(client_id > 1)) {
message(paste0("Multiple default clients detected for this authentication provider. You might need to login with a custom configuration for `client_id` with one of the following ids: ",paste0(client_id,collapse=", ")))
}
} else {
message("The back-end provider did not specify default clients. Use a back-end specific configuration on login! For more information contact the openEO back-end provider.")
}
Expand Down
49 changes: 49 additions & 0 deletions tests/testthat/test-oidc-default-client-select.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
test_that(".get_client works with openeo client_id", {
default_clients = list(list(id="sh-123wd-ws3fs5gf",
grant_types=list("authorization_code+pkce",
"urn:ietf:params:oauth:grant-type:device_code+pkce",
"refresh_token"),
redirect_urls=list()),
list(id = "some-oidc-openeo-client",
grant_types=list("authorization_code+pkce",
"urn:ietf:params:oauth:grant-type:device_code+pkce",
"refresh_token"),
redirect_urls=list()))

c=.get_client(default_clients,grant="urn:ietf:params:oauth:grant-type:device_code+pkce",config=list())

expect_equal(object = c$client_id,expected = "some-oidc-openeo-client",label="openeo client is selected")
})


test_that(".get_client works with compatible first select", {
default_clients = list(list(id="sh-123wd-ws3fs5gf",
grant_types=list("authorization_code+pkce",
"urn:ietf:params:oauth:grant-type:device_code+pkce",
"refresh_token"),
redirect_urls=list()),
list(id = "some-oidc-client",
grant_types=list("authorization_code+pkce",
"urn:ietf:params:oauth:grant-type:device_code+pkce",
"refresh_token"),
redirect_urls=list()))

c=.get_client(default_clients,grant="urn:ietf:params:oauth:grant-type:device_code+pkce",config=list())

expect_equal(object = c$client_id,expected = "sh-123wd-ws3fs5gf",label="first client is selected")
})

test_that(".get_client fails with non compatible", {
default_clients = list(list(id="sh-123wd-ws3fs5gf",
grant_types=list("foo+bar",
"refresh_token"),
redirect_urls=list()),
list(id = "some-oidc-client",
grant_types=list("foo+bar",
"refresh_token"),
redirect_urls=list()))

c=.get_client(default_clients,grant="urn:ietf:params:oauth:grant-type:device_code+pkce",config=list())

expect_null(object = c$client_id,label="first client is selected")
})

0 comments on commit 9a159fd

Please sign in to comment.