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 pub data: String,
98}
99
100impl AuthDef {
101 pub fn new(method: AuthMethod, data: String) -> Self {
102 Self { method, data }
103 }
104}