MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / browser_auth_flow

Function browser_auth_flow

crates/openshell-cli/src/auth.rs:91–176  ·  view source on GitHub ↗

Run the browser-based CF Access auth flow. 1. Generates a one-time confirmation code 2. Starts an ephemeral localhost HTTP server 3. Opens the browser to the gateway's `/auth/connect` page 4. Waits for the XHR POST callback with the CF JWT and matching code 5. Returns the token

(gateway_endpoint: &str)

Source from the content-addressed store, hash-verified

89/// 4. Waits for the XHR POST callback with the CF JWT and matching code
90/// 5. Returns the token
91pub async fn browser_auth_flow(gateway_endpoint: &str) -> Result<String> {
92 // Short-circuit when the browser is suppressed (CI, e2e tests, headless
93 // environments). Without this early return the function still binds a TCP
94 // listener, spawns a callback server, and waits the full AUTH_TIMEOUT
95 // (120 s) for a POST that will never arrive.
96 let no_browser = std::env::var("OPENSHELL_NO_BROWSER")
97 .is_ok_and(|v| v == "1" || v.eq_ignore_ascii_case("true"));
98 if no_browser {
99 return Err(miette::miette!(
100 "authentication skipped (OPENSHELL_NO_BROWSER is set).\n\
101 Authenticate later with: openshell gateway login"
102 ));
103 }
104
105 #[cfg(test)]
106 if std::env::var("OPENSHELL_TEST_BROWSER_AUTH_FAIL")
107 .is_ok_and(|v| v == "1" || v.eq_ignore_ascii_case("true"))
108 {
109 return Err(miette::miette!(
110 "browser authentication failed (OPENSHELL_TEST_BROWSER_AUTH_FAIL is set)"
111 ));
112 }
113
114 let listener = TcpListener::bind("127.0.0.1:0").await.into_diagnostic()?;
115 let local_addr = listener.local_addr().into_diagnostic()?;
116 let callback_port = local_addr.port();
117
118 let code = generate_confirmation_code();
119
120 let auth_url = format!(
121 "{}/auth/connect?callback_port={callback_port}&code={code}",
122 gateway_endpoint.trim_end_matches('/')
123 );
124
125 // Channel to receive the token from the callback handler.
126 let (tx, rx) = oneshot::channel::<String>();
127
128 // Spawn the callback server.
129 let server_handle = tokio::spawn(run_callback_server(
130 listener,
131 tx,
132 code.clone(),
133 gateway_endpoint.to_string(),
134 ));
135
136 // Prompt the user before opening the browser.
137 eprintln!(" Confirmation code: {code}");
138 eprintln!(" Verify this code matches your browser before clicking Connect.");
139 eprintln!();
140
141 eprint!("Press Enter to open the browser for authentication...");
142 std::io::stderr().flush().ok();
143 let mut input = String::new();
144 std::io::stdin().read_line(&mut input).ok();
145 drop(input);
146
147 if let Err(e) = open_browser_url(&auth_url) {
148 debug!(error = %e, "failed to open browser");

Callers 2

gateway_addFunction · 0.85
gateway_loginFunction · 0.85

Calls 6

run_callback_serverFunction · 0.85
open_browser_urlFunction · 0.85
abortMethod · 0.80
spawnFunction · 0.50
flushMethod · 0.45

Tested by

no test coverage detected