use std::collections::HashMap;
use std::sync::Arc;
use log::{log_enabled, trace};
use crate::api::admin::Token;
use crate::commons::{Error, KrillResult};
use crate::commons::error::ApiAuthError;
use crate::config::Config;
use crate::daemon::http::auth::{AuthInfo, Role};
use crate::daemon::http::request::HyperRequest;
pub struct AuthProvider {
unix_users: HashMap<String, Arc<Role>>,
}
impl AuthProvider {
pub fn new(config: Arc<Config>) -> KrillResult<Self> {
let mut unix_users = HashMap::new();
for (k, v) in config.unix_users().iter() {
if let Some(role) = config.auth_roles.get(v) {
unix_users.insert(k.clone(), role);
} else {
return Err(Error::ConfigError(
format!("Unix user {} requested role mapping {} but it could not be found!", k, v)
));
}
}
Ok(AuthProvider {
unix_users,
})
}
pub fn authenticate(
&self, request: &HyperRequest,
) -> Result<Option<(AuthInfo, Option<Token>)>, ApiAuthError> {
if log_enabled!(log::Level::Trace) {
trace!("Attempting to authenticate the request..");
}
let user: Option<&nix::unistd::User> = request.extensions().get();
let res = match user {
Some(user) => {
if let Some(role) = self.unix_users.get(&user.name) {
Ok(Some((
AuthInfo::user(
user.name.clone(),
role.clone()
),
None
)))
} else {
Err(ApiAuthError::ApiInvalidCredentials(
format!("Unauthorised system user '{}'", user.name)
))
}
},
None => Ok(None)
};
if log_enabled!(log::Level::Trace) {
trace!("Authentication result: {res:?}");
}
res
}
}