From c8c69b44250f22f0db5c129d81e4ac81db8fb942 Mon Sep 17 00:00:00 2001 From: Danielle Hutzley Date: Tue, 14 Dec 2021 08:00:06 -0800 Subject: [PATCH] Add mod URL download support --- theseus/src/modpack/mod.rs | 3 +++ theseus/src/modpack/pack.rs | 38 +++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/theseus/src/modpack/mod.rs b/theseus/src/modpack/mod.rs index 8c3ad45da..ba5d86ed3 100644 --- a/theseus/src/modpack/mod.rs +++ b/theseus/src/modpack/mod.rs @@ -59,6 +59,9 @@ pub enum ModpackError { #[error("Error downloading file: {0}")] FetchError(#[from] reqwest::Error), + + #[error("Invalid modpack source: {0} (set the WHITELISTED_MODPACK_DOMAINS environment variable to override)")] + SourceWhitelistError(String), } type ModpackResult = Result; diff --git a/theseus/src/modpack/pack.rs b/theseus/src/modpack/pack.rs index b8e726a7c..09079183d 100644 --- a/theseus/src/modpack/pack.rs +++ b/theseus/src/modpack/pack.rs @@ -10,10 +10,18 @@ use tokio::fs; use super::{ modrinth_api::{self, ModrinthV1}, - ModpackResult, + ModpackResult, ModpackError, }; use crate::launcher::ModLoader; +pub const MODRINTH_DEFAULT_MODPACK_DOMAINS: &'static [&'static str] = &[ + "cdn.modrinth.com", + "edge.forgecdn.net", + "github.com", + "raw.githubusercontent.com", +]; +pub const MODRINTH_MODPACK_DOMAIN_WHITELIST_VAR: &'static str = "WHITELISTED_MODPACK_DOMAINS"; + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct Modpack { pub game: ModpackGame, @@ -95,6 +103,32 @@ impl Modpack { self.files.extend(files); Ok(()) } + + pub async fn add_file(&mut self, source: reqwest::Url, dest: &Path, hashes: Option, env: Option) -> ModpackResult<()> { + let whitelisted_domains = std::env::var(MODRINTH_MODPACK_DOMAIN_WHITELIST_VAR) + .map(|it| serde_json::from_str::>(&it).ok().unwrap()) + .unwrap_or( + MODRINTH_DEFAULT_MODPACK_DOMAINS + .iter() + .cloned() + .map(String::from) + .collect::>(), + ); + + if (whitelisted_domains.iter().find(String::from(source.host_str().unwrap())).is_none()) { + return Err(ModpackError::SourceWhitelistError(String::from(source.host_str().unwrap()))); + } + + let file = ModpackFile { + path: dest, + hashes, + env: env.unwrap_or(ModpackEnv::Both), + downloads: HashSet::from([String::from(source)]) + }; + + self.files.insert(file); + Ok(()) + } } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] @@ -107,7 +141,7 @@ pub enum ModpackGame { #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct ModpackFile { pub path: PathBuf, - pub hashes: ModpackFileHashes, + pub hashes: Option, pub env: ModpackEnv, pub downloads: HashSet, }