sui_rpc/client/
auth.rs

1#[derive(Clone, Debug, Default)]
2pub struct AuthInterceptor {
3    auth: Option<tonic::metadata::MetadataValue<tonic::metadata::Ascii>>,
4}
5
6impl AuthInterceptor {
7    /// Enable HTTP basic authentication with a username and optional password.
8    pub fn basic<U, P>(username: U, password: Option<P>) -> Self
9    where
10        U: std::fmt::Display,
11        P: std::fmt::Display,
12    {
13        use base64::prelude::BASE64_STANDARD;
14        use base64::write::EncoderWriter;
15        use std::io::Write;
16
17        let mut buf = b"Basic ".to_vec();
18        {
19            let mut encoder = EncoderWriter::new(&mut buf, &BASE64_STANDARD);
20            let _ = write!(encoder, "{username}:");
21            if let Some(password) = password {
22                let _ = write!(encoder, "{password}");
23            }
24        }
25        let mut header = tonic::metadata::MetadataValue::try_from(buf)
26            .expect("base64 is always valid HeaderValue");
27        header.set_sensitive(true);
28
29        Self { auth: Some(header) }
30    }
31
32    /// Enable HTTP bearer authentication.
33    pub fn bearer<T>(token: T) -> Self
34    where
35        T: std::fmt::Display,
36    {
37        let header_value = format!("Bearer {token}");
38        let mut header = tonic::metadata::MetadataValue::try_from(header_value)
39            .expect("token is always valid HeaderValue");
40        header.set_sensitive(true);
41
42        Self { auth: Some(header) }
43    }
44}
45
46impl tonic::service::Interceptor for AuthInterceptor {
47    fn call(
48        &mut self,
49        mut request: tonic::Request<()>,
50    ) -> std::result::Result<tonic::Request<()>, tonic::Status> {
51        if let Some(auth) = self.auth.clone() {
52            request
53                .metadata_mut()
54                .insert(http::header::AUTHORIZATION.as_str(), auth);
55        }
56        Ok(request)
57    }
58}
59
60impl tonic::service::Interceptor for &mut AuthInterceptor {
61    fn call(
62        &mut self,
63        mut request: tonic::Request<()>,
64    ) -> std::result::Result<tonic::Request<()>, tonic::Status> {
65        if let Some(auth) = self.auth.clone() {
66            request
67                .metadata_mut()
68                .insert(http::header::AUTHORIZATION.as_str(), auth);
69        }
70        Ok(request)
71    }
72}