cdrs_async/
authenticators.rs

1use cassandra_proto::types::CBytes;
2
3/// Generic CDRS authenticator structure.
4pub struct Authenticator {
5  cassandra_name: Option<String>,
6  auth_token: CBytes,
7}
8
9impl Authenticator {
10  /// Returns authentication token wich will be used
11  /// by a DB server for session authorisation.
12  pub fn get_auth_token(&self) -> CBytes {
13    self.auth_token.clone()
14  }
15
16  /// Returns authentication method name. CDRS will use it
17  /// to match with a method requested by a DB server.
18  pub fn get_cassandra_name(&self) -> Option<String> {
19    self.cassandra_name.clone()
20  }
21}
22
23/// Password authenticator. CDRS will use it if a DB server requested
24/// `org.apache.cassandra.auth.PasswordAuthenticator` authentication.
25#[derive(Debug, Clone)]
26pub struct PasswordAuthenticator {
27  username: String,
28  password: String,
29}
30
31impl PasswordAuthenticator {
32  pub fn new<S: ToString>(username: S, password: S) -> PasswordAuthenticator {
33    PasswordAuthenticator {
34      username: username.to_string(),
35      password: password.to_string(),
36    }
37  }
38}
39
40impl Into<Authenticator> for PasswordAuthenticator {
41  fn into(self) -> Authenticator {
42    let auth_token = {
43      let mut v = vec![0];
44      v.extend_from_slice(self.username.as_bytes());
45      v.push(0);
46      v.extend_from_slice(self.password.as_bytes());
47
48      CBytes::new(v)
49    };
50
51    Authenticator {
52      cassandra_name: Some("org.apache.cassandra.auth.PasswordAuthenticator".into()),
53      auth_token,
54    }
55  }
56}
57
58/// Authenticator which can be used if a DB server
59/// has authentication disabled.
60#[derive(Debug, Clone)]
61pub struct NoneAuthenticator;
62
63impl Into<Authenticator> for NoneAuthenticator {
64  fn into(self) -> Authenticator {
65    Authenticator {
66      cassandra_name: None,
67      auth_token: CBytes::new(vec![0]),
68    }
69  }
70}
71
72#[cfg(test)]
73mod tests {
74  use super::*;
75
76  #[test]
77  fn test_password_authenticator_trait_impl() {
78    let authenticator = PasswordAuthenticator::new("a", "a");
79    let _ = authenticator_tester(Box::new(authenticator.into()));
80  }
81
82  #[test]
83  fn test_password_authenticator_new() {
84    PasswordAuthenticator::new("foo", "bar");
85  }
86
87  #[test]
88  fn test_password_authenticator_get_cassandra_name() {
89    let auth: Authenticator = PasswordAuthenticator::new("foo", "bar").into();
90    assert_eq!(
91      auth.get_cassandra_name(),
92      Some("org.apache.cassandra.auth.PasswordAuthenticator".into())
93    );
94  }
95
96  #[test]
97  fn test_password_authenticator_get_auth_token() {
98    let auth: Authenticator = PasswordAuthenticator::new("foo", "bar").into();
99    let mut expected_token = vec![0];
100    expected_token.extend_from_slice("foo".as_bytes());
101    expected_token.push(0);
102    expected_token.extend_from_slice("bar".as_bytes());
103
104    assert_eq!(auth.get_auth_token().into_plain().unwrap(), expected_token);
105  }
106
107  #[test]
108  fn test_authenticator_none_get_cassandra_name() {
109    let auth: Authenticator = (NoneAuthenticator {}).into();
110    assert_eq!(auth.get_cassandra_name(), None);
111    assert_eq!(auth.get_auth_token().into_plain().unwrap(), vec![0]);
112  }
113
114  fn authenticator_tester(_authenticator: Box<Authenticator>) {}
115}