summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorD. Scott Boggs <scott@tams.tech>2022-12-18 16:03:46 -0500
committerD. Scott Boggs <scott@tams.tech>2022-12-18 16:03:46 -0500
commit6afdc06cc733ba672e15efb7ad9c871719639ff5 (patch)
tree14ab79616651224cf73ff2e6997d0dfd459b0619
parent648de8c8e541ca981f3d857e60eb6e97ad76eed3 (diff)
Added authentication and more robust response logs
-rw-r--r--src/macros.rs29
-rw-r--r--src/mastodon.rs35
2 files changed, 37 insertions, 27 deletions
diff --git a/src/macros.rs b/src/macros.rs
index cf0e26a..ddcc555 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -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
diff --git a/src/mastodon.rs b/src/mastodon.rs
index 4b7b55a..1b3ee0a 100644
--- a/src/mastodon.rs
+++ b/src/mastodon.rs
@@ -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>;