Skip to content

Commit

Permalink
feat: support specify the browser to use
Browse files Browse the repository at this point in the history
Related: #405, #407, #397
  • Loading branch information
yuezk committed Aug 14, 2024
1 parent c2a6a43 commit 9460d49
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 13 deletions.
36 changes: 32 additions & 4 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ compile-time = "0.2"
serde_urlencoded = "0.7"
md5="0.7"
sha256="1"
which="6"

# Tauri dependencies
tauri = { version = "1.5" }
Expand Down
13 changes: 11 additions & 2 deletions apps/gpauth/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct Cli {
clean: bool,
#[arg(long)]
default_browser: bool,
#[arg(long)]
external_browser: Option<String>,
}

impl Cli {
Expand All @@ -59,8 +61,15 @@ impl Cli {
None => portal_prelogin(&self.server, &gp_params).await?,
};

if self.default_browser {
let browser_auth = BrowserAuthenticator::new(&saml_request);
let browser_auth = if let Some(external_browser) = &self.external_browser {
Some(BrowserAuthenticator::new_with_browser(&saml_request, external_browser))
} else if self.default_browser {
Some(BrowserAuthenticator::new(&saml_request))
} else {
None
};

if let Some(browser_auth) = browser_auth {
browser_auth.authenticate()?;

info!("Please continue the authentication process in the default browser");
Expand Down
14 changes: 13 additions & 1 deletion apps/gpclient/src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub(crate) struct ConnectArgs {
#[arg(long)]
os_version: Option<String>,

#[arg(long, help="Disable DTLS and ESP")]
#[arg(long, help = "Disable DTLS and ESP")]
no_dtls: bool,

#[arg(long, help = "The HiDPI mode, useful for high resolution screens")]
Expand All @@ -97,6 +97,12 @@ pub(crate) struct ConnectArgs {

#[arg(long, help = "Use the default browser to authenticate")]
default_browser: bool,

#[arg(
long,
help = "Use the specified browser to authenticate, e.g., firefox, chromium, chrome, or the path to the browser"
)]
external_browser: Option<String>,
}

impl ConnectArgs {
Expand Down Expand Up @@ -326,6 +332,11 @@ impl<'a> ConnectHandler<'a> {
match prelogin {
Prelogin::Saml(prelogin) => {
let use_default_browser = prelogin.support_default_browser() && self.args.default_browser;
let external_browser = if prelogin.support_default_browser() {
self.args.external_browser.as_deref()
} else {
None
};

let cred = SamlAuthLauncher::new(&self.args.server)
.gateway(is_gateway)
Expand All @@ -338,6 +349,7 @@ impl<'a> ConnectHandler<'a> {
.ignore_tls_errors(self.shared_args.ignore_tls_errors)
.clean(self.args.clean)
.default_browser(use_default_browser)
.external_browser(external_browser)
.launch()
.await?;

Expand Down
1 change: 1 addition & 0 deletions crates/gpapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ uzers.workspace = true
serde_urlencoded.workspace = true
md5.workspace = true
sha256.workspace = true
which.workspace = true

tauri = { workspace = true, optional = true }
clap = { workspace = true, optional = true }
Expand Down
11 changes: 11 additions & 0 deletions crates/gpapi/src/process/auth_launcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct SamlAuthLauncher<'a> {
ignore_tls_errors: bool,
clean: bool,
default_browser: bool,
external_browser: Option<&'a str>,
}

impl<'a> SamlAuthLauncher<'a> {
Expand All @@ -35,6 +36,7 @@ impl<'a> SamlAuthLauncher<'a> {
ignore_tls_errors: false,
clean: false,
default_browser: false,
external_browser: None,
}
}

Expand Down Expand Up @@ -88,6 +90,11 @@ impl<'a> SamlAuthLauncher<'a> {
self
}

pub fn external_browser(mut self, external_browser: Option<&'a str>) -> Self {
self.external_browser = external_browser;
self
}

/// Launch the authenticator binary as the current user or SUDO_USER if available.
pub async fn launch(self) -> anyhow::Result<Option<Credential>> {
let mut auth_cmd = Command::new(GP_AUTH_BINARY);
Expand Down Expand Up @@ -133,6 +140,10 @@ impl<'a> SamlAuthLauncher<'a> {
auth_cmd.arg("--default-browser");
}

if let Some(external_browser) = self.external_browser {
auth_cmd.arg("--external-browser").arg(external_browser);
}

let mut non_root_cmd = auth_cmd.into_non_root()?;
let output = non_root_cmd
.kill_on_drop(true)
Expand Down
45 changes: 39 additions & 6 deletions crates/gpapi/src/process/browser_authenticator.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
use std::{env::temp_dir, fs, io::Write, os::unix::fs::PermissionsExt};
use std::{borrow::Cow, env::temp_dir, fs, io::Write, os::unix::fs::PermissionsExt};

use anyhow::bail;
use log::warn;
use log::{info, warn};

pub struct BrowserAuthenticator<'a> {
auth_request: &'a str,
browser: Option<&'a str>,
}

impl BrowserAuthenticator<'_> {
pub fn new(auth_request: &str) -> BrowserAuthenticator {
BrowserAuthenticator { auth_request }
BrowserAuthenticator {
auth_request,
browser: None,
}
}

pub fn new_with_browser<'a>(auth_request: &'a str, browser: &'a str) -> BrowserAuthenticator<'a> {
BrowserAuthenticator {
auth_request,
browser: Some(browser),
}
}

pub fn authenticate(&self) -> anyhow::Result<()> {
if self.auth_request.starts_with("http") {
open::that_detached(self.auth_request)?;
let path = if self.auth_request.starts_with("http") {
Cow::Borrowed(self.auth_request)
} else {
let html_file = temp_dir().join("gpauth.html");

Expand All @@ -31,9 +42,31 @@ impl BrowserAuthenticator<'_> {
file.set_permissions(fs::Permissions::from_mode(0o600))?;
file.write_all(self.auth_request.as_bytes())?;

open::that_detached(html_file)?;
Cow::Owned(html_file.to_string_lossy().to_string())
};

if let Some(browser) = self.browser {
let app = find_browser_path(browser);

info!("Launching browser: {}", app);
open::with_detached(path.as_ref(), app)?;
} else {
info!("Launching the default browser...");
open::that_detached(path.as_ref())?;
}

Ok(())
}
}

fn find_browser_path(browser: &str) -> String {
if browser == "chrome" {
which::which("google-chrome-stable")
.or_else(|_| which::which("google-chrome"))
.or_else(|_| which::which("chromium"))
.map(|path| path.to_string_lossy().to_string())
.unwrap_or_else(|_| browser.to_string())
} else {
browser.into()
}
}

0 comments on commit 9460d49

Please sign in to comment.