tarantool/
auth.rs

1use serde::{Deserialize, Serialize};
2
3#[cfg(not(feature = "picodata"))]
4crate::define_str_enum! {
5    #[derive(Default)]
6    pub enum AuthMethod {
7        #[default]
8        ChapSha1 = "chap-sha1",
9    }
10}
11
12#[cfg(not(feature = "picodata"))]
13impl AuthMethod {
14    pub const DEFAULT: Self = Self::ChapSha1;
15}
16
17#[cfg(feature = "picodata")]
18crate::define_str_enum! {
19    #[derive(Default)]
20    pub enum AuthMethod {
21        ChapSha1 = "chap-sha1",
22        #[default]
23        Md5 = "md5",
24        Ldap = "ldap",
25    }
26}
27
28#[cfg(feature = "picodata")]
29impl AuthMethod {
30    pub const DEFAULT: Self = Self::Md5;
31}
32
33#[cfg(feature = "picodata")]
34mod picodata {
35    use super::AuthMethod;
36    use crate::ffi::tarantool as ffi;
37    use std::mem::MaybeUninit;
38    use std::ops::Range;
39
40    pub(super) fn auth_data_prepare(method: &AuthMethod, user: &str, password: &str) -> String {
41        let Range {
42            start: pwd_start,
43            end: pwd_end,
44        } = password.as_bytes().as_ptr_range();
45        let Range {
46            start: user_start,
47            end: user_end,
48        } = user.as_bytes().as_ptr_range();
49        let Range {
50            start: auth_start,
51            end: auth_end,
52        } = method.as_str().as_bytes().as_ptr_range();
53        let mut data = MaybeUninit::uninit();
54        let mut data_end = MaybeUninit::uninit();
55        let svp = unsafe { ffi::box_region_used() };
56        unsafe {
57            ffi::box_auth_data_prepare(
58                auth_start as _,
59                auth_end as _,
60                pwd_start as _,
61                pwd_end as _,
62                user_start as _,
63                user_end as _,
64                data.as_mut_ptr(),
65                data_end.as_mut_ptr(),
66            );
67        }
68        let data = unsafe { data.assume_init() };
69        let data_end = unsafe { data_end.assume_init() };
70        let bytes: &[u8] = unsafe {
71            std::slice::from_raw_parts(data as *const u8, data_end.offset_from(data) as usize)
72        };
73        let auth_data = rmp_serde::from_slice(bytes).unwrap();
74        unsafe { ffi::box_region_truncate(svp) };
75        auth_data
76    }
77}
78
79pub struct AuthData(String);
80
81impl AuthData {
82    #[cfg(feature = "picodata")]
83    pub fn new(method: &AuthMethod, user: &str, password: &str) -> Self {
84        let data = picodata::auth_data_prepare(method, user, password);
85        Self(data)
86    }
87
88    pub fn into_string(self) -> String {
89        self.0
90    }
91}
92
93#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
94pub struct AuthDef {
95    pub method: AuthMethod,
96    /// Base64 encoded digest.
97    pub data: String,
98}
99
100impl AuthDef {
101    pub fn new(method: AuthMethod, data: String) -> Self {
102        Self { method, data }
103    }
104}