rcurlovh

How to sign OVH API in R (or Curl)


I tried to grab list of my domains on OVH account.

I tried code as bellow


library(httr)
library(dplyr)
library(jsonlite)

urlAPI <- "https://ca.api.ovh.com/v1/domain"

GETendpoint <- "endpoint=ovh-eu"
GETappKey <- "&application_key=XX"
GETappSecret <- "&application_secret=XX"
GETconsKey <-  "&consumer_key=XX"

urlGET <- paste(urlAPI, "?", GETendpoint, GETappKey,GETappSecret,GETconsKey, sep = "")


OVH  <-
  GET(
    urlGET
  )

GET_OVH <-OVH %>% content("text") %>% fromJSON(flatten = F)

This gives me response


[1] "You must login first"

How can i login and grab data from OVH account?


Solution

  • I don't have an account at that site so I can't really test, but looking at the documentation and code samples they provide, it seems you need to sign your requests with a sha1 signature. I don't know of any built in methods for this. Assuming you've created your applications keys as described here https://help.ovhcloud.com/csm/en-ca-api-getting-started-ovhcloud-api?id=kb_article_view&sysparm_article=KB0029722#advanced-usage-pair-ovhcloud-apis-with-an-application

    Here's a reference function that will implement signing that seems inline with their documentation

    OVH <- function(appKey, appSecret, consKey) {
      OVH_CALL <- function(method, url, query=NULL, data=NULL, sign=TRUE) {
        url <- httr::modify_url(url, query=query)
        body <- if (!is.null(data)) jsonlite::toJSON(data, auto_unbox=TRUE) else NULL
        method <- toupper(method)
        headers <- httr::add_headers()
        if (sign) {
          now <- as.character(floor(as.numeric(Sys.time())))
          signature <- paste0("$1$", digest::digest(paste(appSecret, consKey, method, url, body, now, sep="+"), algo="sha1", serialize=FALSE))
          headers <- httr:::request_combine(headers, httr::add_headers(
            "X-Ovh-Application" = appKey,
            "X-Ovh-Consumer" = consKey,
            "X-Ovh-Timestamp" = now,
            "X-Ovh-Signature" = signature
          ))
        }
        
        if (!is.null(data)) {
          headers <- httr:::request_combine(headers, httr::add_headers("Content-type"="application/json"))
        }
        fun <- list("GET" = httr::GET, "POST"=httr::POST)
        fun[[method]](url, headers, body=body)
      }
      OVH_GET <- function(url, query=NULL, sign=TRUE) {
        OVH_CALL("GET", url, query=query, sign=sign)
      }
      OVH_POST <- function(url, query=NULL, data=NULL, sign=TRUE) {
        OVH_CALL("POST", url, query=query, data=data, sign=sign)
      }
      list(GET = OVH_GET, POST = OVH_POST)
    }
    

    This function returns an object with GET and POST methods to take care of the signing. So you would use it like

    appKey <- "application_key"
    appSecret <- "application_secret"
    consKey <-  "consumer_key"
    client <- OVH(appKey, appSecret, consKey)
    client$GET("https://ca.api.ovh.com/v1/me")
    client$GET("https://ca.api.ovh.com/v1/domain")