move towards using #[rocket::async_trait]
this also upgrades some dependencies some of that fixes stuff, others breaks stuff.
This commit is contained in:
		
							parent
							
								
									097d0ea9ce
								
							
						
					
					
						commit
						3c830ab0ce
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -18,3 +18,4 @@ tags.* | ||||
| search_index | ||||
| .buildconfig | ||||
| __pycache__ | ||||
| .vscode/ | ||||
|  | ||||
							
								
								
									
										79
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										79
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -6,7 +6,7 @@ version = "0.1.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5bfd311e7b4102971757a2a6f143a93b1a8e6b5afc2c46936af827fd9eab403f" | ||||
| dependencies = [ | ||||
|  "activitystreams-derive", | ||||
|  "activitystreams-derive 0.1.1", | ||||
|  "activitystreams-traits", | ||||
|  "activitystreams-types", | ||||
|  "serde", | ||||
| @ -25,6 +25,17 @@ dependencies = [ | ||||
|  "syn 0.13.11", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "activitystreams-derive" | ||||
| version = "0.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "65608fdeae5eb05485d5b71a3d2242d76b2b7413608c196d47eb4dff3eed7b85" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "activitystreams-traits" | ||||
| version = "0.1.0" | ||||
| @ -42,7 +53,7 @@ version = "0.2.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ff74c5765278614a009f97b9ec12f9a7c732bbcc5e0337fcfcab619b784860ec" | ||||
| dependencies = [ | ||||
|  "activitystreams-derive", | ||||
|  "activitystreams-derive 0.1.1", | ||||
|  "activitystreams-traits", | ||||
|  "chrono", | ||||
|  "mime 0.3.16", | ||||
| @ -142,7 +153,7 @@ checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -746,7 +757,7 @@ dependencies = [ | ||||
|  "bitflags 1.2.1", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -784,7 +795,7 @@ checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -978,7 +989,7 @@ checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
|  "synstructure", | ||||
| ] | ||||
| 
 | ||||
| @ -993,9 +1004,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "filetime" | ||||
| version = "0.2.9" | ||||
| version = "0.2.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e" | ||||
| checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "libc", | ||||
| @ -1179,7 +1190,7 @@ dependencies = [ | ||||
|  "proc-macro-hack 0.5.15", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -1829,7 +1840,7 @@ dependencies = [ | ||||
|  "migrations_internals", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -2171,9 +2182,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "openssl-sys" | ||||
| version = "0.9.55" | ||||
| version = "0.9.56" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7717097d810a0f2e2323f9e5d11e71608355e24828410b55b9d4f18aa5f9a5d8" | ||||
| checksum = "f02309a7f127000ed50594f0b50ecc69e7c654e16d41b4e8156d1b3df8e0b52e" | ||||
| dependencies = [ | ||||
|  "autocfg 1.0.0", | ||||
|  "cc", | ||||
| @ -2354,29 +2365,29 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project" | ||||
| version = "0.4.10" | ||||
| version = "0.4.13" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "36e3dcd42688c05a66f841d22c5d8390d9a5d4c9aaf57b9285eae4900a080063" | ||||
| checksum = "82c3bfbfb5bb42f99498c7234bbd768c220eb0cea6818259d0d18a1aa3d2595d" | ||||
| dependencies = [ | ||||
|  "pin-project-internal", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project-internal" | ||||
| version = "0.4.10" | ||||
| version = "0.4.13" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f4d7346ac577ff1296e06a418e7618e22655bae834d4970cb6e39d6da8119969" | ||||
| checksum = "ccbf6449dcfb18562c015526b085b8df1aa3cdab180af8ec2ebd300a3bd28f63" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project-lite" | ||||
| version = "0.1.4" | ||||
| version = "0.1.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" | ||||
| checksum = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pin-utils" | ||||
| @ -2435,7 +2446,6 @@ dependencies = [ | ||||
|  "rpassword", | ||||
|  "rsass", | ||||
|  "ructe", | ||||
|  "runtime-fmt", | ||||
|  "scheduled-thread-pool", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
| @ -2472,7 +2482,7 @@ name = "plume-common" | ||||
| version = "0.4.0" | ||||
| dependencies = [ | ||||
|  "activitypub", | ||||
|  "activitystreams-derive", | ||||
|  "activitystreams-derive 0.2.0", | ||||
|  "activitystreams-traits", | ||||
|  "array_tool", | ||||
|  "base64 0.10.1", | ||||
| @ -3066,7 +3076,7 @@ dependencies = [ | ||||
| [[package]] | ||||
| name = "rocket_i18n" | ||||
| version = "0.5.0" | ||||
| source = "git+https://github.com/Plume-org/rocket_i18n?branch=go-async#a6c8cfb3c516d857493d938ec0c89e7bd0c29cad" | ||||
| source = "git+https://github.com/Plume-org/rocket_i18n?branch=go-async#6ff7e2a7dd6dfc730478433f881300f36930ff52" | ||||
| dependencies = [ | ||||
|  "gettext 0.4.0", | ||||
|  "rocket", | ||||
| @ -3108,15 +3118,6 @@ dependencies = [ | ||||
|  "nom 5.1.1", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "runtime-fmt" | ||||
| version = "0.4.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "703425f78450961e590726ac24d823e6dc2340dc18282cf0cb6a417b26ca2ce8" | ||||
| dependencies = [ | ||||
|  "unicode-xid 0.2.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "rust-stemmers" | ||||
| version = "1.2.0" | ||||
| @ -3266,7 +3267,7 @@ checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3326,7 +3327,7 @@ dependencies = [ | ||||
|  "itertools", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3339,7 +3340,7 @@ dependencies = [ | ||||
|  "itertools", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -3561,9 +3562,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "1.0.18" | ||||
| version = "1.0.19" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" | ||||
| checksum = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
| @ -3587,7 +3588,7 @@ checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
|  "unicode-xid 0.2.0", | ||||
| ] | ||||
| 
 | ||||
| @ -4069,7 +4070,7 @@ dependencies = [ | ||||
|  "log 0.4.8", | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
| 
 | ||||
| @ -4103,7 +4104,7 @@ checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" | ||||
| dependencies = [ | ||||
|  "proc-macro2 1.0.12", | ||||
|  "quote 1.0.4", | ||||
|  "syn 1.0.18", | ||||
|  "syn 1.0.19", | ||||
|  "wasm-bindgen-backend", | ||||
|  "wasm-bindgen-shared", | ||||
| ] | ||||
|  | ||||
| @ -23,7 +23,6 @@ num_cpus = "1.10" | ||||
| rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "async" } | ||||
| rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", rev = "async" , features = ["json"] } | ||||
| rpassword = "4.0" | ||||
| runtime-fmt = "0.4.0" | ||||
| scheduled-thread-pool = "0.2.2" | ||||
| serde = "1.0" | ||||
| serde_json = "1.0" | ||||
|  | ||||
| @ -6,7 +6,7 @@ edition = "2018" | ||||
| 
 | ||||
| [dependencies] | ||||
| activitypub = "0.1.1" | ||||
| activitystreams-derive = "0.1.1" | ||||
| activitystreams-derive = "0.2" | ||||
| activitystreams-traits = "0.1.0" | ||||
| array_tool = "1.0" | ||||
| base64 = "0.10" | ||||
|  | ||||
| @ -3,8 +3,8 @@ use array_tool::vec::Uniq; | ||||
| use reqwest::ClientBuilder; | ||||
| use rocket::{ | ||||
|     http::Status, | ||||
|     request::{FromRequestAsync, FromRequestFuture, Request}, | ||||
|     response::{Responder, Response, ResultFuture}, | ||||
|     request::{FromRequest, Request}, | ||||
|     response::{Responder, Response, Result}, | ||||
|     Outcome, | ||||
| }; | ||||
| use serde_json; | ||||
| @ -61,42 +61,36 @@ impl<T> ActivityStream<T> { | ||||
|         ActivityStream(t) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'r, O: Object + Send + 'r> Responder<'r> for ActivityStream<O> { | ||||
|     fn respond_to(self, request: &'r Request<'_>) -> ResultFuture<'r> { | ||||
|         Box::pin(async move { | ||||
|             let mut json = | ||||
|                 serde_json::to_value(&self.0).map_err(|_| Status::InternalServerError)?; | ||||
|             json["@context"] = context(); | ||||
|             let result = serde_json::to_string(&json).map_err(rocket::response::Debug); | ||||
|             match result.respond_to(request).await { | ||||
|                 Ok(r) => { | ||||
|                     Response::build_from(r) | ||||
|                         .raw_header("Content-Type", "application/activity+json") | ||||
|                         .ok() | ||||
|                         .await | ||||
|                 } | ||||
|                 Err(e) => Err(e), | ||||
|             } | ||||
|         }) | ||||
|     async fn respond_to(self, request: &'r Request<'_>) -> Result<'r> { | ||||
|         let mut json = serde_json::to_value(&self.0).map_err(|_| Status::InternalServerError)?; | ||||
|         json["@context"] = context(); | ||||
|         let result = serde_json::to_string(&json).map_err(rocket::response::Debug); | ||||
|         match result.respond_to(request).await { | ||||
|             Ok(r) => Response::build_from(r) | ||||
|                 .raw_header("Content-Type", "application/activity+json") | ||||
|                 .ok(), | ||||
|             Err(e) => Err(e), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct ApRequest; | ||||
| impl<'a, 'r> FromRequestAsync<'a, 'r> for ApRequest { | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for ApRequest { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> FromRequestFuture<'a, Self, Self::Error> { | ||||
|         Box::pin(async move { | ||||
|             request | ||||
|                 .headers() | ||||
|                 .get_one("Accept") | ||||
|                 .map(|header| { | ||||
|                     header | ||||
|                         .split(',') | ||||
|                         .map(|ct| { | ||||
|                             match ct.trim() { | ||||
|     async fn from_request(request: &'a Request<'r>) -> Outcome<Self, (Status, Self::Error), ()> { | ||||
|         request | ||||
|             .headers() | ||||
|             .get_one("Accept") | ||||
|             .map(|header| { | ||||
|                 header | ||||
|                     .split(',') | ||||
|                     .map(|ct| { | ||||
|                         match ct.trim() { | ||||
|                             // bool for Forward: true if found a valid Content-Type for Plume first (HTML),
 | ||||
|                             // false otherwise
 | ||||
|                             "application/ld+json; profile=\"https://w3.org/ns/activitystreams\"" | ||||
| @ -106,18 +100,17 @@ impl<'a, 'r> FromRequestAsync<'a, 'r> for ApRequest { | ||||
|                             "text/html" => Outcome::Forward(true), | ||||
|                             _ => Outcome::Forward(false), | ||||
|                         } | ||||
|                         }) | ||||
|                         .fold(Outcome::Forward(false), |out, ct| { | ||||
|                             if out.clone().forwarded().unwrap_or_else(|| out.is_success()) { | ||||
|                                 out | ||||
|                             } else { | ||||
|                                 ct | ||||
|                             } | ||||
|                         }) | ||||
|                         .map_forward(|_| ()) | ||||
|                 }) | ||||
|                 .unwrap_or(Outcome::Forward(())) | ||||
|         }) | ||||
|                     }) | ||||
|                     .fold(Outcome::Forward(false), |out, ct| { | ||||
|                         if out.clone().forwarded().unwrap_or_else(|| out.is_success()) { | ||||
|                             out | ||||
|                         } else { | ||||
|                             ct | ||||
|                         } | ||||
|                     }) | ||||
|                     .map_forward(|_| ()) | ||||
|             }) | ||||
|             .unwrap_or(Outcome::Forward(())) | ||||
|     } | ||||
| } | ||||
| pub fn broadcast<S, A, T, C>(sender: &S, act: A, to: Vec<T>) | ||||
| @ -217,8 +210,7 @@ pub struct PublicKey { | ||||
|     pub public_key_pem: Option<serde_json::Value>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, Default, UnitString)] | ||||
| #[activitystreams(Hashtag)] | ||||
| #[derive(Clone, Debug, Default, Deserialize, Serialize)] | ||||
| pub struct HashtagType; | ||||
| 
 | ||||
| #[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] | ||||
|  | ||||
| @ -1,42 +1,40 @@ | ||||
| use crate::users::User; | ||||
| use rocket::{ | ||||
|     http::Status, | ||||
|     request::{self, FromRequestAsync, Request}, | ||||
|     request::{self, FromRequest, Request}, | ||||
|     Outcome, | ||||
| }; | ||||
| 
 | ||||
| /// Wrapper around User to use as a request guard on pages reserved to admins.
 | ||||
| pub struct Admin(pub User); | ||||
| 
 | ||||
| impl<'a, 'r> FromRequestAsync<'a, 'r> for Admin { | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for Admin { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|         Box::pin(async move { | ||||
|             let user = try_outcome!(User::from_request(request).await); | ||||
|             if user.is_admin() { | ||||
|                 Outcome::Success(Admin(user)) | ||||
|             } else { | ||||
|                 Outcome::Failure((Status::Unauthorized, ())) | ||||
|             } | ||||
|         }) | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         let user = try_outcome!(User::from_request(request).await); | ||||
|         if user.is_admin() { | ||||
|             Outcome::Success(Admin(user)) | ||||
|         } else { | ||||
|             Outcome::Failure((Status::Unauthorized, ())) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Same as `Admin` but for moderators.
 | ||||
| pub struct Moderator(pub User); | ||||
| 
 | ||||
| impl<'a, 'r> FromRequestAsync<'a, 'r> for Moderator { | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for Moderator { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|         Box::pin(async move { | ||||
|             let user = try_outcome!(User::from_request(request).await); | ||||
|             if user.is_moderator() { | ||||
|                 Outcome::Success(Moderator(user)) | ||||
|             } else { | ||||
|                 Outcome::Failure((Status::Unauthorized, ())) | ||||
|             } | ||||
|         }) | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         let user = try_outcome!(User::from_request(request).await); | ||||
|         if user.is_moderator() { | ||||
|             Outcome::Success(Moderator(user)) | ||||
|         } else { | ||||
|             Outcome::Failure((Status::Unauthorized, ())) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ use chrono::NaiveDateTime; | ||||
| use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl}; | ||||
| use rocket::{ | ||||
|     http::Status, | ||||
|     request::{self, FromRequestAsync, Request}, | ||||
|     request::{self, FromRequest, Request}, | ||||
|     Outcome, | ||||
| }; | ||||
| 
 | ||||
| @ -76,39 +76,38 @@ pub enum TokenError { | ||||
|     DbError, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'r> FromRequestAsync<'a, 'r> for ApiToken { | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for ApiToken { | ||||
|     type Error = TokenError; | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|         Box::pin(async move { | ||||
|             let headers: Vec<_> = request.headers().get("Authorization").collect(); | ||||
|             if headers.len() != 1 { | ||||
|                 return Outcome::Failure((Status::BadRequest, TokenError::NoHeader)); | ||||
|             } | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         let headers: Vec<_> = request.headers().get("Authorization").collect(); | ||||
|         if headers.len() != 1 { | ||||
|             return Outcome::Failure((Status::BadRequest, TokenError::NoHeader)); | ||||
|         } | ||||
| 
 | ||||
|             let mut parsed_header = headers[0].split(' '); | ||||
|             if let Some(auth_type) = parsed_header.next() { | ||||
|                 if let Some(val) = parsed_header.next() { | ||||
|                     if auth_type == "Bearer" { | ||||
|                         if let Outcome::Success(conn) = DbConn::from_request(request).await { | ||||
|                             if let Ok(token) = ApiToken::find_by_value(&*conn, val) { | ||||
|                                 return Outcome::Success(token); | ||||
|                             } | ||||
|                         } else { | ||||
|                             return Outcome::Failure(( | ||||
|                                 Status::InternalServerError, | ||||
|                                 TokenError::DbError, | ||||
|                             )); | ||||
|         let mut parsed_header = headers[0].split(' '); | ||||
|         if let Some(auth_type) = parsed_header.next() { | ||||
|             if let Some(val) = parsed_header.next() { | ||||
|                 if auth_type == "Bearer" { | ||||
|                     if let Outcome::Success(conn) = DbConn::from_request(request).await { | ||||
|                         if let Ok(token) = ApiToken::find_by_value(&*conn, val) { | ||||
|                             return Outcome::Success(token); | ||||
|                         } | ||||
|                     } else { | ||||
|                         return Outcome::Failure(( | ||||
|                             Status::InternalServerError, | ||||
|                             TokenError::DbError, | ||||
|                         )); | ||||
|                     } | ||||
|                 } else { | ||||
|                     return Outcome::Failure((Status::BadRequest, TokenError::NoValue)); | ||||
|                 } | ||||
|             } else { | ||||
|                 return Outcome::Failure((Status::BadRequest, TokenError::NoType)); | ||||
|                 return Outcome::Failure((Status::BadRequest, TokenError::NoValue)); | ||||
|             } | ||||
|         } else { | ||||
|             return Outcome::Failure((Status::BadRequest, TokenError::NoType)); | ||||
|         } | ||||
| 
 | ||||
|             Outcome::Forward(()) | ||||
|         }) | ||||
|         Outcome::Forward(()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ use diesel::r2d2::{ | ||||
| use diesel::{dsl::sql_query, ConnectionError, RunQueryDsl}; | ||||
| use rocket::{ | ||||
|     http::Status, | ||||
|     request::{self, FromRequestAsync}, | ||||
|     request::{self, FromRequest}, | ||||
|     Outcome, Request, | ||||
| }; | ||||
| use std::ops::Deref; | ||||
| @ -21,16 +21,15 @@ pub struct DbConn(pub PooledConnection<ConnectionManager<Connection>>); | ||||
| /// Attempts to retrieve a single connection from the managed database pool. If
 | ||||
| /// no pool is currently managed, fails with an `InternalServerError` status. If
 | ||||
| /// no connections are available, fails with a `ServiceUnavailable` status.
 | ||||
| impl<'a, 'r> FromRequestAsync<'a, 'r> for DbConn { | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for DbConn { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|         Box::pin(async move { | ||||
|             match DbConn::from_request(request).await { | ||||
|                 Outcome::Success(a) => return Outcome::Success(a), | ||||
|                 _ => return Outcome::Failure((Status::ServiceUnavailable, ())), | ||||
|             }; | ||||
|         }) | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         match DbConn::from_request(request).await { | ||||
|             Outcome::Success(a) => return Outcome::Success(a), | ||||
|             _ => return Outcome::Failure((Status::ServiceUnavailable, ())), | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -6,10 +6,11 @@ use rocket::{ | ||||
| 
 | ||||
| pub struct Headers<'r>(pub HeaderMap<'r>); | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for Headers<'r> { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> { | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, ()> { | ||||
|         let mut headers = HeaderMap::new(); | ||||
|         for header in request.headers().clone().into_iter() { | ||||
|             headers.add(header); | ||||
|  | ||||
| @ -4,7 +4,7 @@ pub use self::module::PlumeRocket; | ||||
| mod module { | ||||
|     use crate::{db_conn::DbConn, search, users}; | ||||
|     use rocket::{ | ||||
|         request::{self, FlashMessage, FromRequestAsync, Request}, | ||||
|         request::{self, FlashMessage, FromRequest, Request}, | ||||
|         Outcome, State, | ||||
|     }; | ||||
|     use scheduled_thread_pool::ScheduledThreadPool; | ||||
| @ -20,29 +20,38 @@ mod module { | ||||
|         pub flash_msg: Option<(String, String)>, | ||||
|     } | ||||
| 
 | ||||
|     impl<'a, 'r> FromRequestAsync<'a, 'r> for PlumeRocket { | ||||
|     #[rocket::async_trait] | ||||
|     impl<'a, 'r> FromRequest<'a, 'r> for PlumeRocket { | ||||
|         type Error = (); | ||||
| 
 | ||||
|         fn from_request( | ||||
|             request: &'a Request<'r>, | ||||
|         ) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|             Box::pin(async move { | ||||
|                 let conn = try_outcome!(DbConn::from_request(request).await); | ||||
|                 let intl = try_outcome!(rocket_i18n::I18n::from_request(request).await); | ||||
|                 let user = try_outcome!(users::User::from_request(request).await); | ||||
|                 let worker = | ||||
|                     try_outcome!(request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()); | ||||
|                 let searcher = | ||||
|                     try_outcome!(request.guard::<'_, State<'_, Arc<search::Searcher>>>()); | ||||
|                 let flash_msg = request.guard::<FlashMessage<'_, '_>>().succeeded(); | ||||
|                 Outcome::Success(PlumeRocket { | ||||
|                     conn, | ||||
|                     intl, | ||||
|                     user: Some(user), | ||||
|                     flash_msg: flash_msg.map(|f| (f.name().into(), f.msg().into())), | ||||
|                     worker: worker.clone(), | ||||
|                     searcher: searcher.clone(), | ||||
|                 }) | ||||
|         async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|             let conn = DbConn::from_request(request).await.succeeded().unwrap(); | ||||
|             let intl = rocket_i18n::I18n::from_request(request) | ||||
|                 .await | ||||
|                 .succeeded() | ||||
|                 .unwrap(); | ||||
|             let user = users::User::from_request(request) | ||||
|                 .await | ||||
|                 .succeeded() | ||||
|                 .unwrap(); | ||||
|             let worker = request | ||||
|                 .guard::<State<'_, Arc<ScheduledThreadPool>>>() | ||||
|                 .await | ||||
|                 .succeeded() | ||||
|                 .unwrap(); | ||||
|             let searcher = request | ||||
|                 .guard::<State<'_, Arc<search::Searcher>>>() | ||||
|                 .await | ||||
|                 .succeeded() | ||||
|                 .unwrap(); | ||||
|             let flash_msg = request.guard::<FlashMessage<'_, '_>>().await.succeeded(); | ||||
|             Outcome::Success(PlumeRocket { | ||||
|                 conn, | ||||
|                 intl, | ||||
|                 user: Some(user), | ||||
|                 flash_msg: flash_msg.map(|f| (f.name().into(), f.msg().into())), | ||||
|                 worker: worker.clone(), | ||||
|                 searcher: searcher.clone(), | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| @ -52,7 +61,7 @@ mod module { | ||||
| mod module { | ||||
|     use crate::{db_conn::DbConn, search, users}; | ||||
|     use rocket::{ | ||||
|         request::{self, FromRequestAsync, Request}, | ||||
|         request::{self, FromRequest, Request}, | ||||
|         Outcome, State, | ||||
|     }; | ||||
|     use scheduled_thread_pool::ScheduledThreadPool; | ||||
| @ -66,25 +75,20 @@ mod module { | ||||
|         pub worker: Arc<ScheduledThreadPool>, | ||||
|     } | ||||
| 
 | ||||
|     impl<'a, 'r> FromRequestAsync<'a, 'r> for PlumeRocket { | ||||
|     #[rocket::async_trait] | ||||
|     impl<'a, 'r> FromRequest<'a, 'r> for PlumeRocket { | ||||
|         type Error = (); | ||||
| 
 | ||||
|         fn from_request( | ||||
|             request: &'a Request<'r>, | ||||
|         ) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|             Box::pin(async move { | ||||
|                 let conn = try_outcome!(DbConn::from_request(request).await); | ||||
|                 let user = try_outcome!(users::User::from_request(request).await); | ||||
|                 let worker = | ||||
|                     try_outcome!(request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()); | ||||
|                 let searcher = | ||||
|                     try_outcome!(request.guard::<'_, State<'_, Arc<search::Searcher>>>()); | ||||
|                 Outcome::Success(PlumeRocket { | ||||
|                     conn, | ||||
|                     user: Some(user), | ||||
|                     worker: worker.clone(), | ||||
|                     searcher: searcher.clone(), | ||||
|                 }) | ||||
|         async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|             let conn = try_outcome!(DbConn::from_request(request).await); | ||||
|             let user = try_outcome!(users::User::from_request(request).await); | ||||
|             let worker = try_outcome!(request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()); | ||||
|             let searcher = try_outcome!(request.guard::<'_, State<'_, Arc<search::Searcher>>>()); | ||||
|             Outcome::Success(PlumeRocket { | ||||
|                 conn, | ||||
|                 user: Some(user), | ||||
|                 worker: worker.clone(), | ||||
|                 searcher: searcher.clone(), | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -35,7 +35,7 @@ use reqwest::{ | ||||
| }; | ||||
| use rocket::{ | ||||
|     outcome::IntoOutcome, | ||||
|     request::{self, FromRequestAsync, Request}, | ||||
|     request::{self, FromRequest, Request}, | ||||
| }; | ||||
| use serde_json; | ||||
| use std::{ | ||||
| @ -796,19 +796,18 @@ impl User { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'r> FromRequestAsync<'a, 'r> for User { | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for User { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::FromRequestFuture<'a, Self, Self::Error> { | ||||
|         Box::pin(async move { | ||||
|             let conn = try_outcome!(DbConn::from_request(request).await); | ||||
|             request | ||||
|                 .cookies() | ||||
|                 .get_private(AUTH_COOKIE) | ||||
|                 .and_then(|cookie| cookie.value().parse().ok()) | ||||
|                 .and_then(|id| User::get(&*conn, id).ok()) | ||||
|                 .or_forward(()) | ||||
|         }) | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         let conn = try_outcome!(DbConn::from_request(request).await); | ||||
|         request | ||||
|             .cookies() | ||||
|             .get_private(AUTH_COOKIE) | ||||
|             .and_then(|cookie| cookie.value().parse().ok()) | ||||
|             .and_then(|id| User::get(&*conn, id).ok()) | ||||
|             .or_forward(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| nightly-2020-01-15 | ||||
| nightly-2020-05-05 | ||||
|  | ||||
| @ -35,6 +35,7 @@ impl Scope for plume_models::posts::Post { | ||||
| 
 | ||||
| pub struct Authorization<A, S>(pub ApiToken, PhantomData<(A, S)>); | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r, A, S> FromRequest<'a, 'r> for Authorization<A, S> | ||||
| where | ||||
|     A: Action, | ||||
| @ -42,9 +43,10 @@ where | ||||
| { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::Outcome<Authorization<A, S>, ()> { | ||||
|     async fn from_request(request: &'a Request<'r>) -> request::Outcome<Authorization<A, S>, ()> { | ||||
|         request | ||||
|             .guard::<ApiToken>() | ||||
|             .await | ||||
|             .map_failure(|_| (Status::Unauthorized, ())) | ||||
|             .and_then(|token| { | ||||
|                 if token.can(A::to_str(), S::to_str()) { | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| use rocket::{ | ||||
|     request::{Form, Request}, | ||||
|     response::{self, Responder}, | ||||
|     Outcome, | ||||
| }; | ||||
| use rocket_contrib::json::Json; | ||||
| use serde_json; | ||||
| @ -26,21 +27,31 @@ impl From<std::option::NoneError> for ApiError { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'r> Responder<'r> for ApiError { | ||||
|     fn respond_to(self, req: &'r Request) -> response::ResultFuture<'r> { | ||||
|     async fn respond_to(self, req: &'r Request<'_>) -> response::Result<'r> { | ||||
|         match self.0 { | ||||
|             Error::NotFound => Json(json!({ | ||||
|                 "error": "Not found" | ||||
|             })) | ||||
|             .respond_to(req), | ||||
|             Error::Unauthorized => Json(json!({ | ||||
|                 "error": "You are not authorized to access this resource" | ||||
|             })) | ||||
|             .respond_to(req), | ||||
|             _ => Json(json!({ | ||||
|                 "error": "Server error" | ||||
|             })) | ||||
|             .respond_to(req), | ||||
|             Error::NotFound => { | ||||
|                 Json(json!({ | ||||
|                     "error": "Not found" | ||||
|                 })) | ||||
|                 .respond_to(req) | ||||
|                 .await | ||||
|             } | ||||
|             Error::Unauthorized => { | ||||
|                 Json(json!({ | ||||
|                     "error": "You are not authorized to access this resource" | ||||
|                 })) | ||||
|                 .respond_to(req) | ||||
|                 .await | ||||
|             } | ||||
|             _ => { | ||||
|                 Json(json!({ | ||||
|                     "error": "Server error" | ||||
|                 })) | ||||
|                 .respond_to(req) | ||||
|                 .await | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -62,7 +73,7 @@ pub fn oauth( | ||||
|     let conn = &*rockets.conn; | ||||
|     let app = App::find_by_client_id(conn, &query.client_id)?; | ||||
|     if app.client_secret == query.client_secret { | ||||
|         if let Ok(user) = User::find_by_fqn(&rockets, &query.username) { | ||||
|         if let Outcome::Success(user) = User::find_by_fqn(&rockets, &query.username) { | ||||
|             if user.auth(&query.password) { | ||||
|                 let token = ApiToken::insert( | ||||
|                     conn, | ||||
|  | ||||
| @ -6,8 +6,6 @@ extern crate gettext_macros; | ||||
| #[macro_use] | ||||
| extern crate rocket; | ||||
| #[macro_use] | ||||
| extern crate runtime_fmt; | ||||
| #[macro_use] | ||||
| extern crate serde_json; | ||||
| #[macro_use] | ||||
| extern crate validator_derive; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_models::{Error, PlumeRocket}; | ||||
| use rocket::{ | ||||
|     request::FromRequestAsync, | ||||
|     request::FromRequest, | ||||
|     response::{self, Responder}, | ||||
|     Request, | ||||
| }; | ||||
| @ -15,29 +15,28 @@ impl From<Error> for ErrorPage { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'r> Responder<'r> for ErrorPage { | ||||
|     fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> { | ||||
|         Box::pin(async move { | ||||
|             let rockets = PlumeRocket::from_request(req).await.unwrap(); | ||||
|     async fn respond_to(self, req: &'r Request<'_>) -> response::Result<'r> { | ||||
|         let rockets = PlumeRocket::from_request(req).await.unwrap(); | ||||
| 
 | ||||
|             match self.0 { | ||||
|                 Error::NotFound => { | ||||
|                     render!(errors::not_found(&rockets.to_context())) | ||||
|                         .respond_to(req) | ||||
|                         .await | ||||
|                 } | ||||
|                 Error::Unauthorized => { | ||||
|                     render!(errors::not_found(&rockets.to_context())) | ||||
|                         .respond_to(req) | ||||
|                         .await | ||||
|                 } | ||||
|                 _ => { | ||||
|                     render!(errors::not_found(&rockets.to_context())) | ||||
|                         .respond_to(req) | ||||
|                         .await | ||||
|                 } | ||||
|         match self.0 { | ||||
|             Error::NotFound => { | ||||
|                 render!(errors::not_found(&rockets.to_context())) | ||||
|                     .respond_to(req) | ||||
|                     .await | ||||
|             } | ||||
|         }) | ||||
|             Error::Unauthorized => { | ||||
|                 render!(errors::not_found(&rockets.to_context())) | ||||
|                     .respond_to(req) | ||||
|                     .await | ||||
|             } | ||||
|             _ => { | ||||
|                 render!(errors::not_found(&rockets.to_context())) | ||||
|                     .respond_to(req) | ||||
|                     .await | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -94,10 +94,11 @@ impl Page { | ||||
| #[derive(Shrinkwrap)] | ||||
| pub struct ContentLen(pub u64); | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for ContentLen { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(r: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|     async fn from_request(r: &'a Request<'r>) -> request::Outcome<Self, Self::Error> { | ||||
|         match r.limits().get("forms") { | ||||
|             Some(l) => Outcome::Success(ContentLen(l)), | ||||
|             None => Outcome::Failure((Status::InternalServerError, ())), | ||||
| @ -213,32 +214,29 @@ pub struct CachedFile { | ||||
| #[derive(Debug)] | ||||
| pub struct ThemeFile(NamedFile); | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'r> Responder<'r> for ThemeFile { | ||||
|     fn respond_to(self, r: &'r Request<'_>) -> response::ResultFuture<'r> { | ||||
|         Box::pin(async move { | ||||
|             let contents = std::fs::read(self.0.path()).map_err(|_| Status::InternalServerError)?; | ||||
|     async fn respond_to(self, r: &'r Request<'_>) -> response::Result<'r> { | ||||
|         let contents = std::fs::read(self.0.path()).map_err(|_| Status::InternalServerError)?; | ||||
| 
 | ||||
|             let mut hasher = DefaultHasher::new(); | ||||
|             hasher.write(&contents); | ||||
|             let etag = format!("{:x}", hasher.finish()); | ||||
|         let mut hasher = DefaultHasher::new(); | ||||
|         hasher.write(&contents); | ||||
|         let etag = format!("{:x}", hasher.finish()); | ||||
| 
 | ||||
|             if r.headers() | ||||
|                 .get("If-None-Match") | ||||
|                 .any(|s| s[1..s.len() - 1] == etag) | ||||
|             { | ||||
|                 Response::build() | ||||
|                     .status(Status::NotModified) | ||||
|                     .header(Header::new("ETag", etag)) | ||||
|                     .ok() | ||||
|                     .await | ||||
|             } else { | ||||
|                 Response::build() | ||||
|                     .merge(self.0.respond_to(r).await.ok().unwrap()) | ||||
|                     .header(Header::new("ETag", etag)) | ||||
|                     .ok() | ||||
|                     .await | ||||
|             } | ||||
|         }) | ||||
|         if r.headers() | ||||
|             .get("If-None-Match") | ||||
|             .any(|s| s[1..s.len() - 1] == etag) | ||||
|         { | ||||
|             Response::build() | ||||
|                 .status(Status::NotModified) | ||||
|                 .header(Header::new("ETag", etag)) | ||||
|                 .ok() | ||||
|         } else { | ||||
|             Response::build() | ||||
|                 .merge(self.0.respond_to(r).await.ok().unwrap()) | ||||
|                 .header(Header::new("ETag", etag)) | ||||
|                 .ok() | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -643,7 +643,7 @@ pub fn remote_interact_post( | ||||
|         .and_then(|blog| Post::find_by_slug(&rockets.conn, &slug, blog.id))?; | ||||
|     if let Some(uri) = User::fetch_remote_interact_uri(&remote.remote) | ||||
|         .ok() | ||||
|         .and_then(|uri| rt_format!(uri, uri = target.ap_url).ok()) | ||||
|         .and_then(|uri| uri.replace("{uri}", format!("{}", target.ap_url)).ok()) | ||||
|     { | ||||
|         Ok(Redirect::to(uri).into()) | ||||
|     } else { | ||||
|  | ||||
| @ -201,15 +201,14 @@ pub fn follow_not_connected( | ||||
|         if let Some(uri) = User::fetch_remote_interact_uri(&remote_form) | ||||
|             .ok() | ||||
|             .and_then(|uri| { | ||||
|                 rt_format!( | ||||
|                     uri, | ||||
|                     uri = format!( | ||||
|                 uri.replace( | ||||
|                     "{uri}", | ||||
|                     format!( | ||||
|                         "{}@{}", | ||||
|                         target.fqn, | ||||
|                         target.get_instance(&rockets.conn).ok()?.public_domain | ||||
|                     ) | ||||
|                     ), | ||||
|                 ) | ||||
|                 .ok() | ||||
|             }) | ||||
|         { | ||||
|             Ok(Redirect::to(uri).into()) | ||||
|  | ||||
| @ -44,21 +44,47 @@ pub fn host_meta() -> String { | ||||
| struct WebfingerResolver; | ||||
| 
 | ||||
| impl Resolver<PlumeRocket> for WebfingerResolver { | ||||
|     fn instance_domain<'a>() -> &'a str { | ||||
|     fn instance_domain<'a>(&self) -> &'a str { | ||||
|         CONFIG.base_url.as_str() | ||||
|     } | ||||
| 
 | ||||
|     fn find(prefix: Prefix, acct: String, ctx: PlumeRocket) -> Result<Webfinger, ResolverError> { | ||||
|     fn find( | ||||
|         &self, | ||||
|         prefix: Prefix, | ||||
|         acct: String, | ||||
|         ctx: PlumeRocket, | ||||
|     ) -> Result<Webfinger, ResolverError> { | ||||
|         match prefix { | ||||
|             Prefix::Acct => User::find_by_fqn(&ctx, &acct) | ||||
|                 .await | ||||
|                 .and_then(|usr| usr.webfinger(&*ctx.conn)) | ||||
|                 .or(Err(ResolverError::NotFound)), | ||||
|             Prefix::Group => Blog::find_by_fqn(&ctx, &acct) | ||||
|                 .await | ||||
|                 .and_then(|blog| blog.webfinger(&*ctx.conn)) | ||||
|                 .or(Err(ResolverError::NotFound)), | ||||
|             Prefix::Custom(_) => Err(ResolverError::NotFound), | ||||
|         } | ||||
|     } | ||||
|     fn endpoint( | ||||
|         &self, | ||||
|         resource: impl Into<String>, | ||||
|         resource_repo: PlumeRocket, | ||||
|     ) -> Result<Webfinger, ResolverError> { | ||||
|         let resource = resource.into(); | ||||
|         let mut parsed_query = resource.splitn(2, ':'); | ||||
|         let res_prefix = Prefix::from(parsed_query.next().ok_or(ResolverError::InvalidResource)?); | ||||
|         let res = parsed_query.next().ok_or(ResolverError::InvalidResource)?; | ||||
| 
 | ||||
|         let mut parsed_res = res.splitn(2, '@'); | ||||
|         let user = parsed_res.next().ok_or(ResolverError::InvalidResource)?; | ||||
|         let domain = parsed_res.next().ok_or(ResolverError::InvalidResource)?; | ||||
|         if domain == webfinger.instance_domain() { | ||||
|             webfinger.find(res_prefix, user.to_string(), resource_repo) | ||||
|         } else { | ||||
|             Err(ResolverError::WrongDomain) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[get("/.well-known/webfinger?<resource>")] | ||||
|  | ||||
| @ -51,33 +51,30 @@ impl IntoContext for PlumeRocket { | ||||
| #[derive(Debug)] | ||||
| pub struct Ructe(pub Vec<u8>); | ||||
| 
 | ||||
| #[rocket::async_trait] | ||||
| impl<'r> Responder<'r> for Ructe { | ||||
|     fn respond_to(self, r: &'r Request) -> response::ResultFuture<'r> { | ||||
|         Box::pin(async move { | ||||
|             //if method is not Get or page contain a form, no caching
 | ||||
|             if r.method() != Method::Get || self.0.windows(6).any(|w| w == b"<form ") { | ||||
|                 return HtmlCt(self.0).respond_to(r).await; | ||||
|             } | ||||
|             let mut hasher = DefaultHasher::new(); | ||||
|             hasher.write(&self.0); | ||||
|             let etag = format!("{:x}", hasher.finish()); | ||||
|             if r.headers() | ||||
|                 .get("If-None-Match") | ||||
|                 .any(|s| s[1..s.len() - 1] == etag) | ||||
|             { | ||||
|                 Response::build() | ||||
|                     .status(Status::NotModified) | ||||
|                     .header(Header::new("ETag", etag)) | ||||
|                     .ok() | ||||
|                     .await | ||||
|             } else { | ||||
|                 Response::build() | ||||
|                     .merge(HtmlCt(self.0).respond_to(r).await.ok().unwrap()) | ||||
|                     .header(Header::new("ETag", etag)) | ||||
|                     .ok() | ||||
|                     .await | ||||
|             } | ||||
|         }) | ||||
|     async fn respond_to(self, r: &'r Request<'_>) -> response::Result<'r> { | ||||
|         //if method is not Get or page contain a form, no caching
 | ||||
|         if r.method() != Method::Get || self.0.windows(6).any(|w| w == b"<form ") { | ||||
|             return HtmlCt(self.0).respond_to(r).await; | ||||
|         } | ||||
|         let mut hasher = DefaultHasher::new(); | ||||
|         hasher.write(&self.0); | ||||
|         let etag = format!("{:x}", hasher.finish()); | ||||
|         if r.headers() | ||||
|             .get("If-None-Match") | ||||
|             .any(|s| s[1..s.len() - 1] == etag) | ||||
|         { | ||||
|             Response::build() | ||||
|                 .status(Status::NotModified) | ||||
|                 .header(Header::new("ETag", etag)) | ||||
|                 .ok() | ||||
|         } else { | ||||
|             Response::build() | ||||
|                 .merge(HtmlCt(self.0).respond_to(r).await.ok().unwrap()) | ||||
|                 .header(Header::new("ETag", etag)) | ||||
|                 .ok() | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user