nacos_sdk/api/plugin/auth/
mod.rs

1#[cfg(feature = "auth-by-http")]
2mod auth_by_http;
3#[cfg(feature = "auth-by-http")]
4pub use auth_by_http::*;
5
6#[cfg(feature = "auth-by-aliyun")]
7mod auth_by_aliyun_ram;
8#[cfg(feature = "auth-by-aliyun")]
9pub use auth_by_aliyun_ram::*;
10
11use std::{collections::HashMap, sync::Arc, thread, time::Duration};
12use tokio::{sync::oneshot, time::sleep};
13use tracing::{Instrument, debug, debug_span, info};
14
15use crate::common::executor;
16
17/// Auth plugin in Client.
18/// This api may change in the future, please forgive me if you customize the implementation.
19#[async_trait::async_trait]
20pub trait AuthPlugin: Send + Sync {
21    /// Login with [`AuthContext`], Note that this method will be scheduled continuously.
22    async fn login(&self, server_list: Vec<String>, auth_context: AuthContext);
23
24    /// Get the [`LoginIdentityContext`].
25    fn get_login_identity(&self, resource: RequestResource) -> LoginIdentityContext;
26}
27
28#[derive(Clone, Default)]
29pub struct AuthContext {
30    pub(crate) params: HashMap<String, String>,
31}
32
33impl AuthContext {
34    /// Add the param.
35    pub fn add_param(mut self, key: impl Into<String>, val: impl Into<String>) -> Self {
36        self.params.insert(key.into(), val.into());
37        self
38    }
39
40    /// Add the params.
41    pub fn add_params(mut self, map: HashMap<String, String>) -> Self {
42        self.params.extend(map);
43        self
44    }
45}
46
47#[derive(Clone, Default)]
48pub struct LoginIdentityContext {
49    pub(crate) contexts: HashMap<String, String>,
50}
51
52impl LoginIdentityContext {
53    /// Add the context.
54    pub fn add_context(mut self, key: impl Into<String>, val: impl Into<String>) -> Self {
55        self.contexts.insert(key.into(), val.into());
56        self
57    }
58
59    /// Add the contexts.
60    pub fn add_contexts(mut self, map: HashMap<String, String>) -> Self {
61        self.contexts.extend(map);
62        self
63    }
64}
65
66/// Noop AuthPlugin.
67#[derive(Default)]
68pub(crate) struct NoopAuthPlugin {
69    login_identity: LoginIdentityContext,
70}
71
72#[async_trait::async_trait]
73impl AuthPlugin for NoopAuthPlugin {
74    #[allow(unused_variables)]
75    async fn login(&self, server_list: Vec<String>, auth_context: AuthContext) {
76        // noop
77    }
78
79    fn get_login_identity(&self, _: RequestResource) -> LoginIdentityContext {
80        // noop
81        self.login_identity.clone()
82    }
83}
84
85pub fn init_auth_plugin(
86    auth_plugin: Arc<dyn AuthPlugin>,
87    server_list: Vec<String>,
88    auth_params: HashMap<String, String>,
89    id: String,
90) {
91    let (tx, rx) = oneshot::channel::<()>();
92    executor::spawn(
93        async move {
94            info!("init auth task");
95            let auth_context = AuthContext::default().add_params(auth_params);
96            auth_plugin
97                .login(server_list.clone(), auth_context.clone())
98                .in_current_span()
99                .await;
100            info!("init auth finish");
101            let _ = tx.send(());
102
103            info!("auth plugin task start.");
104            loop {
105                auth_plugin
106                    .login(server_list.clone(), auth_context.clone())
107                    .in_current_span()
108                    .await;
109                debug!("auth_plugin schedule at fixed delay");
110                sleep(Duration::from_secs(30)).await;
111            }
112        }
113        .instrument(debug_span!("auth_task", id = id)),
114    );
115
116    let wait_ret = thread::spawn(move || rx.blocking_recv());
117
118    let _ = wait_ret.join().unwrap();
119}
120
121#[derive(Debug, Default)]
122pub struct RequestResource {
123    pub request_type: String,
124    pub namespace: Option<String>,
125    pub group: Option<String>,
126    pub resource: Option<String>,
127}