Skip to content

Commit 6b0316c

Browse files
committed
refactor: add cookie handling from standard input in ConnectHandler
1 parent 9b4d3b1 commit 6b0316c

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

apps/gpclient/src/connect.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub(crate) struct ConnectHandler<'a> {
165165
shared_args: &'a SharedArgs<'a>,
166166
latest_key_password: RefCell<Option<String>>,
167167
password_from_stdin: RefCell<Option<String>>,
168+
cookie_from_stdin: RefCell<Option<String>>,
168169
}
169170

170171
impl<'a> ConnectHandler<'a> {
@@ -174,6 +175,7 @@ impl<'a> ConnectHandler<'a> {
174175
shared_args,
175176
latest_key_password: Default::default(),
176177
password_from_stdin: Default::default(),
178+
cookie_from_stdin: Default::default(),
177179
}
178180
}
179181

@@ -413,7 +415,7 @@ impl<'a> ConnectHandler<'a> {
413415

414416
async fn obtain_credential(&self, prelogin: &Prelogin, server: &str) -> anyhow::Result<Credential> {
415417
if self.args.cookie_on_stdin {
416-
return read_cookie_from_stdin();
418+
return self.read_cookie_from_stdin();
417419
}
418420

419421
let is_gateway = prelogin.is_gateway();
@@ -473,6 +475,27 @@ impl<'a> ConnectHandler<'a> {
473475
}
474476
}
475477

478+
fn read_cookie_from_stdin(&self) -> anyhow::Result<Credential> {
479+
// If the cookie has been read from stdin, use it directly
480+
if let Some(cookie) = self.cookie_from_stdin.borrow().as_ref() {
481+
info!("Reusing the cookie read from standard input");
482+
return Credential::try_from(serde_json::from_str::<SamlAuthResult>(cookie)?);
483+
}
484+
485+
info!("Reading cookie from standard input");
486+
487+
let mut cookie = String::new();
488+
std::io::stdin().read_line(&mut cookie)?;
489+
490+
// Considering that the gateway connection may fail even though the cookie read
491+
// from stdin is correct. It may retry the gateway connection, so we need to
492+
// save the cookie read from stdin to avoid reading stdin again.
493+
self.cookie_from_stdin.replace(Some(cookie.trim_end().to_owned()));
494+
495+
let auth_result = serde_json::from_str::<SamlAuthResult>(cookie.trim_end()).context("Failed to parse auth data")?;
496+
Credential::try_from(auth_result)
497+
}
498+
476499
fn obtain_password(&self, prelogin: &StandardPrelogin) -> anyhow::Result<String> {
477500
let password = if self.args.passwd_on_stdin {
478501
// If the password has been read from stdin, use it directly
@@ -522,16 +545,6 @@ impl<'a> ConnectHandler<'a> {
522545
}
523546
}
524547

525-
fn read_cookie_from_stdin() -> anyhow::Result<Credential> {
526-
info!("Reading cookie from standard input");
527-
528-
let mut cookie = String::new();
529-
std::io::stdin().read_line(&mut cookie)?;
530-
531-
let auth_result = serde_json::from_str::<SamlAuthResult>(cookie.trim_end()).context("Failed to parse auth data")?;
532-
Credential::try_from(auth_result)
533-
}
534-
535548
fn write_pid_file() {
536549
let pid = std::process::id();
537550

0 commit comments

Comments
 (0)