Skip to main content

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, time::Duration};
12use tracing::{Instrument, debug, debug_span, info};
13
14use crate::common::executor;
15use crate::common::remote::server_list::ServerListProvider;
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: Arc<Vec<String>>, auth_context: Arc<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: Arc<Vec<String>>, auth_context: Arc<AuthContext>) {
76        // noop
77    }
78
79    fn get_login_identity(&self, _: RequestResource) -> LoginIdentityContext {
80        // noop
81        self.login_identity.clone()
82    }
83}
84
85pub(crate) async fn init_auth_plugin(
86    auth_plugin: Arc<dyn AuthPlugin>,
87    server_list_provider: Arc<dyn ServerListProvider>,
88    auth_params: HashMap<String, String>,
89    id: String,
90) {
91    info!("init auth task");
92    let auth_context = Arc::new(AuthContext::default().add_params(auth_params));
93    let server_list = server_list_provider.current_server_list().await;
94    // First login
95    auth_plugin
96        .login(server_list.clone(), auth_context.clone())
97        .in_current_span()
98        .await;
99    info!("init auth finish");
100
101    executor::spawn(
102        async move {
103            // Periodic refresh
104            info!("auth plugin task start.");
105            loop {
106                let server_list = server_list_provider.current_server_list().await;
107                auth_plugin
108                    .login(server_list.clone(), auth_context.clone())
109                    .in_current_span()
110                    .await;
111                debug!("auth_plugin schedule at fixed delay");
112                tokio::time::sleep(Duration::from_secs(30)).await;
113            }
114        }
115        .instrument(debug_span!("auth_task", id = id)),
116    );
117}
118
119#[derive(Debug, Default)]
120pub struct RequestResource {
121    pub request_type: String,
122    pub namespace: Option<String>,
123    pub group: Option<String>,
124    pub resource: Option<String>,
125}