Bumping versions using actix-web 4

This commit is contained in:
Dietrich 2021-10-11 13:01:19 +02:00
parent c148e839f6
commit 3bb79666b2
9 changed files with 620 additions and 604 deletions

1082
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ keywords = ["url", "link", "webpage", "actix", "web"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "README.md" readme = "README.md"
repository = "https://github.com/enaut/pslink/" repository = "https://github.com/enaut/pslink/"
version = "0.4.3" version = "0.4.4"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -16,12 +16,12 @@ version = "0.4.3"
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
fluent = "0.15" fluent = "0.16"
seed = "0.8" seed = "0.8"
serde = {version="1.0", features = ["derive"]} serde = {version="1.0", features = ["derive"]}
unic-langid = "0.9" unic-langid = "0.9"
strum_macros = "0.21" strum_macros = "0.22"
strum = "0.21" strum = "0.22"
enum-map = "1" enum-map = "1"
qrcode = "0.12" qrcode = "0.12"
image = "0.23" image = "0.23"

View File

@ -8,13 +8,13 @@ keywords = ["url", "link", "webpage", "actix", "web"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "README.md" readme = "README.md"
repository = "https://github.com/enaut/pslink/" repository = "https://github.com/enaut/pslink/"
version = "0.4.3" version = "0.4.4"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
fluent = "0.15" fluent = "0.16"
serde = {version="1.0", features = ["derive"]} serde = {version="1.0", features = ["derive"]}
unic-langid = "0.9" unic-langid = "0.9"

View File

@ -9,33 +9,36 @@ license = "MIT OR Apache-2.0"
name = "pslink" name = "pslink"
readme = "README.md" readme = "README.md"
repository = "https://github.com/enaut/pslink/" repository = "https://github.com/enaut/pslink/"
version = "0.4.3" version = "0.4.4"
[build-dependencies] [build-dependencies]
actix-web-static-files = "3.0" actix-web-static-files = { path = "../../actix-web-static-files" }
static-files = { version = "0.2", default-features = false }
[dependencies] [dependencies]
actix-identity = "0.3" actix-identity = "0.4.0-beta.2"
actix-rt = "1.1" actix-rt = "2.2"
actix-web = "3" actix-web = "4.0.0-beta.9"
actix-web-static-files = "3" actix-web-static-files = { path = "../../actix-web-static-files" }
actix-files = "0.5" actix-files = "0.6.0-beta.7"
argonautica = "0.2" argonautica = "0.2"
clap = "2.33" clap = "2.33"
dotenv = "0.15.0" dotenv = "0.15.0"
fluent-langneg = "0.13" fluent-langneg = "0.13"
image = "0.23" image = "0.23"
opentelemetry = "0.14" opentelemetry = "0.16"
opentelemetry-jaeger = "0.12" opentelemetry-jaeger = "0.15"
qrcode = "0.12" qrcode = "0.12"
rand = "0.8" rand = "0.8"
rpassword = "5.0" rpassword = "5.0"
serde = {version="1.0", features = ["derive"]} serde = {version="1.0", features = ["derive"]}
static-files = { version = "0.2", default-features = false }
thiserror = "1.0" thiserror = "1.0"
tracing-actix-web = "0.2.1" tracing-actix-web = "0.4.0-beta.13"
tracing-opentelemetry = "0.12" tracing-opentelemetry = "0.15"
async-trait = "0.1" async-trait = "0.1"
enum-map = {version="1", features = ["serde"]} enum-map = {version="1", features = ["serde"]}
indexmap = "~1.6.2"
pslink-shared = {version="0.4", path = "../shared" } pslink-shared = {version="0.4", path = "../shared" }
@ -48,7 +51,7 @@ version = "0.6"
[dependencies.sqlx] [dependencies.sqlx]
features = ["sqlite", "macros", "runtime-actix-rustls", "chrono", "migrate", "offline"] features = ["sqlite", "macros", "runtime-actix-rustls", "chrono", "migrate", "offline"]
version = "0.4" version = "0.5"
[dependencies.tracing] [dependencies.tracing]
features = ["log"] features = ["log"]
@ -62,11 +65,11 @@ version = "0.2.17"
actix-server = "1.0.4" actix-server = "1.0.4"
tempdir = "0.3" tempdir = "0.3"
test_bin = "0.3" test_bin = "0.3"
tokio = "0.2.25" tokio = "1.12"
assert_cmd = "1.0.7" assert_cmd = "2.0"
predicates = "2.0.0" predicates = "2.0.0"
[dev-dependencies.reqwest] [dev-dependencies.reqwest]
features = ["cookies", "json"] features = ["cookies", "json"]
version = "0.10.10" version = "0.11"

View File

@ -1,4 +1,4 @@
use actix_web_static_files::resource_dir; use static_files::resource_dir;
fn main() { fn main() {
resource_dir("./static/").build().unwrap(); resource_dir("./static/").build().unwrap();

View File

@ -5,6 +5,8 @@ mod views;
use actix_files::Files; use actix_files::Files;
use actix_identity::{CookieIdentityPolicy, IdentityService}; use actix_identity::{CookieIdentityPolicy, IdentityService};
use actix_web::middleware::Compat;
use actix_web::web::Data;
use actix_web::{web, App, HttpServer}; use actix_web::{web, App, HttpServer};
use pslink::ServerConfig; use pslink::ServerConfig;
@ -32,7 +34,7 @@ pub fn get_subscriber(name: &str, env_filter: &str) -> impl Subscriber + Send +
let otel_layer = OpenTelemetryLayer::new(tracer); let otel_layer = OpenTelemetryLayer::new(tracer);
// Use the tracing subscriber `Registry`, or any other subscriber // Use the tracing subscriber `Registry`, or any other subscriber
// that impls `LookupSpan` // that implements `LookupSpan`
Registry::default() Registry::default()
.with(otel_layer) .with(otel_layer)
.with(env_filter) .with(env_filter)
@ -105,9 +107,10 @@ pub async fn webservice(
let server = HttpServer::new(move || { let server = HttpServer::new(move || {
let generated = generate(); let generated = generate();
let logger = Compat::new(TracingLogger::default());
App::new() App::new()
.data(server_config.clone()) .app_data(Data::new(server_config.clone()))
.wrap(TracingLogger) .wrap(logger)
.wrap(IdentityService::new( .wrap(IdentityService::new(
CookieIdentityPolicy::new(&[0; 32]) CookieIdentityPolicy::new(&[0; 32])
.name("auth-cookie") .name("auth-cookie")

View File

@ -30,13 +30,13 @@ use pslink::ServerError;
#[instrument] #[instrument]
fn redirect_builder(target: &str) -> HttpResponse { fn redirect_builder(target: &str) -> HttpResponse {
HttpResponse::SeeOther() HttpResponse::SeeOther()
.set(CacheControl(vec![ .insert_header(CacheControl(vec![
CacheDirective::NoCache, CacheDirective::NoCache,
CacheDirective::NoStore, CacheDirective::NoStore,
CacheDirective::MustRevalidate, CacheDirective::MustRevalidate,
])) ]))
.set(Expires(SystemTime::now().into())) .insert_header(Expires(SystemTime::now().into()))
.set_header(actix_web::http::header::LOCATION, target) .insert_header((actix_web::http::header::LOCATION, target))
.body(format!("Redirect to {}", target)) .body(format!("Redirect to {}", target))
} }
@ -112,7 +112,7 @@ pub async fn index_json(
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Listing Links to Json api"); info!("Listing Links to Json api");
match queries::list_all_allowed(&id, &config, form.0).await { match queries::list_all_allowed(&id, &config, form.0).await {
Ok(links) => Ok(HttpResponse::Ok().json2(&links.list)), Ok(links) => Ok(HttpResponse::Ok().json(&links.list)),
Err(e) => { Err(e) => {
error!("Failed to access database: {:?}", e); error!("Failed to access database: {:?}", e);
warn!("Not logged in - redirecting to login page"); warn!("Not logged in - redirecting to login page");
@ -129,7 +129,7 @@ pub async fn index_users_json(
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Listing Users to Json api"); info!("Listing Users to Json api");
if let Ok(users) = queries::list_users(&id, &config, form.0).await { if let Ok(users) = queries::list_users(&id, &config, form.0).await {
Ok(HttpResponse::Ok().json2(&users.list)) Ok(HttpResponse::Ok().json(&users.list))
} else { } else {
Ok(redirect_builder("/admin/login")) Ok(redirect_builder("/admin/login"))
} }
@ -145,7 +145,7 @@ pub async fn get_logged_user_json(
Ok(HttpResponse::Unauthorized().finish()) Ok(HttpResponse::Unauthorized().finish())
} }
RoleGuard::Regular { user } | RoleGuard::Admin { user } => { RoleGuard::Regular { user } | RoleGuard::Admin { user } => {
Ok(HttpResponse::Ok().json2(&user)) Ok(HttpResponse::Ok().json(&user))
} }
} }
} }
@ -156,7 +156,7 @@ pub async fn download_png(
config: web::Data<crate::ServerConfig>, config: web::Data<crate::ServerConfig>,
link_code: web::Path<String>, link_code: web::Path<String>,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
match queries::get_link(&id, &link_code.0, &config).await { match queries::get_link(&id, &link_code, &config).await {
Ok(query) => { Ok(query) => {
let qr = QrCode::with_error_correction_level( let qr = QrCode::with_error_correction_level(
&format!("http://{}/{}", config.public_url, &query.item.code), &format!("http://{}/{}", config.public_url, &query.item.code),
@ -169,7 +169,9 @@ pub async fn download_png(
.write_to(&mut temporary_data, ImageOutputFormat::Png) .write_to(&mut temporary_data, ImageOutputFormat::Png)
.unwrap(); .unwrap();
let image_data = temporary_data.into_inner(); let image_data = temporary_data.into_inner();
Ok(HttpResponse::Ok().set(ContentType::png()).body(image_data)) Ok(HttpResponse::Ok()
.insert_header(ContentType::png())
.body(image_data))
} }
Err(e) => Err(e), Err(e) => Err(e),
} }
@ -183,7 +185,7 @@ pub async fn process_create_user_json(
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Listing Users to Json api"); info!("Listing Users to Json api");
match queries::create_user(&id, data.into_inner(), &config).await { match queries::create_user(&id, data.into_inner(), &config).await {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json(&Status::Success(Message {
message: format!("Successfully saved user: {}", item.item.username), message: format!("Successfully saved user: {}", item.item.username),
}))), }))),
Err(e) => Err(e), Err(e) => Err(e),
@ -198,7 +200,7 @@ pub async fn process_update_user_json(
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Listing Users to Json api"); info!("Listing Users to Json api");
match queries::update_user(&id, &form, &config).await { match queries::update_user(&id, &form, &config).await {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json(&Status::Success(Message {
message: format!("Successfully saved user: {}", item.item.username), message: format!("Successfully saved user: {}", item.item.username),
}))), }))),
Err(e) => Err(e), Err(e) => Err(e),
@ -212,7 +214,7 @@ pub async fn toggle_admin(
id: Identity, id: Identity,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
let update = queries::toggle_admin(&id, user.id, &config).await?; let update = queries::toggle_admin(&id, user.id, &config).await?;
Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(HttpResponse::Ok().json(&Status::Success(Message {
message: format!( message: format!(
"Successfully changed privileges or user: {}", "Successfully changed privileges or user: {}",
update.item.username update.item.username
@ -230,14 +232,14 @@ pub async fn get_language(
let user = authenticate(&id, &config).await?; let user = authenticate(&id, &config).await?;
match user { match user {
RoleGuard::NotAuthenticated | RoleGuard::Disabled => { RoleGuard::NotAuthenticated | RoleGuard::Disabled => {
Ok(HttpResponse::Ok().json2(&detect_language(&req)?)) Ok(HttpResponse::Ok().json(&detect_language(&req)?))
} }
RoleGuard::Regular { user } | RoleGuard::Admin { user } => { RoleGuard::Regular { user } | RoleGuard::Admin { user } => {
Ok(HttpResponse::Ok().json2(&user.language)) Ok(HttpResponse::Ok().json(&user.language))
} }
} }
} else { } else {
Ok(HttpResponse::Ok().json2(&detect_language(&req)?)) Ok(HttpResponse::Ok().json(&detect_language(&req)?))
} }
} }
@ -248,7 +250,7 @@ pub async fn set_language(
id: Identity, id: Identity,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
queries::set_language(&id, data.0, &config).await?; queries::set_language(&id, data.0, &config).await?;
Ok(HttpResponse::Ok().json2(&data.0)) Ok(HttpResponse::Ok().json(&data.0))
} }
#[instrument(skip(id))] #[instrument(skip(id))]
@ -278,23 +280,23 @@ pub async fn process_login_json(
info!("Log-in of user: {}", &u.username); info!("Log-in of user: {}", &u.username);
let session_token = u.username.clone(); let session_token = u.username.clone();
id.remember(session_token); id.remember(session_token);
Ok(HttpResponse::Ok().json2(&u)) Ok(HttpResponse::Ok().json(&u))
} else { } else {
info!("Invalid password for user: {}", &u.username); info!("Invalid password for user: {}", &u.username);
Ok(HttpResponse::Unauthorized().json2(&Status::Error(Message { Ok(HttpResponse::Unauthorized().json(&Status::Error(Message {
message: "Failed to Login".to_string(), message: "Failed to Login".to_string(),
}))) })))
} }
} else { } else {
// should fail earlier if secret is missing. // should fail earlier if secret is missing.
Ok(HttpResponse::Unauthorized().json2(&Status::Error(Message { Ok(HttpResponse::Unauthorized().json(&Status::Error(Message {
message: "Failed to Login".to_string(), message: "Failed to Login".to_string(),
}))) })))
} }
} }
Err(e) => { Err(e) => {
info!("Failed to login: {}", e); info!("Failed to login: {}", e);
Ok(HttpResponse::Unauthorized().json2(&Status::Error(Message { Ok(HttpResponse::Unauthorized().json(&Status::Error(Message {
message: "Failed to Login".to_string(), message: "Failed to Login".to_string(),
}))) })))
} }
@ -311,7 +313,7 @@ pub async fn logout(id: Identity) -> Result<HttpResponse, ServerError> {
#[instrument()] #[instrument()]
pub async fn to_admin() -> Result<HttpResponse, ServerError> { pub async fn to_admin() -> Result<HttpResponse, ServerError> {
let response = HttpResponse::PermanentRedirect() let response = HttpResponse::PermanentRedirect()
.set_header(actix_web::http::header::LOCATION, "/app/") .insert_header((actix_web::http::header::LOCATION, "/app/"))
.body(r#"The admin interface moved to <a href="/app/">/app/</a>"#); .body(r#"The admin interface moved to <a href="/app/">/app/</a>"#);
Ok(response) Ok(response)
@ -324,7 +326,7 @@ pub async fn redirect(
req: HttpRequest, req: HttpRequest,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Redirecting to {:?}", data); info!("Redirecting to {:?}", data);
let link = queries::get_link_simple(&data.0, &config).await; let link = queries::get_link_simple(&data, &config).await;
info!("link: {:?}", link); info!("link: {:?}", link);
match link { match link {
Ok(link) => { Ok(link) => {
@ -334,7 +336,7 @@ pub async fn redirect(
Err(ServerError::Database(e)) => { Err(ServerError::Database(e)) => {
info!( info!(
"Link was not found: http://{}/{} \n {}", "Link was not found: http://{}/{} \n {}",
&config.public_url, &data.0, e &config.public_url, &data, e
); );
Ok(HttpResponse::NotFound().body( Ok(HttpResponse::NotFound().body(
r#"<!DOCTYPE html> r#"<!DOCTYPE html>
@ -373,7 +375,7 @@ pub async fn process_create_link_json(
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
let new_link = queries::create_link(&id, data.into_inner(), &config).await; let new_link = queries::create_link(&id, data.into_inner(), &config).await;
match new_link { match new_link {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json(&Status::Success(Message {
message: format!("Successfully saved link: {}", item.item.code), message: format!("Successfully saved link: {}", item.item.code),
}))), }))),
Err(e) => Err(e), Err(e) => Err(e),
@ -388,7 +390,7 @@ pub async fn process_update_link_json(
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
let new_link = queries::update_link(&id, data.into_inner(), &config).await; let new_link = queries::update_link(&id, data.into_inner(), &config).await;
match new_link { match new_link {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json(&Status::Success(Message {
message: format!("Successfully updated link: {}", item.item.code), message: format!("Successfully updated link: {}", item.item.code),
}))), }))),
Err(e) => Err(e), Err(e) => Err(e),
@ -402,7 +404,7 @@ pub async fn process_delete_link_json(
data: web::Json<LinkDelta>, data: web::Json<LinkDelta>,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
queries::delete_link(&id, &data.code, &config).await?; queries::delete_link(&id, &data.code, &config).await?;
Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(HttpResponse::Ok().json(&Status::Success(Message {
message: format!("Successfully deleted link: {}", &data.code), message: format!("Successfully deleted link: {}", &data.code),
}))) })))
} }

View File

@ -8,11 +8,11 @@ license = "MIT OR Apache-2.0"
name = "pslink-shared" name = "pslink-shared"
readme = "../pslink/README.md" readme = "../pslink/README.md"
repository = "https://github.com/enaut/pslink/" repository = "https://github.com/enaut/pslink/"
version = "0.4.3" version = "0.4.4"
[dependencies] [dependencies]
serde = {version="1.0", features = ["derive"]} serde = {version="1.0", features = ["derive"]}
chrono = {version = "0.4", features = ["serde"] } chrono = {version = "0.4", features = ["serde"] }
enum-map = {version="1", features = ["serde"]} enum-map = {version="1", features = ["serde"]}
strum_macros = "0.21" strum_macros = "0.22"
strum = "0.21" strum = "0.22"

View File

@ -1,11 +1,11 @@
//! The more generic datatypes used in pslink //! The more generic data-types used in pslink
use std::ops::Deref; use std::ops::Deref;
use serde::{Deserialize, Serialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
use strum_macros::{AsRefStr, EnumIter, EnumString, ToString}; use strum_macros::{AsRefStr, EnumIter, EnumString};
use crate::apirequests::users::Role; use crate::apirequests::users::Role;
/// A generic list returntype containing the User and a Vec containing e.g. Links or Users /// A generic list return type containing the User and a Vec containing e.g. Links or Users
#[derive(Clone, Deserialize, Serialize)] #[derive(Clone, Deserialize, Serialize)]
pub struct ListWithOwner<T> { pub struct ListWithOwner<T> {
pub user: User, pub user: User,
@ -48,7 +48,7 @@ pub struct Count {
pub number: i32, pub number: i32,
} }
/// Everytime a shor url is clicked record it for statistical evaluation. /// Every time a short url is clicked record it for statistical evaluation.
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
pub struct Click { pub struct Click {
pub id: i64, pub id: i64,
@ -118,20 +118,10 @@ impl<T> Deref for Loadable<T> {
} }
/// An `enum` containing the available languages. /// An `enum` containing the available languages.
/// To add an additional language add it to this enum aswell as an appropriate file into the locales folder. /// To add an additional language add it to this enum as well as an appropriate file into the locales folder.
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]
#[derive( #[derive(
Debug, Debug, Copy, Clone, EnumIter, EnumString, AsRefStr, Eq, PartialEq, Serialize, Deserialize,
Copy,
Clone,
EnumIter,
EnumString,
ToString,
AsRefStr,
Eq,
PartialEq,
Serialize,
Deserialize,
)] )]
pub enum Lang { pub enum Lang {
#[strum(serialize = "en-US", serialize = "en", serialize = "enUS")] #[strum(serialize = "en-US", serialize = "en", serialize = "enUS")]
@ -139,3 +129,9 @@ pub enum Lang {
#[strum(serialize = "de-DE", serialize = "de", serialize = "deDE")] #[strum(serialize = "de-DE", serialize = "de", serialize = "deDE")]
DeDE, DeDE,
} }
impl std::fmt::Display for Lang {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}