Added POST routes for everything

This commit is contained in:
Raphaël Thériault 2020-01-15 15:13:08 -05:00
parent 35db5f64d4
commit 11c5e2f384
4 changed files with 100 additions and 35 deletions

7
Cargo.lock generated
View File

@ -708,6 +708,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libsqlite3-sys 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
"radix_fmt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1315,6 +1316,11 @@ dependencies = [
"scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "radix_fmt"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
version = "0.7.3"
@ -2133,6 +2139,7 @@ dependencies = [
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum r2d2 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e48fa64898ef0286b6ee4b4d8f61483f9182acf5e44e62a398b1c7f56f2f861d"
"checksum radix_fmt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"

View File

@ -30,6 +30,7 @@ env_logger = "0.7.1"
futures = "0.3.1"
lazy_static = "1.4.0"
num_cpus = "1.11.1"
radix_fmt = "1.0.0"
rand = "0.7.3"
toml = "0.5.5"
[dependencies.diesel]

View File

@ -94,27 +94,39 @@ async fn main() {
.route("/", web::get().to(routes::index))
.route("/logout", web::get().to(routes::logout))
.route("/config", web::get().to(routes::get_config))
.route("/f", web::get().to(routes::files::select))
.route("/l", web::get().to(routes::links::select))
.route("/t", web::get().to(routes::texts::select))
.route("/f/{id}", web::get().to(routes::files::get))
.route("/l/{id}", web::get().to(routes::links::get))
.route("/t/{id}", web::get().to(routes::texts::get))
.service(
web::resource("/f")
.route(web::get().to(routes::files::select))
.route(web::post().to(routes::files::post)),
)
.service(
web::resource("/l")
.route(web::get().to(routes::links::select))
.route(web::post().to(routes::links::post)),
)
.service(
web::resource("/t")
.route(web::get().to(routes::texts::select))
.route(web::post().to(routes::texts::post)),
)
.service(
web::resource("/f/{id}")
.data(web::Json::<routes::files::PutFile>::configure(|cfg| {
cfg.limit(max_filesize_json)
}))
.route(web::get().to(routes::files::get))
.route(web::put().to(routes::files::put))
.route(web::delete().to(routes::files::delete)),
)
.service(
web::resource("/l/{id}")
.route(web::get().to(routes::links::get))
.route(web::put().to(routes::links::put))
.route(web::delete().to(routes::links::delete)),
)
.service(
web::resource("/t/{id}")
.route(web::get().to(routes::texts::get))
.route(web::put().to(routes::texts::put))
.route(web::delete().to(routes::texts::delete)),
)

View File

@ -79,9 +79,8 @@ async fn auth(
}
}
/// Match result from REPLACE queries
#[inline(always)]
fn match_replace_result<T: Serialize>(
/// Match result from REPLACE queries for PUT routes
fn match_replace_result_put<T: Serialize>(
result: Result<T, BlockingError<diesel::result::Error>>,
) -> Result<HttpResponse, Error> {
match result {
@ -92,8 +91,20 @@ fn match_replace_result<T: Serialize>(
}
}
/// Match result from REPLACE queries for POST routes
fn match_replace_result_post<T: Serialize>(
result: Result<T, BlockingError<diesel::result::Error>>,
id: i32,
) -> Result<HttpResponse, Error> {
match result {
Ok(_) => Ok(HttpResponse::Created().body(format!("{}", radix_fmt::radix_36(id)))),
Err(_) => Err(HttpResponse::InternalServerError()
.body("Internal server error")
.into()),
}
}
/// Handles error from single GET queries using find
#[inline(always)]
fn match_find_error<T>(error: BlockingError<diesel::result::Error>) -> Result<T, Error> {
match error {
BlockingError::Error(e) => match e {
@ -345,7 +356,7 @@ pub mod files {
pub filename: String,
}
/// Common setup for both routes
/// Common setup for both PUT and POST
async fn setup(config: &Config) -> Result<(PathBuf, PathBuf), Error> {
let path = config.files_dir.clone();
let relative_path = PathBuf::new();
@ -361,7 +372,7 @@ pub mod files {
Ok((path, relative_path))
}
/// Common conversion for both routes
/// Common conversion for both PUT and POST
fn pts(path: &PathBuf) -> Result<String, Error> {
match path.to_str() {
Some(rp) => Ok(rp.to_owned()),
@ -370,19 +381,6 @@ pub mod files {
.into()),
}
}
/// Common database query for both routes
async fn query(
id: i32,
relative_path: String,
pool: web::Data<Pool>,
) -> Result<HttpResponse, Error> {
match web::block(move || queries::files::replace(id, &relative_path, pool)).await {
Ok(file) => Ok(HttpResponse::Created().json(file)),
Err(_) => Err(HttpResponse::InternalServerError()
.body("Internal server error")
.into()),
}
}
/// PUT a new file entry
pub async fn put(
@ -422,7 +420,12 @@ pub mod files {
.into());
}
query(id, relative_path, pool).await
match web::block(move || queries::files::replace(id, &relative_path, pool)).await {
Ok(file) => Ok(HttpResponse::Created().json(file)),
Err(_) => Err(HttpResponse::InternalServerError()
.body("Internal server error")
.into()),
}
}
/// POST a new file entry using a multipart body
@ -497,7 +500,12 @@ pub mod files {
};
}
query(id, relative_path, pool).await
match web::block(move || queries::files::replace(id, &relative_path, pool)).await {
Ok(_) => Ok(HttpResponse::Created().body(format!("{}", radix_fmt::radix_36(id)))),
Err(_) => Err(HttpResponse::InternalServerError()
.body("Internal server error")
.into()),
}
}
}
@ -505,7 +513,8 @@ pub mod links {
use crate::{
queries::{self, SelectQuery},
routes::{
auth, match_find_error, match_replace_result, parse_id, timestamp_to_last_modified,
auth, match_find_error, match_replace_result_post, match_replace_result_put, parse_id,
timestamp_to_last_modified,
},
Pool,
};
@ -513,6 +522,8 @@ pub mod links {
use actix_web::{web, Error, HttpRequest, HttpResponse};
select!(links);
delete!(links);
random_id!(links);
/// GET a link entry and redirect to it
pub async fn get(
@ -531,7 +542,7 @@ pub mod links {
/// Request body when PUTting links
#[derive(Deserialize)]
pub struct PutLink {
pub struct PutPostLink {
pub forward: String,
}
@ -539,7 +550,7 @@ pub mod links {
pub async fn put(
request: HttpRequest,
path: web::Path<String>,
body: web::Json<PutLink>,
body: web::Json<PutPostLink>,
pool: web::Data<Pool>,
identity: Identity,
password_hash: web::Data<Vec<u8>>,
@ -547,12 +558,27 @@ pub mod links {
auth(identity, request, &password_hash).await?;
let id = parse_id(&path)?;
match_replace_result(
match_replace_result_put(
web::block(move || queries::links::replace(id, &body.forward, pool)).await,
)
}
delete!(links);
/// POST a new link entry
pub async fn post(
request: HttpRequest,
body: web::Json<PutPostLink>,
pool: web::Data<Pool>,
identity: Identity,
password_hash: web::Data<Vec<u8>>,
) -> Result<HttpResponse, Error> {
auth(identity, request, &password_hash).await?;
let id = random_id(&pool).await?;
match_replace_result_post(
web::block(move || queries::links::replace(id, &body.forward, pool)).await,
id,
)
}
}
pub mod texts {
@ -560,7 +586,8 @@ pub mod texts {
use crate::{
queries::{self, SelectQuery},
routes::{
auth, match_find_error, match_replace_result, parse_id, timestamp_to_last_modified,
auth, match_find_error, match_replace_result_post, match_replace_result_put, parse_id,
timestamp_to_last_modified,
},
Pool,
};
@ -572,6 +599,8 @@ pub mod texts {
use actix_web::{web, Error, HttpRequest, HttpResponse};
select!(texts);
delete!(texts);
random_id!(texts);
/// GET a text entry and display it
pub async fn get(
@ -630,11 +659,27 @@ pub mod texts {
auth(identity, request, &password_hash).await?;
let id = parse_id(&path)?;
match_replace_result(
match_replace_result_put(
web::block(move || queries::texts::replace(id, &body.contents, body.highlight, pool))
.await,
)
}
delete!(texts);
/// PUT a new text entry
pub async fn post(
request: HttpRequest,
body: web::Json<PutText>,
pool: web::Data<Pool>,
identity: Identity,
password_hash: web::Data<Vec<u8>>,
) -> Result<HttpResponse, Error> {
auth(identity, request, &password_hash).await?;
let id = random_id(&pool).await?;
match_replace_result_post(
web::block(move || queries::texts::replace(id, &body.contents, body.highlight, pool))
.await,
id,
)
}
}