Skip to main content

custom_auth_handler/
main.rs

1use std::env;
2use std::error::Error;
3use std::sync::Arc;
4
5use nano_get::{
6    AuthDecision, AuthHandler, AuthTarget, Challenge, Client, Header, Request, Response, Url,
7};
8
9struct DemoTokenAuth;
10
11impl AuthHandler for DemoTokenAuth {
12    fn respond(
13        &self,
14        _target: AuthTarget,
15        _url: &Url,
16        challenges: &[Challenge],
17        _request: &Request,
18        _response: &Response,
19    ) -> Result<AuthDecision, nano_get::NanoGetError> {
20        let supports_token = challenges
21            .iter()
22            .any(|challenge| challenge.scheme.eq_ignore_ascii_case("token"));
23
24        if supports_token {
25            return Ok(AuthDecision::UseHeaders(vec![Header::new(
26                "Authorization",
27                "Token example-secret",
28            )?]));
29        }
30
31        Ok(AuthDecision::NoMatch)
32    }
33}
34
35fn print_setup() {
36    println!("The custom-auth-handler example needs a real protected endpoint.");
37    println!("Set NANO_GET_CUSTOM_AUTH_URL to a URL that challenges with a custom scheme.");
38    println!("The example handler looks for a scheme named `Token`.");
39}
40
41fn main() -> Result<(), Box<dyn Error>> {
42    let Some(url) = env::var("NANO_GET_CUSTOM_AUTH_URL").ok() else {
43        print_setup();
44        return Ok(());
45    };
46
47    let client = Client::builder()
48        .auth_handler(Arc::new(DemoTokenAuth))
49        .build();
50    let response = client.execute(Request::get(&url)?)?;
51
52    println!("custom-auth-handler example");
53    println!(
54        "status: {} {}",
55        response.status_code, response.reason_phrase
56    );
57    println!(
58        "parsed WWW-Authenticate challenges: {}",
59        response.www_authenticate_challenges()?.len()
60    );
61
62    Ok(())
63}