use std::sync::Arc;
use crate::acl::{AccessControlList, user_handle::UserHandle};
pub type AuthenticateInternal<'a> = &'a mut dyn FnMut(&Arc<UserHandle>, &[u8], &[u8]) -> bool;
pub struct GarnetAclAuthenticator {
pub acl: Arc<AccessControlList>,
pub user_handle: Option<Arc<UserHandle>>,
}
impl GarnetAclAuthenticator {
pub fn new(acl: Arc<AccessControlList>) -> Self {
Self {
acl,
user_handle: None,
}
}
pub fn authenticate(
&mut self,
username: &[u8],
password: &[u8],
authenticate_internal: AuthenticateInternal<'_>,
) -> bool {
let uname = super::ascii_sanitize(username);
let user_handle = if uname.is_empty() {
self.acl.get_default_user_handle()
} else {
self.acl.get_user_handle(&uname)
};
let Some(user_handle) = user_handle else {
return false;
};
if authenticate_internal(&user_handle, username, password) {
self.user_handle = Some(user_handle);
return true;
}
false
}
pub fn get_user_handle(&self) -> Option<&Arc<UserHandle>> {
self.user_handle.as_ref()
}
pub fn get_access_control_list(&self) -> &Arc<AccessControlList> {
&self.acl
}
}
impl GarnetAclAuthenticator {
pub fn is_authenticated(&self) -> bool {
self.user_handle.is_some()
}
pub fn can_authenticate(&self) -> bool {
true
}
pub fn has_acl_support(&self) -> bool {
true
}
}