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…
Reference in New Issue
Block a user