Code improvements

This commit is contained in:
Timo Ley 2022-01-10 14:37:27 +01:00
parent 5aeb937e6c
commit b191626ad9
6 changed files with 28 additions and 30 deletions

View file

@ -12,9 +12,9 @@ use crate::ipfs::error::IPFSError;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum CDNError { pub enum CDNError {
#[error("SQL error: {0}")] #[error("SQL error: {0}")]
SQL(#[from] sqlx::Error), Sql(#[from] sqlx::Error),
#[error("IPFS error: {0}")] #[error("IPFS error: {0}")]
IPFS(#[from] IPFSError), Ipfs(#[from] IPFSError),
#[error("Decode error: {0}")] #[error("Decode error: {0}")]
Decode(#[from] FromUtf8Error), Decode(#[from] FromUtf8Error),
#[error("Internal server error")] #[error("Internal server error")]
@ -28,10 +28,7 @@ impl IntoResponse for CDNError {
fn into_response(self) -> axum::http::Response<Self::Body> { fn into_response(self) -> axum::http::Response<Self::Body> {
let status = match self { let status = match self {
CDNError::SQL(err) => match err { CDNError::Sql(sqlx::Error::RowNotFound) => StatusCode::NOT_FOUND,
sqlx::Error::RowNotFound => StatusCode::NOT_FOUND,
_ => StatusCode::INTERNAL_SERVER_ERROR,
},
_ => StatusCode::INTERNAL_SERVER_ERROR, _ => StatusCode::INTERNAL_SERVER_ERROR,
}; };
status.into_response() status.into_response()

View file

@ -6,5 +6,5 @@ pub enum IPFSError {
#[error("Reqwest error: {0}")] #[error("Reqwest error: {0}")]
Reqwest(#[from] reqwest::Error), Reqwest(#[from] reqwest::Error),
#[error("URL parse error: {0}")] #[error("URL parse error: {0}")]
URL(#[from] ParseError), Url(#[from] ParseError),
} }

View file

@ -18,7 +18,8 @@ where
let header = req let header = req
.headers() .headers()
.and_then(|headers| headers.get("x-forwarded-for")); .and_then(|headers| headers.get("x-forwarded-for"));
let header = header.ok_or(ExtractError::HeaderMissing("X-Forwarded-For".to_string()))?; let header =
header.ok_or_else(|| ExtractError::HeaderMissing("X-Forwarded-For".to_string()))?;
let mut value = header.to_str()?; let mut value = header.to_str()?;
let pos = value.chars().position(|r| r == ','); let pos = value.chars().position(|r| r == ',');
value = match pos { value = match pos {

View file

@ -27,7 +27,7 @@ pub enum APIError {
#[error("{0}")] #[error("{0}")]
Internal(String), Internal(String),
#[error("IPFS error: {0}")] #[error("IPFS error: {0}")]
IPFS(#[from] IPFSError), Ipfs(#[from] IPFSError),
} }
impl ErrorResponse { impl ErrorResponse {
@ -35,7 +35,7 @@ impl ErrorResponse {
let reason = status.canonical_reason().unwrap_or_default(); let reason = status.canonical_reason().unwrap_or_default();
Self { Self {
status, status,
error: message.unwrap_or(reason.to_string()), error: message.unwrap_or_else(|| reason.to_string()),
} }
} }
} }
@ -58,9 +58,9 @@ impl IntoResponse for APIError {
APIError::Internal(err) => { APIError::Internal(err) => {
ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, Some(err)) ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, Some(err))
} }
APIError::IPFS(_) => ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, None), APIError::Ipfs(_) => ErrorResponse::new(StatusCode::INTERNAL_SERVER_ERROR, None),
}; };
let status = res.status.clone(); let status = res.status;
(status, Json(res)).into_response() (status, Json(res)).into_response()
} }
} }

View file

@ -109,17 +109,17 @@ async fn upload(
let ipfs = vars.ipfs_client()?; let ipfs = vars.ipfs_client()?;
while let Some(field) = form.next_field().await? { while let Some(field) = form.next_field().await? {
match field.name().ok_or(APIError::BadRequest( match field.name().ok_or_else(|| {
"A multipart-form field is missing a name".to_string(), APIError::BadRequest("A multipart-form field is missing a name".to_string())
))? { })? {
"token" => token = Some(field.text().await?), "token" => token = Some(field.text().await?),
"category" => category = Some(field.text().await?), "category" => category = Some(field.text().await?),
"file" | "file[]" => { "file" | "file[]" => {
let filename = field let filename = field
.file_name() .file_name()
.ok_or(APIError::BadRequest( .ok_or_else(|| {
"A file field has no filename".to_string(), APIError::BadRequest("A file field has no filename".to_string())
))? })?
.to_string(); .to_string();
let file = ipfs.add(field.bytes().await?, filename).await?; let file = ipfs.add(field.bytes().await?, filename).await?;
files.push(file); files.push(file);
@ -128,11 +128,11 @@ async fn upload(
} }
} }
let token = token.ok_or(APIError::Unauthorized("Missing token".to_string()))?; let token = token.ok_or_else(|| APIError::Unauthorized("Missing token".to_string()))?;
let category = category.ok_or(APIError::BadRequest("Missing category".to_string()))?; let category = category.ok_or_else(|| APIError::BadRequest("Missing category".to_string()))?;
let user = User::check_token(token, &db_pool) let user = User::check_token(token, &db_pool)
.await? .await?
.ok_or(APIError::Forbidden("token not existing".to_string()))?; .ok_or_else(|| APIError::Forbidden("token not existing".to_string()))?;
let total = (user.dayuploads as isize) + (files.len() as isize); let total = (user.dayuploads as isize) + (files.len() as isize);
if total > 20 { if total > 20 {

View file

@ -46,9 +46,9 @@ impl Meme {
cdn: String, cdn: String,
) -> Result<Vec<Self>> { ) -> Result<Vec<Self>> {
let q: Vec<Meme> = sqlx::query("SELECT memes.id, user, filename, category, name, UNIX_TIMESTAMP(timestamp) AS ts, cid FROM memes, users WHERE memes.user = users.id AND (category LIKE ? AND name LIKE ? AND filename LIKE ?) ORDER BY memes.id") let q: Vec<Meme> = sqlx::query("SELECT memes.id, user, filename, category, name, UNIX_TIMESTAMP(timestamp) AS ts, cid FROM memes, users WHERE memes.user = users.id AND (category LIKE ? AND name LIKE ? AND filename LIKE ?) ORDER BY memes.id")
.bind(params.category.unwrap_or(String::from("%"))) .bind(params.category.unwrap_or_else(|| String::from("%")))
.bind(format!("%{}%", params.user.unwrap_or(String::from("")))) .bind(format!("%{}%", params.user.unwrap_or_else(String::new)))
.bind(format!("%{}%", params.search.unwrap_or(String::from("")))) .bind(format!("%{}%", params.search.unwrap_or_else(String::new)))
.map(|row: MySqlRow| Self::new(DBMeme { .map(|row: MySqlRow| Self::new(DBMeme {
id: row.get("id"), id: row.get("id"),
filename: row.get("filename"), filename: row.get("filename"),
@ -68,9 +68,9 @@ impl Meme {
cdn: String, cdn: String,
) -> Result<Self> { ) -> Result<Self> {
let q: Meme = sqlx::query("SELECT memes.id, user, filename, category, name, UNIX_TIMESTAMP(timestamp) AS ts, cid FROM memes, users WHERE memes.user = users.id AND (category LIKE ? AND name LIKE ? AND filename LIKE ?) ORDER BY RAND() LIMIT 1") let q: Meme = sqlx::query("SELECT memes.id, user, filename, category, name, UNIX_TIMESTAMP(timestamp) AS ts, cid FROM memes, users WHERE memes.user = users.id AND (category LIKE ? AND name LIKE ? AND filename LIKE ?) ORDER BY RAND() LIMIT 1")
.bind(params.category.unwrap_or(String::from("%"))) .bind(params.category.unwrap_or_else(|| String::from("%")))
.bind(format!("%{}%", params.user.unwrap_or(String::from("")))) .bind(format!("%{}%", params.user.unwrap_or_else(String::new)))
.bind(format!("%{}%", params.search.unwrap_or(String::from("")))) .bind(format!("%{}%", params.search.unwrap_or_else(String::new)))
.map(|row: MySqlRow| Self::new(DBMeme { .map(|row: MySqlRow| Self::new(DBMeme {
id: row.get("id"), id: row.get("id"),
filename: row.get("filename"), filename: row.get("filename"),
@ -130,9 +130,9 @@ impl Category {
impl User { impl User {
pub async fn get(params: UserIDQuery, pool: &MySqlPool) -> Result<Self> { pub async fn get(params: UserIDQuery, pool: &MySqlPool) -> Result<Self> {
let q: User = sqlx::query("SELECT id, name, MD5(token) AS hash, uploads FROM (SELECT id, name, IFNULL(count.uploads, 0) AS uploads FROM users LEFT JOIN (SELECT user, COUNT(*) AS uploads FROM memes WHERE DATE(timestamp) = CURDATE() GROUP BY (user)) AS count ON users.id = count.user) AS users, token WHERE users.id = token.uid AND (users.id LIKE ? OR token LIKE ? OR name LIKE ?) UNION SELECT id, name, 0 AS hash, 0 AS uploads FROM users WHERE id = '000'") let q: User = sqlx::query("SELECT id, name, MD5(token) AS hash, uploads FROM (SELECT id, name, IFNULL(count.uploads, 0) AS uploads FROM users LEFT JOIN (SELECT user, COUNT(*) AS uploads FROM memes WHERE DATE(timestamp) = CURDATE() GROUP BY (user)) AS count ON users.id = count.user) AS users, token WHERE users.id = token.uid AND (users.id LIKE ? OR token LIKE ? OR name LIKE ?) UNION SELECT id, name, 0 AS hash, 0 AS uploads FROM users WHERE id = '000'")
.bind(params.id.unwrap_or(String::from(""))) .bind(params.id.unwrap_or_else(String::new))
.bind(params.token.unwrap_or(String::from(""))) .bind(params.token.unwrap_or_else(String::new))
.bind(params.name.unwrap_or(String::from(""))) .bind(params.name.unwrap_or_else(String::new))
.map(|row: MySqlRow| Self { .map(|row: MySqlRow| Self {
id: row.get("id"), id: row.get("id"),
name: row.get("name"), name: row.get("name"),