couchbase_core/mgmtx/
user_helper.rs1use crate::httpx::client::Client;
20use crate::httpx::request::OnBehalfOfInfo;
21use crate::mgmtx::error;
22use crate::mgmtx::mgmt::Management;
23use crate::mgmtx::node_target::NodeTarget;
24use crate::mgmtx::options::{EnsureUserPollOptions, GetUserOptions};
25use std::sync::Arc;
26
27#[derive(Debug, Clone)]
28pub struct EnsureUserHelper<'a> {
29 user_agent: &'a str,
30 username: &'a str,
31 auth_domain: &'a str,
32 want_missing: bool,
33
34 on_behalf_of_info: Option<&'a OnBehalfOfInfo>,
35
36 confirmed_endpoints: Vec<&'a str>,
37}
38
39impl<'a> EnsureUserHelper<'a> {
40 pub fn new(
41 user_agent: &'a str,
42 username: &'a str,
43 auth_domain: &'a str,
44 want_missing: bool,
45 on_behalf_of_info: Option<&'a OnBehalfOfInfo>,
46 ) -> Self {
47 Self {
48 user_agent,
49 username,
50 auth_domain,
51 want_missing,
52 on_behalf_of_info,
53 confirmed_endpoints: vec![],
54 }
55 }
56
57 async fn poll_one<C: Client>(
58 &self,
59 client: Arc<C>,
60 target: &NodeTarget,
61 ) -> error::Result<bool> {
62 let resp = Management {
63 http_client: client,
64 user_agent: self.user_agent.to_string(),
65 endpoint: target.endpoint.to_string(),
66 canonical_endpoint: target.canonical_endpoint.to_string(),
67 auth: target.auth.clone(),
68 tracing: Default::default(),
69 }
70 .get_user(&GetUserOptions {
71 on_behalf_of_info: self.on_behalf_of_info,
72 username: self.username,
73 auth_domain: self.auth_domain,
74 })
75 .await;
76
77 match resp {
78 Ok(_) => Ok(!self.want_missing),
79 Err(e) => {
80 if let error::ErrorKind::Server(e) = e.kind() {
81 if e.kind() == &error::ServerErrorKind::UserNotFound {
82 if self.want_missing {
83 return Ok(true);
84 }
85
86 return Ok(false);
87 }
88 }
89
90 Err(e)
91 }
92 }
93 }
94
95 pub async fn poll<C: Client>(
96 &mut self,
97 opts: &'a EnsureUserPollOptions<C>,
98 ) -> error::Result<bool> {
99 let mut filtered_targets = vec![];
100 for target in &opts.targets {
101 if !self.confirmed_endpoints.contains(&target.endpoint.as_str()) {
102 filtered_targets.push(target);
103 }
104 }
105
106 let mut success_endpoints = vec![];
107 for target in &opts.targets {
108 if self.poll_one(opts.client.clone(), target).await? {
109 success_endpoints.push(target.endpoint.as_str());
110 }
111 }
112
113 self.confirmed_endpoints
114 .extend_from_slice(success_endpoints.as_slice());
115
116 Ok(success_endpoints.len() == filtered_targets.len())
117 }
118}