diff --git a/src/main.rs b/src/main.rs index 6218e71..cc59337 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,6 +79,12 @@ fn main() { .required(false) .takes_value(false) .help("Install packages avoiding the GIT package provider. Try this flag if the default mode is not working.")) + .arg(Arg::with_name("external") + .short("e") + .long("external") + .required(false) + .takes_value(false) + .help("Allow installing packages from non-verified repositories.")) .arg(Arg::with_name("package_name") .help("Package name")); @@ -766,6 +772,13 @@ fn install_main(_config_set: ConfigSet, matches: &ArgMatches) { Box::new(GitPackageResolver::new()) }; + let allow_external: bool = if matches.is_present("external") { + println!("Allowing external repositories"); + true + }else{ + false + }; + let mut package_manager = DefaultPackageManager::new_default(Some(package_resolver)); if package_manager.is_index_outdated() { @@ -792,7 +805,7 @@ fn install_main(_config_set: ConfigSet, matches: &ArgMatches) { println!("Using cached package index, run 'espanso package refresh' to update it.") } - let res = package_manager.install_package(package_name); + let res = package_manager.install_package(package_name, allow_external); match res { Ok(install_result) => { @@ -812,6 +825,22 @@ fn install_main(_config_set: ConfigSet, matches: &ArgMatches) { InstallResult::AlreadyInstalled => { eprintln!("{} already installed!", package_name); }, + InstallResult::BlockedExternalPackage(repo_url) => { + eprintln!("Warning: the requested package is hosted on an external repository:"); + eprintln!(); + eprintln!("{}", repo_url); + eprintln!(); + eprintln!("and its contents may not have been verified by espanso."); + eprintln!(); + eprintln!("For your security, espanso blocks packages that are not verified."); + eprintln!("If you want to install the package anyway, you can force espanso"); + eprintln!("to install it with the following command, but please do it only"); + eprintln!("if you trust the source or you verified the contents of the package"); + eprintln!("by checking out the repository listed above."); + eprintln!(); + eprintln!("espanso install {} --external", package_name); + eprintln!(); + } InstallResult::Installed => { println!("{} successfully installed!", package_name); println!(); diff --git a/src/package/default.rs b/src/package/default.rs index d3bbd7f..10cebfa 100644 --- a/src/package/default.rs +++ b/src/package/default.rs @@ -24,7 +24,7 @@ use std::fs::{File, create_dir}; use std::io::{BufReader, BufRead}; use std::time::{SystemTime, UNIX_EPOCH}; use crate::package::UpdateResult::{NotOutdated, Updated}; -use crate::package::InstallResult::{NotFoundInIndex, AlreadyInstalled}; +use crate::package::InstallResult::{NotFoundInIndex, AlreadyInstalled, BlockedExternalPackage}; use std::fs; use tempfile::TempDir; use git2::Repository; @@ -138,13 +138,31 @@ impl DefaultPackageManager { return None } + let original_repo = if fields.contains_key("package_original_repo") { + fields.get("package_original_repo").unwrap().clone() + }else{ + fields.get("package_repo").unwrap().clone() + }; + + let is_core = if fields.contains_key("is_core") { + match fields.get("is_core").unwrap().clone().as_ref() { + "true" => true, + "false" => false, + _ => false, + } + }else{ + false + }; + let package = Package { name: fields.get("package_name").unwrap().clone(), title: fields.get("package_title").unwrap().clone(), version: fields.get("package_version").unwrap().clone(), repo: fields.get("package_repo").unwrap().clone(), desc: fields.get("package_desc").unwrap().clone(), - author: fields.get("package_author").unwrap().clone() + author: fields.get("package_author").unwrap().clone(), + is_core, + original_repo }; Some(package) @@ -228,11 +246,15 @@ impl super::PackageManager for DefaultPackageManager { None } - fn install_package(&self, name: &str) -> Result> { + fn install_package(&self, name: &str, allow_external: bool) -> Result> { let package = self.get_package(name); match package { Some(package) => { - self.install_package_from_repo(name, &package.repo) + if package.is_core || allow_external { + self.install_package_from_repo(name, &package.repo) + }else{ + Ok(BlockedExternalPackage(package.original_repo)) + } }, None => { Ok(NotFoundInIndex) @@ -451,7 +473,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("doesnotexist").unwrap(), NotFoundInIndex); + assert_eq!(temp.package_manager.install_package("doesnotexist", false).unwrap(), NotFoundInIndex); } #[test] @@ -462,7 +484,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("italian-accents").unwrap(), AlreadyInstalled); + assert_eq!(temp.package_manager.install_package("italian-accents", false).unwrap(), AlreadyInstalled); } #[test] @@ -472,7 +494,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("dummy-package").unwrap(), Installed); + assert_eq!(temp.package_manager.install_package("dummy-package", false).unwrap(), Installed); assert!(temp.package_dir.path().join("dummy-package").exists()); assert!(temp.package_dir.path().join("dummy-package/README.md").exists()); assert!(temp.package_dir.path().join("dummy-package/package.yml").exists()); @@ -485,7 +507,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("not-existing").unwrap(), NotFoundInRepo); + assert_eq!(temp.package_manager.install_package("not-existing", false).unwrap(), NotFoundInRepo); } #[test] @@ -495,7 +517,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("dummy-package2").unwrap(), MissingPackageVersion); + assert_eq!(temp.package_manager.install_package("dummy-package2", false).unwrap(), MissingPackageVersion); } #[test] @@ -505,7 +527,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("dummy-package3").unwrap(), UnableToParsePackageInfo); + assert_eq!(temp.package_manager.install_package("dummy-package3", false).unwrap(), UnableToParsePackageInfo); } #[test] @@ -515,7 +537,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("dummy-package4").unwrap(), UnableToParsePackageInfo); + assert_eq!(temp.package_manager.install_package("dummy-package4", false).unwrap(), UnableToParsePackageInfo); } #[test] @@ -525,7 +547,7 @@ mod tests { std::fs::write(index_file, INSTALL_PACKAGE_INDEX); }); - assert_eq!(temp.package_manager.install_package("dummy-package").unwrap(), Installed); + assert_eq!(temp.package_manager.install_package("dummy-package", false).unwrap(), Installed); assert!(temp.package_dir.path().join("dummy-package").exists()); assert!(temp.package_dir.path().join("dummy-package/README.md").exists()); assert!(temp.package_dir.path().join("dummy-package/package.yml").exists()); @@ -571,6 +593,7 @@ mod tests { package_version: "0.1.0" package_author: "Federico Terzi" package_repo: "https://github.com/federico-terzi/espanso-hub-core" + is_core: true --- "###); @@ -582,7 +605,9 @@ mod tests { version: "0.1.0".to_string(), repo: "https://github.com/federico-terzi/espanso-hub-core".to_string(), desc: "Include Italian accents substitutions to espanso.".to_string(), - author: "Federico Terzi".to_string() + author: "Federico Terzi".to_string(), + original_repo: "https://github.com/federico-terzi/espanso-hub-core".to_string(), + is_core: true, }; assert_eq!(package, target_package); @@ -599,6 +624,7 @@ mod tests { package_version:"0.1.0" package_author:Federico Terzi package_repo: "https://github.com/federico-terzi/espanso-hub-core" + is_core: true --- Readme text "###); @@ -611,7 +637,9 @@ mod tests { version: "0.1.0".to_string(), repo: "https://github.com/federico-terzi/espanso-hub-core".to_string(), desc: "Include Italian accents substitutions to espanso.".to_string(), - author: "Federico Terzi".to_string() + author: "Federico Terzi".to_string(), + original_repo: "https://github.com/federico-terzi/espanso-hub-core".to_string(), + is_core: true, }; assert_eq!(package, target_package); diff --git a/src/package/mod.rs b/src/package/mod.rs index 78ecaf1..c33a3bd 100644 --- a/src/package/mod.rs +++ b/src/package/mod.rs @@ -31,7 +31,7 @@ pub trait PackageManager { fn get_package(&self, name: &str) -> Option; - fn install_package(&self, name: &str) -> Result>; + fn install_package(&self, name: &str, allow_external: bool) -> Result>; fn install_package_from_repo(&self, name: &str, repo_url: &str) -> Result>; fn remove_package(&self, name: &str) -> Result>; @@ -50,9 +50,17 @@ pub struct Package { pub version: String, pub repo: String, pub desc: String, - pub author: String + pub author: String, + + #[serde(default = "default_is_core")] + pub is_core: bool, + #[serde(default = "default_original_repo")] + pub original_repo: String, } +fn default_is_core() -> bool {false} +fn default_original_repo() -> String {"".to_owned()} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] pub struct PackageIndex { #[serde(rename = "lastUpdate")] @@ -75,7 +83,8 @@ pub enum InstallResult { UnableToParsePackageInfo, MissingPackageVersion, AlreadyInstalled, - Installed + Installed, + BlockedExternalPackage(String) } #[derive(Clone, Debug, PartialEq)] diff --git a/src/res/test/get_package_index.json b/src/res/test/get_package_index.json index 7512f40..428ed4e 100644 --- a/src/res/test/get_package_index.json +++ b/src/res/test/get_package_index.json @@ -8,7 +8,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "A package to include some basic emojis in espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -19,7 +20,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Include Italian accents substitutions to espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true } diff --git a/src/res/test/index_without_update.json b/src/res/test/index_without_update.json index 4746703..7d83c46 100644 --- a/src/res/test/index_without_update.json +++ b/src/res/test/index_without_update.json @@ -8,7 +8,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "A package to include some basic emojis in espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -19,7 +20,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Include Italian accents substitutions to espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true } diff --git a/src/res/test/install_package_index.json b/src/res/test/install_package_index.json index c9b1e62..63222f7 100644 --- a/src/res/test/install_package_index.json +++ b/src/res/test/install_package_index.json @@ -8,8 +8,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Dummy package", - "author": "Federico Terzi" - + "author": "Federico Terzi", + "is_core": true }, { @@ -18,7 +18,8 @@ "version": "9.9.9", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Dummy package", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -28,7 +29,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Dummy package", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -38,7 +40,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Dummy package", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -49,7 +52,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Include Italian accents substitutions to espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -59,7 +63,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Package that does not exist in the repo", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true } ]} \ No newline at end of file diff --git a/src/res/test/outdated_index.json b/src/res/test/outdated_index.json index 7512f40..428ed4e 100644 --- a/src/res/test/outdated_index.json +++ b/src/res/test/outdated_index.json @@ -8,7 +8,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "A package to include some basic emojis in espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }, @@ -19,7 +20,8 @@ "version": "0.1.0", "repo": "https://github.com/federico-terzi/espanso-hub-core", "desc": "Include Italian accents substitutions to espanso.", - "author": "Federico Terzi" + "author": "Federico Terzi", + "is_core": true }