Fix rejected files showing in hash routes (#375)

* Fix rejected files showing in hash routes

* Run prepare and formatter

* Add modrinth.com exception for callback URLs

* run fmt
This commit is contained in:
Geometrically
2022-06-18 14:09:37 -07:00
committed by GitHub
parent 782bb11894
commit cd514285d9
8 changed files with 237 additions and 181 deletions

View File

@@ -118,8 +118,8 @@ impl Notification {
id: NotificationId,
executor: E,
) -> Result<Option<Self>, sqlx::error::Error>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
where
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
{
let result = sqlx::query!(
"
@@ -138,19 +138,24 @@ impl Notification {
if let Some(row) = result {
let mut actions: Vec<NotificationAction> = Vec::new();
row.actions.unwrap_or_default().split(" ~~~~ ").for_each(|x| {
let action: Vec<&str> = x.split(" |||| ").collect();
row.actions
.unwrap_or_default()
.split(" ~~~~ ")
.for_each(|x| {
let action: Vec<&str> = x.split(" |||| ").collect();
if action.len() >= 3 {
actions.push(NotificationAction {
id: NotificationActionId(action[0].parse().unwrap_or(0)),
notification_id: id,
title: action[1].to_string(),
action_route_method: action[3].to_string(),
action_route: action[2].to_string(),
});
}
});
if action.len() >= 3 {
actions.push(NotificationAction {
id: NotificationActionId(
action[0].parse().unwrap_or(0),
),
notification_id: id,
title: action[1].to_string(),
action_route_method: action[3].to_string(),
action_route: action[2].to_string(),
});
}
});
Ok(Some(Notification {
id,
@@ -172,12 +177,13 @@ impl Notification {
notification_ids: Vec<NotificationId>,
exec: E,
) -> Result<Vec<Notification>, sqlx::Error>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{
use futures::stream::TryStreamExt;
let notification_ids_parsed: Vec<i64> = notification_ids.into_iter().map(|x| x.0).collect();
let notification_ids_parsed: Vec<i64> =
notification_ids.into_iter().map(|x| x.0).collect();
sqlx::query!(
"
SELECT n.id, n.user_id, n.title, n.text, n.link, n.created, n.read, n.type notification_type,
@@ -231,8 +237,8 @@ impl Notification {
user_id: UserId,
exec: E,
) -> Result<Vec<Notification>, sqlx::Error>
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
where
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
{
use futures::stream::TryStreamExt;

View File

@@ -1,4 +1,4 @@
/*!
/*!
This auth module is primarily for use within the main website. Applications interacting with the
authenticated API (a very small portion - notifications, private projects, editing/creating projects
and versions) should either retrieve the Modrinth GitHub token through the site, or create a personal
@@ -16,6 +16,7 @@ use crate::models::error::ApiError;
use crate::models::ids::base62_impl::{parse_base62, to_base62};
use crate::models::ids::DecodingError;
use crate::models::users::Role;
use crate::parse_strings_from_var;
use crate::util::auth::get_github_user_from_token;
use actix_web::http::StatusCode;
use actix_web::web::{scope, Data, Query, ServiceConfig};
@@ -24,7 +25,6 @@ use serde::{Deserialize, Serialize};
use sqlx::postgres::PgPool;
use thiserror::Error;
use time::OffsetDateTime;
use crate::parse_strings_from_var;
pub fn config(cfg: &mut ServiceConfig) {
cfg.service(scope("auth").service(auth_callback).service(init));
@@ -82,7 +82,7 @@ impl actix_web::ResponseError for AuthorizationError {
AuthorizationError::Decoding(..) => "decoding_error",
AuthorizationError::Authentication(..) => {
"authentication_error"
},
}
AuthorizationError::Url => "url_error",
},
description: &self.to_string(),
@@ -114,13 +114,16 @@ pub async fn init(
Query(info): Query<AuthorizationInit>,
client: Data<PgPool>,
) -> Result<HttpResponse, AuthorizationError> {
let url = url::Url::parse(&info.url).map_err(|_| AuthorizationError::Url)?;
let url =
url::Url::parse(&info.url).map_err(|_| AuthorizationError::Url)?;
let allowed_callback_urls = parse_strings_from_var("ALLOWED_CALLBACK_URLS")
.unwrap_or_default();
let allowed_callback_urls =
parse_strings_from_var("ALLOWED_CALLBACK_URLS").unwrap_or_default();
let domain = url.domain().ok_or(AuthorizationError::Url)?;
if !allowed_callback_urls.iter().any(|x| domain.ends_with(x)) {
if !allowed_callback_urls.iter().any(|x| domain.ends_with(x))
|| domain == "modrinth.com"
{
return Err(AuthorizationError::Url);
}

View File

@@ -34,12 +34,17 @@ pub async fn get_version_from_hash(
let result = sqlx::query!(
"
SELECT f.version_id version_id FROM hashes h
SELECT f.version_id version_id
FROM hashes h
INNER JOIN files f ON h.file_id = f.id
WHERE h.algorithm = $2 AND h.hash = $1
INNER JOIN versions v on f.version_id = v.id
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3
",
hash.as_bytes(),
algorithm.algorithm
algorithm.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
)
.fetch_optional(&**pool)
.await?;
@@ -81,10 +86,13 @@ pub async fn download_version(
SELECT f.url url, f.id id, f.version_id version_id, v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = $1
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3
",
hash.as_bytes(),
algorithm.algorithm
algorithm.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
)
.fetch_optional(&mut *transaction)
.await?;
@@ -242,10 +250,13 @@ pub async fn get_update_from_hash(
SELECT v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = $1
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = $1 AND s.status != $3
",
hash.as_bytes(),
algorithm.algorithm
algorithm.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
)
.fetch_optional(&**pool)
.await?;
@@ -310,10 +321,14 @@ pub async fn get_versions_from_hashes(
"
SELECT h.hash hash, h.algorithm algorithm, f.version_id version_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[])
INNER JOIN versions v ON v.id = f.version_id
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3
",
hashes_parsed.as_slice(),
file_data.algorithm
file_data.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
)
.fetch_all(&**pool)
.await?;
@@ -370,10 +385,13 @@ pub async fn download_files(
SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[])
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3
",
hashes_parsed.as_slice(),
file_data.algorithm
file_data.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
)
.fetch_all(&mut *transaction)
.await?;
@@ -421,10 +439,13 @@ pub async fn update_files(
SELECT f.url url, h.hash hash, h.algorithm algorithm, f.version_id version_id, v.mod_id project_id FROM hashes h
INNER JOIN files f ON h.file_id = f.id
INNER JOIN versions v ON v.id = f.version_id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[])
INNER JOIN mods m on v.mod_id = m.id
INNER JOIN statuses s on m.status = s.id
WHERE h.algorithm = $2 AND h.hash = ANY($1::bytea[]) AND s.status != $3
",
hashes_parsed.as_slice(),
update_data.algorithm
update_data.algorithm,
models::projects::ProjectStatus::Rejected.to_string()
)
.fetch_all(&mut *transaction)
.await?;

View File

@@ -14,7 +14,7 @@ pub enum AuthenticationError {
#[error("An unknown database error occurred")]
Sqlx(#[from] sqlx::Error),
#[error("Database Error: {0}")]
Database(#[from] crate::database::models::DatabaseError),
Database(#[from] models::DatabaseError),
#[error("Error while parsing JSON: {0}")]
SerDe(#[from] serde_json::Error),
#[error("Error while communicating to GitHub OAuth2: {0}")]