Misc v3 linear tasks (#767)

* v3_reroute 404 error

* hash change

* fixed issue with error conversion

* added new model confirmation tests
+ title name change

* renaming, fields

* owner; test changes

* clippy prepare

* fmt

* merge fixes

* clippy

* working merge

* revs

* merge fixes
This commit is contained in:
Wyatt Verchere
2023-12-01 19:15:00 -08:00
committed by GitHub
parent 2d92b08404
commit a70df067bc
119 changed files with 2897 additions and 1334 deletions

View File

@@ -52,8 +52,12 @@ pub async fn get_version_from_hash(
.map(|x| x.1)
.ok();
let hash = info.into_inner().0.to_lowercase();
let algorithm = hash_query
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&[hash.clone()]));
let file = database::models::Version::get_file_from_hash(
hash_query.algorithm.clone(),
algorithm,
hash,
hash_query.version_id.map(|x| x.into()),
&**pool,
@@ -64,26 +68,36 @@ pub async fn get_version_from_hash(
let version = database::models::Version::get(file.version_id, &**pool, &redis).await?;
if let Some(version) = version {
if !is_authorized_version(&version.inner, &user_option, &pool).await? {
return Ok(HttpResponse::NotFound().body(""));
return Err(ApiError::NotFound);
}
Ok(HttpResponse::Ok().json(models::projects::Version::from(version)))
} else {
Ok(HttpResponse::NotFound().body(""))
Err(ApiError::NotFound)
}
} else {
Ok(HttpResponse::NotFound().body(""))
Err(ApiError::NotFound)
}
}
#[derive(Serialize, Deserialize)]
pub struct HashQuery {
#[serde(default = "default_algorithm")]
pub algorithm: String,
pub algorithm: Option<String>, // Defaults to calculation based on size of hash
pub version_id: Option<VersionId>,
}
pub fn default_algorithm() -> String {
// Calculates whether or not to use sha1 or sha512 based on the size of the hash
pub fn default_algorithm_from_hashes(hashes: &[String]) -> String {
// Gets first hash, optionally
let empty_string = "".into();
let hash = hashes.first().unwrap_or(&empty_string);
let hash_len = hash.len();
// Sha1 = 40 characters
// Sha512 = 128 characters
// Favour sha1 as default, unless the hash is longer or equal to 128 characters
if hash_len >= 128 {
return "sha512".into();
}
"sha1".into()
}
@@ -122,7 +136,10 @@ pub async fn get_update_from_hash(
let hash = info.into_inner().0.to_lowercase();
if let Some(file) = database::models::Version::get_file_from_hash(
hash_query.algorithm.clone(),
hash_query
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&[hash.clone()])),
hash,
hash_query.version_id.map(|x| x.into()),
&**pool,
@@ -163,7 +180,7 @@ pub async fn get_update_from_hash(
if let Some(first) = versions.last() {
if !is_authorized_version(&first.inner, &user_option, &pool).await? {
return Ok(HttpResponse::NotFound().body(""));
return Err(ApiError::NotFound);
}
return Ok(HttpResponse::Ok().json(models::projects::Version::from(first)));
@@ -171,14 +188,13 @@ pub async fn get_update_from_hash(
}
}
Ok(HttpResponse::NotFound().body(""))
Err(ApiError::NotFound)
}
// Requests above with multiple versions below
#[derive(Deserialize)]
pub struct FileHashes {
#[serde(default = "default_algorithm")]
pub algorithm: String,
pub algorithm: Option<String>, // Defaults to calculation based on size of hash
pub hashes: Vec<String>,
}
@@ -200,8 +216,13 @@ pub async fn get_versions_from_hashes(
.map(|x| x.1)
.ok();
let algorithm = file_data
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&file_data.hashes));
let files = database::models::Version::get_files_from_hash(
file_data.algorithm.clone(),
algorithm.clone(),
&file_data.hashes,
&**pool,
&redis,
@@ -220,7 +241,7 @@ pub async fn get_versions_from_hashes(
for version in versions_data {
for file in files.iter().filter(|x| x.version_id == version.id.into()) {
if let Some(hash) = file.hashes.get(&file_data.algorithm) {
if let Some(hash) = file.hashes.get(&algorithm) {
response.insert(hash.clone(), version.clone());
}
}
@@ -247,8 +268,12 @@ pub async fn get_projects_from_hashes(
.map(|x| x.1)
.ok();
let algorithm = file_data
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&file_data.hashes));
let files = database::models::Version::get_files_from_hash(
file_data.algorithm.clone(),
algorithm.clone(),
&file_data.hashes,
&**pool,
&redis,
@@ -268,7 +293,7 @@ pub async fn get_projects_from_hashes(
for project in projects_data {
for file in files.iter().filter(|x| x.project_id == project.id.into()) {
if let Some(hash) = file.hashes.get(&file_data.algorithm) {
if let Some(hash) = file.hashes.get(&algorithm) {
response.insert(hash.clone(), project.clone());
}
}
@@ -279,8 +304,7 @@ pub async fn get_projects_from_hashes(
#[derive(Deserialize)]
pub struct ManyUpdateData {
#[serde(default = "default_algorithm")]
pub algorithm: String,
pub algorithm: Option<String>, // Defaults to calculation based on size of hash
pub hashes: Vec<String>,
pub loaders: Option<Vec<String>>,
pub loader_fields: Option<HashMap<String, Vec<serde_json::Value>>>,
@@ -304,8 +328,12 @@ pub async fn update_files(
.map(|x| x.1)
.ok();
let algorithm = update_data
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&update_data.hashes));
let files = database::models::Version::get_files_from_hash(
update_data.algorithm.clone(),
algorithm.clone(),
&update_data.hashes,
&**pool,
&redis,
@@ -366,7 +394,7 @@ pub async fn update_files(
if let Some(version) = version {
if is_authorized_version(&version.inner, &user_option, &pool).await? {
if let Some(hash) = file.hashes.get(&update_data.algorithm) {
if let Some(hash) = file.hashes.get(&algorithm) {
response.insert(
hash.clone(),
models::projects::Version::from(version.clone()),
@@ -390,8 +418,7 @@ pub struct FileUpdateData {
#[derive(Serialize, Deserialize)]
pub struct ManyFileUpdateData {
#[serde(default = "default_algorithm")]
pub algorithm: String,
pub algorithm: Option<String>, // Defaults to calculation based on size of hash
pub hashes: Vec<FileUpdateData>,
}
@@ -413,8 +440,17 @@ pub async fn update_individual_files(
.map(|x| x.1)
.ok();
let algorithm = update_data.algorithm.clone().unwrap_or_else(|| {
default_algorithm_from_hashes(
&update_data
.hashes
.iter()
.map(|x| x.hash.clone())
.collect::<Vec<_>>(),
)
});
let files = database::models::Version::get_files_from_hash(
update_data.algorithm.clone(),
algorithm.clone(),
&update_data
.hashes
.iter()
@@ -445,7 +481,7 @@ pub async fn update_individual_files(
for project in projects {
for file in files.iter().filter(|x| x.project_id == project.inner.id) {
if let Some(hash) = file.hashes.get(&update_data.algorithm) {
if let Some(hash) = file.hashes.get(&algorithm) {
if let Some(query_file) = update_data.hashes.iter().find(|x| &x.hash == hash) {
let version = all_versions
.iter()
@@ -514,9 +550,12 @@ pub async fn delete_file(
.1;
let hash = info.into_inner().0.to_lowercase();
let algorithm = hash_query
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&[hash.clone()]));
let file = database::models::Version::get_file_from_hash(
hash_query.algorithm.clone(),
algorithm.clone(),
hash,
hash_query.version_id.map(|x| x.into()),
&**pool,
@@ -605,7 +644,7 @@ pub async fn delete_file(
Ok(HttpResponse::NoContent().body(""))
} else {
Ok(HttpResponse::NotFound().body(""))
Err(ApiError::NotFound)
}
}
@@ -635,8 +674,12 @@ pub async fn download_version(
.ok();
let hash = info.into_inner().0.to_lowercase();
let algorithm = hash_query
.algorithm
.clone()
.unwrap_or_else(|| default_algorithm_from_hashes(&[hash.clone()]));
let file = database::models::Version::get_file_from_hash(
hash_query.algorithm.clone(),
algorithm.clone(),
hash,
hash_query.version_id.map(|x| x.into()),
&**pool,
@@ -649,16 +692,16 @@ pub async fn download_version(
if let Some(version) = version {
if !is_authorized_version(&version.inner, &user_option, &pool).await? {
return Ok(HttpResponse::NotFound().body(""));
return Err(ApiError::NotFound);
}
Ok(HttpResponse::TemporaryRedirect()
.append_header(("Location", &*file.url))
.json(DownloadRedirect { url: file.url }))
} else {
Ok(HttpResponse::NotFound().body(""))
Err(ApiError::NotFound)
}
} else {
Ok(HttpResponse::NotFound().body(""))
Err(ApiError::NotFound)
}
}