Skip to content

Commit

Permalink
feat: windows
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeladler committed Jul 1, 2024
1 parent 1c47bb6 commit 6eee313
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 25 deletions.
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ sha2 = "0.10.8"
[dev-dependencies]
mockito = "1.4.0"
temp-dir = "0.1.13"

[target.'cfg(target_os = "windows")'.dependencies]
winreg = "0.7"
1 change: 1 addition & 0 deletions src/crx3.rs → src/chromium/crx3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct CrxFile {
pub zip_archive: Vec<u8>,
}

#[allow(dead_code)]
pub async fn parse_file<P: AsRef<Path>>(path: P) -> Result<CrxFile> {
let mut file = File::open(path).await?;

Expand Down
11 changes: 11 additions & 0 deletions src/chromium/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod crx3;

#[cfg(not(target_os = "windows"))]
mod unix;
#[cfg(not(target_os = "windows"))]
pub use unix::install;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
pub use windows::install;
22 changes: 18 additions & 4 deletions src/chromium.rs → src/chromium/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,38 @@ use tokio::fs::{create_dir_all, File};
use tokio::io::AsyncWriteExt;
use tracing::info;

use crate::crx3;
use super::crx3;
use crate::manifest;

#[derive(Debug, Serialize, Deserialize)]
pub struct ExternalExt {
struct ExternalExt {
pub external_crx: PathBuf,
pub external_version: String,
}

const DEFAULT_BASE_URL_GOOGLE: &str = "https://clients2.google.com";

pub async fn install(
client: ClientWithMiddleware,
base_url: Option<String>,
extension_id: String,
dest_dir: PathBuf,
profiles: Vec<PathBuf>,
) -> Result<()> {
let ext = download_extension(client, base_url, extension_id, &dest_dir).await?;
for p in profiles {
install_extension(&ext, &p).await?;
}
Ok(())
}

/// download_extension downloads a chromium extension from the Chrome Web Store.
///
/// * `client` - A reqwest client with middleware.
/// * `base_url` - Use this to override the default base URL.
/// * `extension_id` - The ID of the extension to download.
/// * `dest_dir` - The directory to save the extension to.
pub async fn download_extension(
async fn download_extension(
client: ClientWithMiddleware,
base_url: Option<String>,
extension_id: String,
Expand Down Expand Up @@ -54,7 +68,7 @@ pub async fn download_extension(
})
}

pub async fn install_extension(ext: &ExternalExt, profile_dir: &Path) -> Result<()> {
async fn install_extension(ext: &ExternalExt, profile_dir: &Path) -> Result<()> {
let profile_extensions = profile_dir.join("External Extensions");
let mut json_path = profile_extensions.join(ext.external_crx.file_name().unwrap());
json_path.set_extension("json");
Expand Down
37 changes: 37 additions & 0 deletions src/chromium/windows.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use anyhow::Result;
use reqwest_middleware::ClientWithMiddleware;
use std::path::PathBuf;
use tracing::info;

pub async fn install(
_client: ClientWithMiddleware,
_base_url: Option<String>,
extension_id: String,
_dest_dir: PathBuf,
_profiles: Vec<PathBuf>,
) -> Result<()> {
let hklm = winreg::RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE);
let os_arch = std::env::var("PROCESSOR_ARCHITECTURE").unwrap_or_default();
let base_key_path = if os_arch == "AMD64" {
"Software\\Wow6432Node\\Google\\Chrome\\Extensions"
} else {
"Software\\Google\\Chrome\\Extensions"
};

let mut path = String::with_capacity(base_key_path.len() + 2 + extension_id.len());
path.push_str(base_key_path);
path.push('\\');
path.push_str(&extension_id);

let (key, disp) = hklm.create_subkey(path)?;
if disp == winreg::enums::RegDisposition::REG_CREATED_NEW_KEY {
key.set_value(
"update_url",
&"https://clients2.google.com/service/update2/crx",
)?;
info!("Installed extension {extension_id}");
} else {
info!("Extension {extension_id} already installed");
}
Ok(())
}
25 changes: 5 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod chromium;
mod config;
mod crx3;
mod firefox;
mod manifest;

Expand Down Expand Up @@ -75,9 +74,9 @@ async fn run<P: AsRef<Path>>(cfg_path: P) -> Result<u32> {
for ((name, kind), profiles) in ext_to_profiles.drain() {
match kind {
config::BrowserKind::Chromium => {
set.spawn(do_chromium(
cfg.base_url_google.clone(),
set.spawn(chromium::install(
client.clone(),
cfg.base_url_google.clone(),
name,
dest_dir_chromium.clone(),
profiles,
Expand Down Expand Up @@ -105,20 +104,6 @@ async fn run<P: AsRef<Path>>(cfg_path: P) -> Result<u32> {
Ok(err_count)
}

async fn do_chromium(
base_url: Option<String>,
client: ClientWithMiddleware,
name: String,
dest_dir: PathBuf,
profiles: Vec<PathBuf>,
) -> Result<()> {
let ext = chromium::download_extension(client, base_url, name.to_string(), &dest_dir).await?;
for p in profiles {
chromium::install_extension(&ext, &p).await?;
}
Ok(())
}

async fn do_firefox(
base_url: Option<String>,
client: ClientWithMiddleware,
Expand Down Expand Up @@ -160,6 +145,7 @@ mod tests {
io::AsyncReadExt,
};

#[cfg(not(target_os = "windows"))]
#[tokio::test]
async fn test_chromium() {
let mut server = mockito::Server::new_async().await;
Expand Down Expand Up @@ -212,9 +198,8 @@ mod tests {
.unwrap();
let mut content = String::with_capacity(4096);
f.read_to_string(&mut content).await.unwrap();
let ext = serde_json::from_str::<chromium::ExternalExt>(&content).unwrap();
assert_eq!(ext.external_crx, crx_file);
assert_eq!(ext.external_version, "2.1.2");
assert!(content.contains(crx_file.to_str().unwrap()));
assert!(content.contains("2.1.2"));

m1.assert_async().await;
}
Expand Down

0 comments on commit 6eee313

Please sign in to comment.