Check if authorization is supported
Change-Id: If2dd75b629a0ae958d98ae220ec90a78decd0e95
diff --git a/R/KorAPConnection.R b/R/KorAPConnection.R
index b5ee9c3..cd68a67 100644
--- a/R/KorAPConnection.R
+++ b/R/KorAPConnection.R
@@ -20,6 +20,7 @@
#' @slot accessToken OAuth2 access token.
#' @slot oauthClient OAuth2 client object.
#' @slot oauthScope OAuth2 scope.
+#' @slot authorizationSupported logical that indicates if authorization is supported/necessary for the current KorAP instance. Automatically set during initialization.
#' @slot userAgent user agent string used for connection the API.
#' @slot timeout timeout in seconds for API requests (this does not influence server internal timeouts)
#' @slot verbose logical that decides whether operations will default to be verbose.
@@ -27,7 +28,13 @@
#' @slot welcome list containing HTTP response received from KorAP server welcome function.
#' @export
-KorAPConnection <- setClass("KorAPConnection", slots=c(KorAPUrl="character", apiVersion="character", indexRevision="characterOrNULL", apiUrl="character", accessToken="characterOrNULL", oauthClient="ANY", oauthScope="characterOrNULL", userAgent="character", timeout="numeric", verbose="logical", cache="logical", welcome="listOrNULL"))
+KorAPConnection <- setClass("KorAPConnection", slots=c(KorAPUrl="character", apiVersion="character", indexRevision="characterOrNULL", apiUrl="character", accessToken="characterOrNULL", oauthClient="ANY", oauthScope="characterOrNULL", authorizationSupported="logical", userAgent="character", timeout="numeric", verbose="logical", cache="logical", welcome="listOrNULL"))
+
+generic_kor_app_id = "99FbPHH7RrN36hbndF7b6f"
+
+kustvakt_redirect_uri = "http://localhost:1410/"
+kustvakt_auth_path = "settings/oauth/authorize"
+
#' @param .Object KorAPConnection object
#' @param KorAPUrl URL of the web user interface of the KorAP server instance you want to access.
@@ -36,7 +43,7 @@
#' @param accessToken OAuth2 access token. For queries on corpus parts with restricted
#' access (e.g. textual queries on IPR protected data), you need to authorize
#' your application with an access token.
-#' You can obtain an access token using the [auth()] method.
+#' You can obtain an access token in the OAuth settings of your KorAP web interface.
#'
#' More details are explained in the
#' [authorization section](https://github.com/KorAP/RKorAPClient#authorization)
@@ -73,7 +80,7 @@
#'
#' @param oauthClient OAuth2 client object.
#' @param oauthScope OAuth2 scope.
-#' @param authorizationPossible logical that indicates if authorization is possible/necessary for the current KorAP instance. Automatically set during initialization.
+#' @param authorizationSupported logical that indicates if authorization is supported/necessary for the current KorAP instance. Automatically set during initialization.
#' @param userAgent user agent string.
#' @param timeout tineout in seconds for API requests (this does not influence server internal timeouts).
#' @param verbose logical that decides whether following operations will default to
@@ -103,7 +110,7 @@
#' @rdname KorAPConnection-class
#' @export
setMethod("initialize", "KorAPConnection",
- function(.Object, KorAPUrl = "https://korap.ids-mannheim.de/", apiVersion = 'v1.0', apiUrl, accessToken = getAccessToken(KorAPUrl), oauthClient = NULL, oauthScope = "search match_info", userAgent = "R-KorAP-Client", timeout=240, verbose = FALSE, cache = TRUE) {
+ function(.Object, KorAPUrl = "https://korap.ids-mannheim.de/", apiVersion = 'v1.0', apiUrl, accessToken = getAccessToken(KorAPUrl), oauthClient = NULL, oauthScope = "search match_info", authorizationSupported = TRUE, userAgent = "R-KorAP-Client", timeout=240, verbose = FALSE, cache = TRUE) {
.Object <- callNextMethod()
m <- regexpr("https?://[^?]+", KorAPUrl, perl = TRUE)
.Object@KorAPUrl <- regmatches(KorAPUrl, m)
@@ -120,14 +127,23 @@
.Object@apiVersion = apiVersion
.Object@userAgent = userAgent
.Object@oauthScope = oauthScope
+ .Object@authorizationSupported = authorizationSupported
.Object@timeout = timeout
.Object@verbose = verbose
.Object@cache = cache
.Object@welcome = apiCall(.Object, .Object@apiUrl, json = FALSE, cache = FALSE, getHeaders = TRUE)
if (!is.null(.Object@welcome)) {
message(.Object@welcome[[2]])
+ resp <- httr2::request(.Object@KorAPUrl) |>
+ httr2::req_url_path_append(kustvakt_auth_path) |>
+ httr2::req_error(is_error = \(resp) FALSE) |>
+ httr2::req_perform()
+ .Object@authorizationSupported = (httr2::resp_status(resp) == 200)
+
+ .Object@indexRevision <- .Object@welcome[[1]][["x-index-revision"]]
+ } else {
+ message("Could not connect to KorAP instance ", .Object@KorAPUrl)
}
- .Object@indexRevision <- .Object@welcome[[1]][["x-index-revision"]]
.Object
})
@@ -194,15 +210,11 @@
kco
})
-generic_kor_app_id = "99FbPHH7RrN36hbndF7b6f"
-
-kustvakt_redirekt_uri = "http://localhost:1410/"
-kustvakt_auth_path = "settings/oauth/authorize"
oauthRefresh <- function(req, client, scope, kco) {
httr2::req_oauth_auth_code(req, client, scope = scope,
auth_url = paste0(kco@KorAPUrl, kustvakt_auth_path),
- redirect_uri = kustvakt_redirekt_uri,
+ redirect_uri = kustvakt_redirect_uri,
cache_key = kco@KorAPUrl)
}
@@ -235,6 +247,10 @@
#'
#' @export
setMethod("auth", "KorAPConnection", function(kco, app_id = generic_kor_app_id, app_secret = NULL, scope = kco@oauthScope) {
+ if (kco@authorizationSupported == FALSE) {
+ log_info(kco@verbose, "Authorization is not supported by this KorAP instance.")
+ return(kco)
+ }
if ( kco@KorAPUrl != "https://korap.ids-mannheim.de/" & app_id == generic_kor_app_id) {
warning(paste("You can use the default app_id only for the IDS Mannheim KorAP main instance for querying DeReKo. Please provide your own app_id for accesing", kco@KorAPUrl))
return(kco)
@@ -251,7 +267,7 @@
httr2::oauth_flow_auth_code(
scope = scope,
auth_url = paste0(kco@KorAPUrl, kustvakt_auth_path),
- redirect_uri = kustvakt_redirekt_uri
+ redirect_uri = kustvakt_redirect_uri
))$access_token
log_info(kco@verbose, "Client authorized. New access token set.")
} else {
@@ -283,8 +299,8 @@
}
-warnIfNoAccessToken <- function(kco) {
- if (is.null(kco@accessToken) & is.null(kco@oauthClient)) {
+warnIfNotAuthorized <- function(kco) {
+ if (kco@authorizationSupported & is.null(kco@accessToken) & is.null(kco@oauthClient)) {
warning(
paste0(
"In order to receive KWICSs also from corpora with restricted licenses, you may need to\n",
@@ -351,40 +367,33 @@
req <- req |> httr2::req_auth_bearer_token(kco@accessToken)
}
- # Perform the request and handle errors
- resp <- tryCatch(
- req |> httr2::req_perform(),
- error = function(e) {
- message(if(kco@verbose) "\n" else "", "Request failed: ", paste(e$message, e$parent$message, sep = " "))
- e$resp
- }
- )
-#
- if (is.null(resp)) return(invisible(NULL))
+ resp <- req |>
+ httr2::req_error(is_error = \(resp) FALSE) |>
+ httr2::req_perform()
- # Check response status
+ # if (is.null(resp)) return(invisible(NULL))
+
if (resp |> httr2::resp_status() != 200) {
-
- message("API request failed with status: ", resp |> httr2::resp_status())
-
- result <- tryCatch(
- resp |> httr2::resp_body_json(),
- error = function(e) {
- message("Failed to parse json with error details: ", e$message)
- return(NULL)
+ message("Request failed with status ", resp |> httr2::resp_status(), ": ", resp |> httr2::resp_status_desc())
+ if (resp |> httr2::resp_content_type() == "application/json") {
+ result <- tryCatch(
+ resp |> httr2::resp_body_json(),
+ error = function(e) {
+ message("Failed to parse json with error details: ", e$message)
+ return(NULL)
+ }
+ )
+ # Handle errors in the response (if any)
+ if (!is.null(result$errors)) {
+ errors <- result$errors
+ warning_msgs <- if (is.data.frame(errors)) {
+ apply(errors, 1, function(warning) paste(warning[1], ": ", warning[2]))
+ } else {
+ lapply(errors, function(error) paste(error, collapse = " "))
+ }
+ message(paste(warning_msgs, collapse = "\n"))
}
- )
- # Handle errors in the response (if any)
- if (!is.null(result$errors)) {
- errors <- result$errors
- warning_msgs <- if (is.data.frame(errors)) {
- apply(errors, 1, function(warning) paste(warning[1], ": ", warning[2]))
- } else {
- lapply(errors, function(error) paste(error, collapse = " "))
- }
- message(paste(warning_msgs, collapse = "\n"))
}
-
return(invisible(NULL))
}
diff --git a/man/KorAPConnection-class.Rd b/man/KorAPConnection-class.Rd
index d8573f8..a7da86f 100644
--- a/man/KorAPConnection-class.Rd
+++ b/man/KorAPConnection-class.Rd
@@ -20,6 +20,7 @@
accessToken = getAccessToken(KorAPUrl),
oauthClient = NULL,
oauthScope = "search match_info",
+ authorizationSupported = TRUE,
userAgent = "R-KorAP-Client",
timeout = 240,
verbose = FALSE,
@@ -51,7 +52,7 @@
\item{accessToken}{OAuth2 access token. For queries on corpus parts with restricted
access (e.g. textual queries on IPR protected data), you need to authorize
your application with an access token.
-You can obtain an access token using the \code{\link[=auth]{auth()}} method.
+You can obtain an access token in the OAuth settings of your KorAP web interface.
More details are explained in the
\href{https://github.com/KorAP/RKorAPClient#authorization}{authorization section}
@@ -87,7 +88,7 @@
\item{oauthScope}{OAuth2 scope.}
-\item{authorizationPossible}{logical that indicates if authorization is possible/necessary for the current KorAP instance. Automatically set during initialization.}
+\item{authorizationSupported}{logical that indicates if authorization is supported/necessary for the current KorAP instance. Automatically set during initialization.}
\item{userAgent}{user agent string.}
@@ -134,6 +135,8 @@
\item{\code{oauthScope}}{OAuth2 scope.}
+\item{\code{authorizationSupported}}{logical that indicates if authorization is supported/necessary for the current KorAP instance. Automatically set during initialization.}
+
\item{\code{userAgent}}{user agent string used for connection the API.}
\item{\code{timeout}}{timeout in seconds for API requests (this does not influence server internal timeouts)}