diff options
Diffstat (limited to 'src/indieauth.rs')
-rw-r--r-- | src/indieauth.rs | 99 |
1 files changed, 71 insertions, 28 deletions
diff --git a/src/indieauth.rs b/src/indieauth.rs index 27a70a1..f6bac04 100644 --- a/src/indieauth.rs +++ b/src/indieauth.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; #[allow(unused_imports)] -use log::{error,info}; -use url::Url; +use log::{error, info}; +use std::sync::Arc; use tide::prelude::*; #[allow(unused_imports)] -use tide::{Request, Response, Next, Result}; -use std::sync::Arc; +use tide::{Next, Request, Response, Result}; +use url::Url; use crate::database; use crate::ApplicationState; @@ -14,7 +14,7 @@ use crate::ApplicationState; pub struct User { pub me: Url, pub client_id: Url, - scope: String + scope: String, } impl User { @@ -28,23 +28,40 @@ impl User { Self { me: Url::parse(me).unwrap(), client_id: Url::parse(client_id).unwrap(), - scope: scope.to_string() + scope: scope.to_string(), } } } #[cfg(any(not(debug_assertions), test))] -async fn get_token_data(token: String, token_endpoint: &http_types::Url, http_client: &surf::Client) -> (http_types::StatusCode, Option<User>) { - match http_client.get(token_endpoint).header("Authorization", token).header("Accept", "application/json").send().await { +async fn get_token_data( + token: String, + token_endpoint: &http_types::Url, + http_client: &surf::Client, +) -> (http_types::StatusCode, Option<User>) { + match http_client + .get(token_endpoint) + .header("Authorization", token) + .header("Accept", "application/json") + .send() + .await + { Ok(mut resp) => { if resp.status() == 200 { match resp.body_json::<User>().await { Ok(user) => { - info!("Token endpoint request successful. Validated user: {}", user.me); + info!( + "Token endpoint request successful. Validated user: {}", + user.me + ); (resp.status(), Some(user)) - }, + } Err(err) => { - error!("Token endpoint parsing error (HTTP status {}): {}", resp.status(), err); + error!( + "Token endpoint parsing error (HTTP status {}): {}", + resp.status(), + err + ); (http_types::StatusCode::InternalServerError, None) } } @@ -63,7 +80,7 @@ async fn get_token_data(token: String, token_endpoint: &http_types::Url, http_cl pub struct IndieAuthMiddleware { #[allow(dead_code)] // it's not really dead since it's only dead in debug scope cache: Arc<retainer::Cache<String, User>>, - monitor_task: Option<async_std::task::JoinHandle<()>> + monitor_task: Option<async_std::task::JoinHandle<()>>, } impl IndieAuthMiddleware { /// Create a new instance of IndieAuthMiddleware. @@ -74,12 +91,19 @@ impl IndieAuthMiddleware { pub fn new() -> Self { let cache: Arc<retainer::Cache<String, User>> = Arc::new(retainer::Cache::new()); let cache_clone = cache.clone(); - let task = async_std::task::spawn(async move { cache_clone.monitor(4, 0.1, std::time::Duration::from_secs(30)).await }); + let task = async_std::task::spawn(async move { + cache_clone + .monitor(4, 0.1, std::time::Duration::from_secs(30)) + .await + }); #[cfg(all(debug_assertions, not(test)))] error!("ATTENTION: You are running in debug mode. NO REQUESTS TO TOKEN ENDPOINT WILL BE MADE. YOU WILL BE PROCEEDING WITH DEBUG USER CREDENTIALS. DO NOT RUN LIKE THIS IN PRODUCTION."); - Self { cache, monitor_task: Some(task) } + Self { + cache, + monitor_task: Some(task), + } } } impl Drop for IndieAuthMiddleware { @@ -96,7 +120,8 @@ impl Drop for IndieAuthMiddleware { // (it is safe tho cuz None is no nullptr and dereferencing it doesn't cause unsafety) // (could cause a VERY FUNNY race condition to occur though // if you tried to refer to the value in another thread!) - let task = std::mem::take(&mut self.monitor_task).expect("Dropped IndieAuthMiddleware TWICE? Impossible!"); + let task = std::mem::take(&mut self.monitor_task) + .expect("Dropped IndieAuthMiddleware TWICE? Impossible!"); // Then cancel the task, using another task to request cancellation. // Because apparently you can't run async code from Drop... // This should drop the last reference for the [`cache`], @@ -105,27 +130,41 @@ impl Drop for IndieAuthMiddleware { } } #[async_trait] -impl<B> tide::Middleware<ApplicationState<B>> for IndieAuthMiddleware where - B: database::Storage + Send + Sync + Clone +impl<B> tide::Middleware<ApplicationState<B>> for IndieAuthMiddleware +where + B: database::Storage + Send + Sync + Clone, { - #[cfg(all(not(test), debug_assertions))] - async fn handle(&self, mut req: Request<ApplicationState<B>>, next: Next<'_, ApplicationState<B>>) -> Result { - req.set_ext(User::new("http://localhost:8080/", "https://curl.haxx.se/","create update delete undelete media")); + async fn handle( + &self, + mut req: Request<ApplicationState<B>>, + next: Next<'_, ApplicationState<B>>, + ) -> Result { + req.set_ext(User::new( + "http://localhost:8080/", + "https://curl.haxx.se/", + "create update delete undelete media", + )); Ok(next.run(req).await) } #[cfg(any(not(debug_assertions), test))] - async fn handle(&self, mut req: Request<ApplicationState<B>>, next: Next<'_, ApplicationState<B>>) -> Result { + async fn handle( + &self, + mut req: Request<ApplicationState<B>>, + next: Next<'_, ApplicationState<B>>, + ) -> Result { let header = req.header("Authorization"); match header { None => { // TODO: move that to the request handling functions // or make a middleware that refuses to accept unauthenticated requests - Ok(Response::builder(401).body(json!({ - "error": "unauthorized", - "error_description": "Please provide an access token." - })).build()) - }, + Ok(Response::builder(401) + .body(json!({ + "error": "unauthorized", + "error_description": "Please provide an access token." + })) + .build()) + } Some(value) => { let endpoint = &req.state().token_endpoint; let http_client = &req.state().http_client; @@ -177,9 +216,13 @@ mod tests { use super::*; #[test] fn user_scopes_are_checkable() { - let user = User::new("https://fireburn.ru/", "https://quill.p3k.io/", "create update media"); + let user = User::new( + "https://fireburn.ru/", + "https://quill.p3k.io/", + "create update media", + ); assert!(user.check_scope("create")); assert!(!user.check_scope("delete")); } -} \ No newline at end of file +} |