I'm building a webserver that authenticates via oauth2. With the example from axum/oauth I got it to work with my nextcloud-instance. To get the UserId and store it in a database, I'd like to make a request to the OCS-Api from my nextcloud instance. The request works and I get the expected response, but I can't get it to serialize. Here's the OCS-Api documentation with an expected example of a response.
{
"ocs": {
"meta": {
"status": "string",
"statuscode": 0,
"message": "string",
"totalitems": "string",
"itemsperpage": "string"
},
"data": {
"userId": "string",
"message": "string",
"icon": "string",
"clearAt": 0,
"status": "online",
"messageId": "string",
"messageIsPredefined": true,
"statusIsUserDefined": true
}
}
}
I tried to serialize the Json from the Response into my OCSUser struct
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct OCSUser {
user_id: String,
}
Here's the function in question:
let token = oauth_client
.exchange_code(AuthorizationCode::new(query.code.clone()))
.request_async(async_http_client)
.await
.context("failed in sending request request to authorization server")?;
// Fetch user data from discord
let client = reqwest::Client::new();
let client2 = client
// https://discord.com/developers/docs/resources/user#get-current-user
.get("https://nextcloud.apo-riesinger.de/ocs/v2.php/apps/user_status/api/v1/user_status")
.bearer_auth(token.access_token().secret())
.header("OCS-APIREQUEST", "true")
.header(ACCEPT, "application/json")
.send()
.await
.context("failed in sending request to target Url")?;
println!("{:?}", &client2);
let user_data = client2
.json::<OCSUser>()
.await
.context("failed to deserialize response as JSON")?;
println!("{:?}", &user_data);
It always reaches the print statement with &client2, but can't reach the last one. To test the waters, I tried to model the structure of the expected response according to the documentation and got an output via the text method from Structure. The output was the following
"{\"ocs\":{\"meta\":{\"status\":\"ok\",\"statuscode\":200,\"message\":\"OK\"},\"data\":{\"userId\":\"chef\",\"message\":null,\"messageId\":null,\"messageIsPredefined\":false,\"icon\":null,\"clearAt\":null,\"status\":\"offline\",\"statusIsUserDefined\":false}}}"
The last idea I had was that the textencoding was different, but I'm not sure. For completeness, here's the content of the printstatement with client2
Response { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("nextcloud.apo-riesinger.de")), port: None, path: "/ocs/v2.php/apps/user_status/api/v1/user_status", query: None, fragment: None }, status: 200, headers: {"server": "openresty", "date": "Wed, 24 Jan 2024 23:51:35 GMT", "content-type": "application/json; charset=utf-8", "content-length": "223", "connection": "keep-alive", "referrer-policy": "no-referrer", "x-content-type-options": "nosniff", "x-frame-options": "SAMEORIGIN", "x-permitted-cross-domain-policies": "none", "x-robots-tag": "noindex, nofollow", "x-xss-protection": "1; mode=block", "x-powered-by": "PHP/8.2.15", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc_sessionPassphrase=FhePXWSLltK4IXpDmcTi%2Fk0pT%2FDEcDRXQjW%2Fu1jcew%2BjvxiUeEnMQl11pRIRNDq3nHncV6xcDLJ26zNR2%2BStn1dcx%2F684OWV6tzK0Dg92Hxg%2BxjCMDbxAShCWB9Mmp5O; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "__Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax", "set-cookie": "__Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "set-cookie": "oc5ny1g9qec3=53d44aaeaa6fd48dccad3e27f7525d44; path=/; secure; HttpOnly; SameSite=Lax", "expires": "Thu, 19 Nov 1981 08:52:00 GMT", "cache-control": "no-cache, no-store, must-revalidate", "pragma": "no-cache", "content-security-policy": "default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'", "x-request-id": "F1j2zkPIca8Z5fS66ktF", "feature-policy": "autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'", "strict-transport-security": "max-age=63072000; preload", "x-served-by": "nextcloud.apo-riesinger.de"} }
As this is my first rust project, I'd really appreciate the help. It is a really difficult but rather rewarding language. Does anyone have an idea? Thank you very much.
Your struct needs to include the same nested structure as the JSON.
#[derive(Debug, Serialize, Deserialize)]
struct OCSUser {
ocs: Ocs,
}
#[derive(Debug, Serialize, Deserialize)]
struct Ocs {
data: OcsData,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct OcsData {
user_id: String,
}