Added authentication and more robust response logs

This commit is contained in:
D. Scott Boggs 2022-12-18 16:03:46 -05:00
parent 648de8c8e5
commit 6afdc06cc7
2 changed files with 37 additions and 27 deletions

View File

@ -22,15 +22,10 @@ macro_rules! methods {
let url = url.as_ref();
debug!(url = url, method = stringify!($method), call_id = as_debug!(call_id); "making API request");
let response = self.client
.$method(url)
.send()
.await?;
let response = self.authenticated(self.client.$method(url)).send().await?;
match response.error_for_status() {
Ok(response) => {
let response = response
.json()
.await?;
let response = read_response(response).await?;
debug!(response = as_serde!(response), url = url, method = stringify!($method), call_id = as_debug!(call_id); "received API response");
Ok(response)
}
@ -66,7 +61,7 @@ macro_rules! paged_routes {
let url = self.route(concat!("/api/v1/", $url));
let call_id = uuid::Uuid::new_v4();
debug!(url = url, method = stringify!($method), call_id = as_debug!(call_id); "making API request");
let response = self.client.$method(&url).send().await?;
let response = self.authenticated(self.client.$method(&url)).send().await?;
match response.error_for_status() {
Ok(response) => {
@ -122,7 +117,7 @@ macro_rules! paged_routes {
debug!(url = url, method = "get", call_id = as_debug!(call_id); "making API request");
let response = self.client.get(&url).send().await?;
let response = self.authenticated(self.client.get(&url)).send().await?;
match response.error_for_status() {
Ok(response) => {
@ -208,7 +203,8 @@ macro_rules! route {
let form_data = Form::new()
$(
.part(stringify!($param), {
match std::fs::File::open($param.as_ref()) {
let path = $param.as_ref();
match std::fs::File::open(path) {
Ok(mut file) => {
let mut data = if let Ok(metadata) = file.metadata() {
Vec::with_capacity(metadata.len().try_into()?)
@ -219,7 +215,7 @@ macro_rules! route {
Part::bytes(data)
}
Err(err) => {
error!(path = $param.as_ref(), error = as_debug!(err); "error reading file contents for multipart form");
error!(path = as_debug!(path), error = as_debug!(err); "error reading file contents for multipart form");
return Err(err.into());
}
}
@ -234,8 +230,7 @@ macro_rules! route {
"making API request"
);
let response = self.client
.post(url)
let response = self.authenticated(self.client.post(url))
.multipart(form_data)
.send()
.await?;
@ -319,15 +314,15 @@ macro_rules! route {
stringify!($param): $param,
)*
});
let url = &self.route(concat!("/api/v1/", $url));
debug!(
url = $url, method = stringify!($method),
url = url.as_str(), method = stringify!($method),
call_id = as_debug!(call_id),
form_data = as_serde!(&form_data);
"making API request"
);
let response = self.client
.$method(&self.route(concat!("/api/v1/", $url)))
let response = self.authenticated(self.client.$method(url))
.json(&form_data)
.send()
.await?;
@ -425,7 +420,7 @@ macro_rules! paged_routes_with_id {
let url = self.route(&format!(concat!("/api/v1/", $url), id));
debug!(url = url, method = stringify!($method), call_id = as_debug!(call_id); "making API request");
let response = self.client.$method(&url).send().await?;
let response = self.authenticated(self.client.$method(&url)).send().await?;
match response.error_for_status() {
Ok(response) => {
Page::new(self.clone(), response, call_id).await

View File

@ -1,4 +1,4 @@
use std::{borrow::Cow, ops::Deref, sync::Arc};
use std::{borrow::Cow, ops::Deref, path::Path, sync::Arc};
use crate::{
entities::{
@ -11,6 +11,7 @@ use crate::{
errors::{Error, Result},
event_stream::event_stream,
helpers::read_response::read_response,
log_serde,
AddFilterRequest,
AddPushRequest,
Data,
@ -22,7 +23,7 @@ use crate::{
};
use futures::TryStream;
use log::{as_debug, as_serde, debug, error, info, trace};
use reqwest::Client;
use reqwest::{Client, RequestBuilder};
use url::Url;
use uuid::Uuid;
@ -91,7 +92,7 @@ impl Mastodon {
(get (q: &'a str, resolve: bool,)) search: "search" => SearchResult,
(get (local: bool,)) get_public_timeline: "timelines/public" => Vec<Status>,
(post (uri: Cow<'static, str>,)) follows: "follows" => Account,
(post multipart (file: Cow<'static, str>,)) media: "media" => Attachment,
(post multipart (file: impl AsRef<Path>,)) media: "media" => Attachment,
(post) clear_notifications: "notifications/clear" => Empty,
(post (id: &str,)) dismiss_notification: "notifications/dismiss" => Empty,
(get) get_push_subscription: "push/subscription" => Subscription,
@ -187,14 +188,18 @@ impl Mastodon {
/// Post a new status to the account.
pub async fn new_status(&self, status: NewStatus) -> Result<Status> {
Ok(self
.client
.post(&self.route("/api/v1/statuses"))
let url = self.route("/api/v1/statuses");
let response = self
.authenticated(self.client.post(&url))
.json(&status)
.send()
.await?
.json()
.await?)
.await?;
debug!(
status = log_serde!(response Status), url = url,
headers = log_serde!(response Headers);
"received API response"
);
Ok(read_response(response).await?)
}
/// Get timeline filtered by a hashtag(eg. `#coffee`) either locally or
@ -252,6 +257,8 @@ impl Mastodon {
Ok(response) => Page::new(self.clone(), response, call_id).await,
Err(err) => {
error!(err = as_debug!(err), url = url, method = stringify!($method), call_id = as_debug!(call_id); "error making API request");
// Cannot retrieve request body as it's been moved into the
// other match arm.
Err(err.into())
},
}
@ -411,7 +418,9 @@ impl Mastodon {
url.set_scheme(new_scheme)
.map_err(|_| Error::Other("Bad URL scheme!".to_string()))?;
event_stream(url.to_string())
/// Set the bearer authentication token
fn authenticated(&self, request: RequestBuilder) -> RequestBuilder {
request.bearer_auth(&self.data.token)
}
}
@ -460,6 +469,12 @@ impl MastodonUnauthenticated {
let route = route.join("card")?;
self.get(route.as_str()).await
}
/// Since this client needs no authentication, this returns the
/// `RequestBuilder` unmodified.
fn authenticated(&self, request: RequestBuilder) -> RequestBuilder {
request
}
}
impl Deref for Mastodon {
type Target = Arc<MastodonClient>;