[APP-3801] implement remote environments auth (#9331)

This commit is contained in:
Moira Huang
2026-04-28 21:31:23 -05:00
committed by GitHub
parent c325d146ab
commit f0c8b7f723
21 changed files with 685 additions and 69 deletions
+73 -6
View File
@@ -3,6 +3,7 @@
//! [`SshTransport`] uses an existing SSH ControlMaster socket to check/install
//! the remote server binary and to launch the `remote-server-proxy` process
//! whose stdin/stdout become the protocol channel.
use std::fmt;
use std::future::Future;
use std::path::PathBuf;
use std::pin::Pin;
@@ -12,8 +13,11 @@ use std::sync::Arc;
use anyhow::Result;
use warpui::r#async::executor;
use remote_server::auth::RemoteServerAuthContext;
use remote_server::client::RemoteServerClient;
use remote_server::setup::{self, RemotePlatform, CHECK_TIMEOUT, INSTALL_TIMEOUT};
use remote_server::setup::{
self, remote_server_daemon_dir, RemotePlatform, CHECK_TIMEOUT, INSTALL_TIMEOUT,
};
use remote_server::ssh::{run_ssh_command, run_ssh_script, ssh_args};
use remote_server::transport::{Connection, RemoteTransport};
@@ -23,16 +27,54 @@ use remote_server::transport::{Connection, RemoteTransport};
/// process (`ssh -N -o ControlMaster=yes -o ControlPath=<path>`). All SSH
/// commands (binary check, install, proxy launch) are multiplexed through
/// this socket without re-authenticating.
#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct SshTransport {
socket_path: PathBuf,
auth_context: Arc<RemoteServerAuthContext>,
}
impl fmt::Debug for SshTransport {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SshTransport")
.field("socket_path", &self.socket_path)
.finish_non_exhaustive()
}
}
impl SshTransport {
pub fn new(socket_path: PathBuf) -> Self {
Self { socket_path }
pub fn new(socket_path: PathBuf, auth_context: Arc<RemoteServerAuthContext>) -> Self {
Self {
socket_path,
auth_context,
}
}
pub fn socket_path(&self) -> &PathBuf {
&self.socket_path
}
pub fn remote_daemon_socket_path(&self) -> String {
format!(
"{}/server.sock",
remote_server_daemon_dir(&self.auth_context.remote_server_identity_key())
)
}
pub fn remote_daemon_pid_path(&self) -> String {
format!(
"{}/server.pid",
remote_server_daemon_dir(&self.auth_context.remote_server_identity_key())
)
}
fn remote_proxy_command(&self) -> String {
let binary = remote_server::setup::remote_server_binary();
let identity_key = self.auth_context.remote_server_identity_key();
let quoted_identity_key = shell_words::quote(&identity_key);
format!("{binary} remote-server-proxy --identity-key {quoted_identity_key}")
}
}
impl RemoteTransport for SshTransport {
fn detect_platform(
&self,
@@ -100,10 +142,10 @@ impl RemoteTransport for SshTransport {
executor: Arc<executor::Background>,
) -> Pin<Box<dyn Future<Output = Result<Connection>> + Send>> {
let socket_path = self.socket_path.clone();
let remote_proxy_command = self.remote_proxy_command();
Box::pin(async move {
let binary = setup::remote_server_binary();
let mut args = ssh_args(&socket_path);
args.push(format!("{binary} remote-server-proxy"));
args.push(remote_proxy_command);
// `kill_on_drop(true)` pairs with ownership of the `Child` being
// returned in the [`Connection`] below: the
@@ -142,3 +184,28 @@ impl RemoteTransport for SshTransport {
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use warpui::r#async::BoxFuture;
fn static_auth_context() -> Arc<RemoteServerAuthContext> {
Arc::new(RemoteServerAuthContext::new(
|| -> BoxFuture<'static, Option<String>> { Box::pin(async { None }) },
|| "user id/with spaces".to_string(),
))
}
#[test]
fn remote_proxy_command_quotes_identity_key() {
let transport = SshTransport::new(
PathBuf::from("/tmp/control-master.sock"),
static_auth_context(),
);
let command = transport.remote_proxy_command();
assert!(command.contains("remote-server-proxy --identity-key"));
assert!(command.contains("'user id/with spaces'"));
}
}