new rust, clippy
This commit is contained in:
parent
4c920e5a9d
commit
0fbecaba3d
16 changed files with 67 additions and 60 deletions
|
@ -3,7 +3,7 @@ use serde::Deserialize;
|
||||||
use time::{OffsetDateTime, Duration};
|
use time::{OffsetDateTime, Duration};
|
||||||
use tower_cookies::{Cookies, Cookie};
|
use tower_cookies::{Cookies, Cookie};
|
||||||
|
|
||||||
use crate::types::{user::User, response::ResponseCode, session::Session, extract::{Json, AuthorizedUser, Check, CheckResult, Log}};
|
use crate::types::{user::User, http::ResponseCode, session::Session, extract::{Json, AuthorizedUser, Check, CheckResult, Log}};
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct RegistrationRequet {
|
pub struct RegistrationRequet {
|
||||||
|
@ -24,9 +24,9 @@ impl Check for RegistrationRequet {
|
||||||
Self::assert_length(&self.email, 1, 50, "Email can only by 1-50 characters long")?;
|
Self::assert_length(&self.email, 1, 50, "Email can only by 1-50 characters long")?;
|
||||||
Self::assert_length(&self.password, 1, 50, "Password can only by 1-50 characters long")?;
|
Self::assert_length(&self.password, 1, 50, "Password can only by 1-50 characters long")?;
|
||||||
Self::assert_length(&self.gender, 1, 100, "Gender can only by 1-100 characters long")?;
|
Self::assert_length(&self.gender, 1, 100, "Gender can only by 1-100 characters long")?;
|
||||||
Self::assert_range(self.day as u64, 1, 255, "Birthday day can only be between 1-255")?;
|
Self::assert_range(u64::from(self.day), 1, 255, "Birthday day can only be between 1-255")?;
|
||||||
Self::assert_range(self.month as u64, 1, 255, "Birthday month can only be between 1-255")?;
|
Self::assert_range(u64::from(self.month), 1, 255, "Birthday month can only be between 1-255")?;
|
||||||
Self::assert_range(self.year as u64, 1, 4294967295, "Birthday year can only be between 1-4294967295")?;
|
Self::assert_range(u64::from(self.year), 1, 4_294_967_295, "Birthday year can only be between 1-4294967295")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use axum::{Router, response::{Response, Redirect, IntoResponse}, routing::get};
|
use axum::{Router, response::{Response, Redirect, IntoResponse}, routing::get};
|
||||||
|
|
||||||
use crate::{types::{extract::AuthorizedUser, response::ResponseCode}, console};
|
use crate::{types::{extract::AuthorizedUser, http::ResponseCode}, console};
|
||||||
|
|
||||||
async fn root(user: Option<AuthorizedUser>) -> Response {
|
async fn root(user: Option<AuthorizedUser>) -> Response {
|
||||||
if user.is_some() {
|
if user.is_some() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use axum::{response::Response, Router, routing::{post, patch}};
|
use axum::{response::Response, Router, routing::{post, patch}};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::types::{extract::{AuthorizedUser, Json, Check, CheckResult}, post::Post, response::ResponseCode};
|
use crate::types::{extract::{AuthorizedUser, Json, Check, CheckResult}, post::Post, http::ResponseCode};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use axum::{Router, response::Response, routing::post};
|
use axum::{Router, response::Response, routing::post};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use crate::types::{extract::{AuthorizedUser, Json, Check, CheckResult}, response::ResponseCode, user::User};
|
use crate::types::{extract::{AuthorizedUser, Json, Check, CheckResult}, http::ResponseCode, user::User};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct UserLoadRequest {
|
struct UserLoadRequest {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use serde::Serialize;
|
||||||
use serde_json::{ser::Formatter, Value};
|
use serde_json::{ser::Formatter, Value};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use crate::types::response::ResponseCode;
|
use crate::types::http::ResponseCode;
|
||||||
|
|
||||||
struct LogMessage {
|
struct LogMessage {
|
||||||
ip: IpAddr,
|
ip: IpAddr,
|
||||||
|
@ -19,7 +19,7 @@ impl ToString for LogMessage {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
let mut ip = self.ip.to_string();
|
let mut ip = self.ip.to_string();
|
||||||
if ip.contains("::ffff:") {
|
if ip.contains("::ffff:") {
|
||||||
ip = ip.as_str()[7..].to_string()
|
ip = ip.as_str()[7..].to_string();
|
||||||
}
|
}
|
||||||
let color = match self.method {
|
let color = match self.method {
|
||||||
Method::GET => "#3fe04f",
|
Method::GET => "#3fe04f",
|
||||||
|
@ -81,52 +81,52 @@ impl Formatter for HtmlFormatter {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()> where W: ?Sized + io::Write {
|
fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()> where W: ?Sized + io::Write {
|
||||||
let buff = format!("<span class='number'>{}</span>", value);
|
let buff = format!("<span class='number'>{value}</span>");
|
||||||
writer.write_all(buff.as_bytes())
|
writer.write_all(buff.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ impl Formatter for HtmlFormatter {
|
||||||
|
|
||||||
fn beautify(body: String) -> String {
|
fn beautify(body: String) -> String {
|
||||||
if body.is_empty() {
|
if body.is_empty() {
|
||||||
return "".to_string()
|
return String::new()
|
||||||
}
|
}
|
||||||
let Ok(mut json) = serde_json::from_str::<Value>(&body) else {
|
let Ok(mut json) = serde_json::from_str::<Value>(&body) else {
|
||||||
return body
|
return body
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use rusqlite::Result;
|
|
||||||
|
|
||||||
pub mod posts;
|
pub mod posts;
|
||||||
pub mod users;
|
pub mod users;
|
||||||
pub mod sessions;
|
pub mod sessions;
|
||||||
|
@ -8,7 +6,7 @@ pub fn connect() -> Result<rusqlite::Connection, rusqlite::Error> {
|
||||||
rusqlite::Connection::open("xssbook.db")
|
rusqlite::Connection::open("xssbook.db")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<()> {
|
pub fn init() -> Result<(), rusqlite::Error> {
|
||||||
users::init()?;
|
users::init()?;
|
||||||
posts::init()?;
|
posts::init()?;
|
||||||
sessions::init()?;
|
sessions::init()?;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH, Duration};
|
||||||
|
|
||||||
use rusqlite::{OptionalExtension, Row};
|
use rusqlite::{OptionalExtension, Row};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
@ -91,7 +91,7 @@ pub fn add_post(user_id: u64, content: &str) -> Result<Post, rusqlite::Error> {
|
||||||
let Ok(comments_json) = serde_json::to_string(&comments) else {
|
let Ok(comments_json) = serde_json::to_string(&comments) else {
|
||||||
return Err(rusqlite::Error::InvalidQuery)
|
return Err(rusqlite::Error::InvalidQuery)
|
||||||
};
|
};
|
||||||
let date = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
|
let date = u64::try_from(SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO).as_millis()).unwrap_or(0);
|
||||||
let conn = database::connect()?;
|
let conn = database::connect()?;
|
||||||
let mut stmt = conn.prepare("INSERT INTO posts (user_id, content, likes, comments, date) VALUES(?,?,?,?,?) RETURNING *;")?;
|
let mut stmt = conn.prepare("INSERT INTO posts (user_id, content, likes, comments, date) VALUES(?,?,?,?,?) RETURNING *;")?;
|
||||||
let post = stmt.query_row((user_id, content, likes_json, comments_json, date), |row| {
|
let post = stmt.query_row((user_id, content, likes_json, comments_json, date), |row| {
|
||||||
|
|
|
@ -4,7 +4,6 @@ use tracing::instrument;
|
||||||
use crate::{database, types::session::Session};
|
use crate::{database, types::session::Session};
|
||||||
|
|
||||||
pub fn init() -> Result<(), rusqlite::Error> {
|
pub fn init() -> Result<(), rusqlite::Error> {
|
||||||
tracing::trace!("Retrieving posts page");
|
|
||||||
let sql = "
|
let sql = "
|
||||||
CREATE TABLE IF NOT EXISTS sessions (
|
CREATE TABLE IF NOT EXISTS sessions (
|
||||||
user_id INTEGER PRIMARY KEY NOT NULL,
|
user_id INTEGER PRIMARY KEY NOT NULL,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH, Duration};
|
||||||
use rusqlite::{OptionalExtension, Row};
|
use rusqlite::{OptionalExtension, Row};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ fn user_from_row(row: &Row, hide_password: bool) -> Result<User, rusqlite::Error
|
||||||
let month = row.get(8)?;
|
let month = row.get(8)?;
|
||||||
let year = row.get(9)?;
|
let year = row.get(9)?;
|
||||||
|
|
||||||
let password = if hide_password { "".to_string() } else { password };
|
let password = if hide_password { String::new() } else { password };
|
||||||
|
|
||||||
Ok(User{user_id, firstname, lastname, email, password, gender,date, day, month, year})
|
Ok(User{user_id, firstname, lastname, email, password, gender,date, day, month, year})
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ pub fn get_user_page(page: u64, hide_password: bool) -> Result<Vec<User>, rusqli
|
||||||
#[instrument()]
|
#[instrument()]
|
||||||
pub fn add_user(request: RegistrationRequet) -> Result<User, rusqlite::Error> {
|
pub fn add_user(request: RegistrationRequet) -> Result<User, rusqlite::Error> {
|
||||||
tracing::trace!("Adding new user");
|
tracing::trace!("Adding new user");
|
||||||
let date = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
|
let date = u64::try_from(SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO).as_millis()).unwrap_or(0);
|
||||||
|
|
||||||
let conn = database::connect()?;
|
let conn = database::connect()?;
|
||||||
let mut stmt = conn.prepare("INSERT INTO users (firstname, lastname, email, password, gender, date, day, month, year) VALUES(?,?,?,?,?,?,?,?,?) RETURNING *;")?;
|
let mut stmt = conn.prepare("INSERT INTO users (firstname, lastname, email, password, gender, date, day, month, year) VALUES(?,?,?,?,?,?,?,?,?) RETURNING *;")?;
|
||||||
|
|
30
src/main.rs
30
src/main.rs
|
@ -1,9 +1,9 @@
|
||||||
use std::net::SocketAddr;
|
use std::{net::SocketAddr, process::exit};
|
||||||
use axum::{Router, response::Response, http::{Request, StatusCode}, middleware::{Next, self}, extract::ConnectInfo, RequestExt, body::HttpBody, Extension};
|
use axum::{Router, response::Response, http::{Request, StatusCode}, middleware::{Next, self}, extract::ConnectInfo, RequestExt, body::HttpBody, Extension};
|
||||||
use tower_cookies::CookieManagerLayer;
|
use tower_cookies::CookieManagerLayer;
|
||||||
use tracing::metadata::LevelFilter;
|
use tracing::{metadata::LevelFilter, error, info};
|
||||||
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, Layer, filter::filter_fn};
|
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, Layer, filter::filter_fn};
|
||||||
use types::response::ResponseCode;
|
use types::http::ResponseCode;
|
||||||
|
|
||||||
use crate::{api::{pages, auth, users, posts}, types::extract::RouterURI};
|
use crate::{api::{pages, auth, users, posts}, types::extract::RouterURI};
|
||||||
|
|
||||||
|
@ -12,8 +12,11 @@ mod database;
|
||||||
mod types;
|
mod types;
|
||||||
mod console;
|
mod console;
|
||||||
|
|
||||||
async fn serve<B>(req: Request<B>, next: Next<B>) -> Response {
|
async fn serve<B>(req: Request<B>, next: Next<B>) -> Response where
|
||||||
let file = ResponseCode::Success.file(&req.uri().to_string()).await;
|
B: Send + Sync + 'static + HttpBody,
|
||||||
|
{
|
||||||
|
let uri = req.uri();
|
||||||
|
let file = ResponseCode::Success.file(&uri.to_string()).await;
|
||||||
if file.status() != StatusCode::OK {
|
if file.status() != StatusCode::OK {
|
||||||
return next.run(req).await;
|
return next.run(req).await;
|
||||||
}
|
}
|
||||||
|
@ -40,8 +43,6 @@ async fn not_found() -> Response {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
|
||||||
database::init().unwrap();
|
|
||||||
|
|
||||||
let fmt_layer = tracing_subscriber::fmt::layer();
|
let fmt_layer = tracing_subscriber::fmt::layer();
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(
|
.with(
|
||||||
|
@ -51,6 +52,11 @@ async fn main() {
|
||||||
)
|
)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
|
if database::init().is_err() {
|
||||||
|
error!("Failed to connect to the sqlite database");
|
||||||
|
exit(1)
|
||||||
|
};
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.fallback(not_found)
|
.fallback(not_found)
|
||||||
.nest("/", pages::router())
|
.nest("/", pages::router())
|
||||||
|
@ -64,12 +70,16 @@ async fn main() {
|
||||||
.layer(Extension(RouterURI("/api/posts")))
|
.layer(Extension(RouterURI("/api/posts")))
|
||||||
).layer(CookieManagerLayer::new());
|
).layer(CookieManagerLayer::new());
|
||||||
|
|
||||||
let addr = "[::]:8080".parse::<std::net::SocketAddr>().unwrap();
|
let Ok(addr) = "[::]:8080".parse::<std::net::SocketAddr>() else {
|
||||||
tracing::info!("listening on {}", addr);
|
error!("Failed to parse port binding");
|
||||||
|
exit(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
info!("listening on {}", addr);
|
||||||
|
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
|
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap_or(());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use axum::{extract::{FromRequestParts, FromRequest, ConnectInfo}, async_trait, r
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
use crate::{types::{user::User, response::{ResponseCode, Result}, session::Session}, console};
|
use crate::{types::{user::User, http::{ResponseCode, Result}, session::Session}, console};
|
||||||
|
|
||||||
pub struct AuthorizedUser(pub User);
|
pub struct AuthorizedUser(pub User);
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ impl<S> FromRequestParts<S> for AuthorizedUser where S: Send + Sync {
|
||||||
return Err(ResponseCode::InternalServerError.text("Valid token but no valid user"))
|
return Err(ResponseCode::InternalServerError.text("Valid token but no valid user"))
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(AuthorizedUser(user))
|
Ok(Self(user))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,25 +48,25 @@ impl<S, B> FromRequest<S, B> for Log where
|
||||||
async fn from_request(mut req: Request<B>, state: &S) -> Result<Self> {
|
async fn from_request(mut req: Request<B>, state: &S) -> Result<Self> {
|
||||||
|
|
||||||
let Ok(ConnectInfo(info)) = req.extract_parts::<ConnectInfo<SocketAddr>>().await else {
|
let Ok(ConnectInfo(info)) = req.extract_parts::<ConnectInfo<SocketAddr>>().await else {
|
||||||
return Ok(Log)
|
return Ok(Self)
|
||||||
};
|
};
|
||||||
let method = req.method().clone();
|
let method = req.method().clone();
|
||||||
let path = req.extensions().get::<RouterURI>().unwrap().0;
|
let path = req.extensions().get::<RouterURI>().map_or("", |path| path.0);
|
||||||
let uri = req.uri().clone();
|
let uri = req.uri().clone();
|
||||||
|
|
||||||
let Ok(bytes) = Bytes::from_request(req, state).await else {
|
let Ok(bytes) = Bytes::from_request(req, state).await else {
|
||||||
console::log(info.ip(), method.clone(), uri.clone(), Some(path.to_string()), None).await;
|
console::log(info.ip(), method.clone(), uri.clone(), Some(path.to_string()), None).await;
|
||||||
return Ok(Log)
|
return Ok(Self)
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(body) = String::from_utf8(bytes.bytes().flatten().collect()) else {
|
let Ok(body) = String::from_utf8(bytes.bytes().flatten().collect()) else {
|
||||||
console::log(info.ip(), method.clone(), uri.clone(), Some(path.to_string()), None).await;
|
console::log(info.ip(), method.clone(), uri.clone(), Some(path.to_string()), None).await;
|
||||||
return Ok(Log)
|
return Ok(Self)
|
||||||
};
|
};
|
||||||
|
|
||||||
console::log(info.ip(), method.clone(), uri.clone(), Some(path.to_string()), Some(body.to_string())).await;
|
console::log(info.ip(), method.clone(), uri.clone(), Some(path.to_string()), Some(body.to_string())).await;
|
||||||
|
|
||||||
Ok(Log)
|
Ok(Self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ impl<T, S, B> FromRequest<S, B> for Json<T> where
|
||||||
return Err(ResponseCode::InternalServerError.text("Failed to read connection info"));
|
return Err(ResponseCode::InternalServerError.text("Failed to read connection info"));
|
||||||
};
|
};
|
||||||
let method = req.method().clone();
|
let method = req.method().clone();
|
||||||
let path = req.extensions().get::<RouterURI>().unwrap().0;
|
let path = req.extensions().get::<RouterURI>().map_or("", |path| path.0);
|
||||||
let uri = req.uri().clone();
|
let uri = req.uri().clone();
|
||||||
|
|
||||||
let Ok(bytes) = Bytes::from_request(req, state).await else {
|
let Ok(bytes) = Bytes::from_request(req, state).await else {
|
||||||
|
@ -111,7 +111,7 @@ impl<T, S, B> FromRequest<S, B> for Json<T> where
|
||||||
return Err(ResponseCode::BadRequest.text(&msg));
|
return Err(ResponseCode::BadRequest.text(&msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Json(value))
|
Ok(Self(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub enum ResponseCode {
|
||||||
|
|
||||||
impl ResponseCode {
|
impl ResponseCode {
|
||||||
|
|
||||||
pub fn code(self) -> StatusCode {
|
const fn code(self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
Self::Success => StatusCode::OK,
|
Self::Success => StatusCode::OK,
|
||||||
Self::Created => StatusCode::CREATED,
|
Self::Created => StatusCode::CREATED,
|
||||||
|
@ -56,16 +56,16 @@ impl ResponseCode {
|
||||||
#[instrument()]
|
#[instrument()]
|
||||||
pub async fn file(self, path: &str) -> Response {
|
pub async fn file(self, path: &str) -> Response {
|
||||||
if !path.chars().any(|c| c == '.' ) {
|
if !path.chars().any(|c| c == '.' ) {
|
||||||
return ResponseCode::BadRequest.text("Folders cannot be served");
|
return Self::BadRequest.text("Folders cannot be served");
|
||||||
}
|
}
|
||||||
let path = format!("public{}", path);
|
let path = format!("public{path}");
|
||||||
let svc = ServeFile::new(path);
|
let svc = ServeFile::new(path);
|
||||||
let Ok(mut res) = svc.oneshot(Request::new(Body::empty())).await else {
|
let Ok(mut res) = svc.oneshot(Request::new(Body::empty())).await else {
|
||||||
tracing::error!("Error while fetching file");
|
tracing::error!("Error while fetching file");
|
||||||
return ResponseCode::InternalServerError.text("Error while fetching file");
|
return Self::InternalServerError.text("Error while fetching file");
|
||||||
};
|
};
|
||||||
if res.status() != StatusCode::OK {
|
if res.status() != StatusCode::OK {
|
||||||
return ResponseCode::NotFound.text("File not found");
|
return Self::NotFound.text("File not found");
|
||||||
}
|
}
|
||||||
*res.status_mut() = self.code();
|
*res.status_mut() = self.code();
|
||||||
res.into_response()
|
res.into_response()
|
|
@ -2,4 +2,4 @@ pub mod user;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod session;
|
pub mod session;
|
||||||
pub mod extract;
|
pub mod extract;
|
||||||
pub mod response;
|
pub mod http;
|
|
@ -4,7 +4,7 @@ use serde::Serialize;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::database;
|
use crate::database;
|
||||||
use crate::types::response::{Result, ResponseCode};
|
use crate::types::http::{Result, ResponseCode};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Post {
|
pub struct Post {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use serde::Serialize;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::database;
|
use crate::database;
|
||||||
use crate::types::response::{Result, ResponseCode};
|
use crate::types::http::{Result, ResponseCode};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
|
@ -27,7 +27,7 @@ impl Session {
|
||||||
let token: String = rand::thread_rng().sample_iter(&Alphanumeric).take(32).map(char::from).collect();
|
let token: String = rand::thread_rng().sample_iter(&Alphanumeric).take(32).map(char::from).collect();
|
||||||
match database::sessions::set_session(user_id, &token) {
|
match database::sessions::set_session(user_id, &token) {
|
||||||
Err(_) => Err(ResponseCode::BadRequest.text("Failed to create session")),
|
Err(_) => Err(ResponseCode::BadRequest.text("Failed to create session")),
|
||||||
Ok(_) => Ok(Session {user_id, token})
|
Ok(_) => Ok(Self {user_id, token})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use tracing::instrument;
|
||||||
|
|
||||||
use crate::api::auth::RegistrationRequet;
|
use crate::api::auth::RegistrationRequet;
|
||||||
use crate::database;
|
use crate::database;
|
||||||
use crate::types::response::{Result, ResponseCode};
|
use crate::types::http::{Result, ResponseCode};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
@ -69,11 +69,11 @@ impl User {
|
||||||
|
|
||||||
#[instrument()]
|
#[instrument()]
|
||||||
pub fn new(request: RegistrationRequet) -> Result<Self> {
|
pub fn new(request: RegistrationRequet) -> Result<Self> {
|
||||||
if User::from_email(&request.email).is_ok() {
|
if Self::from_email(&request.email).is_ok() {
|
||||||
return Err(ResponseCode::BadRequest.text(&format!("Email is already in use by {}", &request.email)))
|
return Err(ResponseCode::BadRequest.text(&format!("Email is already in use by {}", &request.email)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(user) = User::from_password(&request.password) {
|
if let Ok(user) = Self::from_password(&request.password) {
|
||||||
return Err(ResponseCode::BadRequest.text(&format!("Password is already in use by {}", user.email)))
|
return Err(ResponseCode::BadRequest.text(&format!("Password is already in use by {}", user.email)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue