cassandra_protocol/
authenticators.rs1use crate::error::Result;
2use crate::types::CBytes;
3
4pub trait SaslAuthenticator {
16 fn initial_response(&self) -> CBytes;
17
18 fn evaluate_challenge(&self, challenge: CBytes) -> Result<CBytes>;
19
20 fn handle_success(&self, data: CBytes) -> Result<()>;
21}
22
23pub trait SaslAuthenticatorProvider {
25 fn name(&self) -> Option<&str>;
26
27 fn create_authenticator(&self) -> Box<dyn SaslAuthenticator + Send>;
28}
29
30#[derive(Debug, Clone)]
31pub struct StaticPasswordAuthenticator {
32 username: String,
33 password: String,
34}
35
36impl StaticPasswordAuthenticator {
37 pub fn new<S: ToString>(username: S, password: S) -> StaticPasswordAuthenticator {
38 StaticPasswordAuthenticator {
39 username: username.to_string(),
40 password: password.to_string(),
41 }
42 }
43}
44
45impl SaslAuthenticator for StaticPasswordAuthenticator {
46 fn initial_response(&self) -> CBytes {
47 let mut token = vec![0];
48 token.extend_from_slice(self.username.as_bytes());
49 token.push(0);
50 token.extend_from_slice(self.password.as_bytes());
51
52 CBytes::new(token)
53 }
54
55 fn evaluate_challenge(&self, _challenge: CBytes) -> Result<CBytes> {
56 Err("Server challenge is not supported for StaticPasswordAuthenticator!".into())
57 }
58
59 fn handle_success(&self, _data: CBytes) -> Result<()> {
60 Ok(())
61 }
62}
63
64#[derive(Debug, Clone)]
66pub struct StaticPasswordAuthenticatorProvider {
67 username: String,
68 password: String,
69}
70
71impl SaslAuthenticatorProvider for StaticPasswordAuthenticatorProvider {
72 fn name(&self) -> Option<&str> {
73 Some("org.apache.cassandra.auth.PasswordAuthenticator")
74 }
75
76 fn create_authenticator(&self) -> Box<dyn SaslAuthenticator + Send> {
77 Box::new(StaticPasswordAuthenticator::new(
78 self.username.clone(),
79 self.password.clone(),
80 ))
81 }
82}
83
84impl StaticPasswordAuthenticatorProvider {
85 pub fn new<S: ToString>(username: S, password: S) -> Self {
86 StaticPasswordAuthenticatorProvider {
87 username: username.to_string(),
88 password: password.to_string(),
89 }
90 }
91}
92
93#[derive(Debug, Clone)]
94pub struct NoneAuthenticator;
95
96impl SaslAuthenticator for NoneAuthenticator {
97 fn initial_response(&self) -> CBytes {
98 CBytes::new(vec![0])
99 }
100
101 fn evaluate_challenge(&self, _challenge: CBytes) -> Result<CBytes> {
102 Err("Server challenge is not supported for NoneAuthenticator!".into())
103 }
104
105 fn handle_success(&self, _data: CBytes) -> Result<()> {
106 Ok(())
107 }
108}
109
110#[derive(Debug, Clone)]
112pub struct NoneAuthenticatorProvider;
113
114impl SaslAuthenticatorProvider for NoneAuthenticatorProvider {
115 fn name(&self) -> Option<&str> {
116 None
117 }
118
119 fn create_authenticator(&self) -> Box<dyn SaslAuthenticator + Send> {
120 Box::new(NoneAuthenticator)
121 }
122}
123
124#[cfg(test)]
125#[allow(deprecated)]
126mod tests {
127 use super::*;
128
129 #[test]
130 fn test_static_password_authenticator_new() {
131 StaticPasswordAuthenticator::new("foo", "bar");
132 }
133
134 #[test]
135 fn test_static_password_authenticator_cassandra_name() {
136 let auth = StaticPasswordAuthenticatorProvider::new("foo", "bar");
137 assert_eq!(
138 auth.name(),
139 Some("org.apache.cassandra.auth.PasswordAuthenticator")
140 );
141 }
142
143 #[test]
144 fn test_authenticator_none_cassandra_name() {
145 let auth = NoneAuthenticator;
146 let provider = NoneAuthenticatorProvider;
147 assert_eq!(provider.name(), None);
148 assert_eq!(auth.initial_response().into_bytes().unwrap(), vec![0]);
149 }
150}