use serde::{Deserialize, Serialize};
#[cfg(not(feature = "picodata"))]
crate::define_str_enum! {
#[derive(Default)]
pub enum AuthMethod {
#[default]
ChapSha1 = "chap-sha1",
}
}
#[cfg(not(feature = "picodata"))]
impl AuthMethod {
pub const DEFAULT: Self = Self::ChapSha1;
}
#[cfg(feature = "picodata")]
crate::define_str_enum! {
#[derive(Default)]
pub enum AuthMethod {
#[default]
Md5 = "md5",
ScramSha256 = "scram-sha256",
ChapSha1 = "chap-sha1",
Ldap = "ldap",
}
}
#[cfg(feature = "picodata")]
impl AuthMethod {
pub const DEFAULT: Self = Self::Md5;
}
#[cfg(feature = "picodata")]
mod picodata {
use super::AuthMethod;
use crate::ffi::tarantool as ffi;
use std::mem::MaybeUninit;
use std::ops::Range;
pub(super) fn auth_data_prepare(method: &AuthMethod, user: &str, password: &str) -> String {
let Range {
start: pwd_start,
end: pwd_end,
} = password.as_bytes().as_ptr_range();
let Range {
start: user_start,
end: user_end,
} = user.as_bytes().as_ptr_range();
let Range {
start: auth_start,
end: auth_end,
} = method.as_str().as_bytes().as_ptr_range();
let mut data = MaybeUninit::uninit();
let mut data_end = MaybeUninit::uninit();
let svp = unsafe { ffi::box_region_used() };
unsafe {
ffi::box_auth_data_prepare(
auth_start as _,
auth_end as _,
pwd_start as _,
pwd_end as _,
user_start as _,
user_end as _,
data.as_mut_ptr(),
data_end.as_mut_ptr(),
);
}
let data = unsafe { data.assume_init() };
let data_end = unsafe { data_end.assume_init() };
let bytes: &[u8] = unsafe {
std::slice::from_raw_parts(data as *const u8, data_end.offset_from(data) as usize)
};
let auth_data = rmp_serde::from_slice(bytes).unwrap();
unsafe { ffi::box_region_truncate(svp) };
auth_data
}
}
pub struct AuthData(String);
impl AuthData {
#[cfg(feature = "picodata")]
pub fn new(method: &AuthMethod, user: &str, password: &str) -> Self {
let data = picodata::auth_data_prepare(method, user, password);
Self(data)
}
pub fn into_string(self) -> String {
self.0
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct AuthDef {
pub method: AuthMethod,
pub data: String,
}
impl AuthDef {
pub fn new(method: AuthMethod, data: String) -> Self {
Self { method, data }
}
}