use std::error::Error;
use log::{debug, error, info};
use users::{Group, Users, UsersCache};
pub(crate) struct User {
pub(crate) username: String,
group: Vec<Group>,
}
impl User {
pub(crate) fn new() -> Result<Self, Box<dyn Error>> {
debug!("Begin user data creation");
let userscache = UsersCache::new();
let uid = userscache.get_current_uid();
let user = match userscache.get_user_by_uid(uid) {
Some(user) => user,
None => return Err(From::from("Couldn't extract user from its UID")),
};
let username = match user.name().to_str() {
Some(name) => name.to_owned(),
None => return Err(From::from("Couldn't convert &str to string")),
};
let group = match user.groups() {
Some(group) => group,
None => {
return Err(From::from(
"Couldn't extract group membership from user data",
))
}
};
Ok(Self { username, group })
}
pub(crate) fn verify_user(&self, username: &str) -> Result<(), Box<dyn Error>> {
debug!(
"Begin to verify if {} is authorized to use Rudo",
&self.username
);
let actualuser = &self.username;
if actualuser == username {
debug!("{} has been authorized", actualuser);
Ok(())
} else {
let err = format!(
"{} is not authorized to use Rudo! Will be report to administrator!",
actualuser
);
error!("{}", err);
Err(From::from(err))
}
}
pub(crate) fn verify_group(&self, arggroup: &str) -> Result<(), Box<dyn Error>> {
debug!(
"Beginning to verify if the user is a member of {}",
arggroup
);
let group = &self.group;
let mut count: u8 = 0;
for gr in group {
if gr.name() == arggroup {
count = count.saturating_add(1);
}
}
if count == 0 {
let error = format!("User is not a member of the authorized group: {}", arggroup);
error!("{}", error);
Err(From::from(error))
} else if count == 1 {
info!("User is a member of the authorized group: {}", arggroup);
Ok(())
} else if count >= 2 {
let err = format!("{} is list multiple time", arggroup);
error!("{}", err);
Err(From::from(err))
} else {
Err(From::from("You shouldn't see this error!"))
}
}
}
#[cfg(test)]
mod tests {
use super::{Error, User};
#[test]
fn test_verify_group() -> Result<(), Box<dyn Error>> {
let userdata = User::new()?;
if userdata.verify_group("test").is_err() {
Ok(())
} else {
Err(From::from("The group should not correspond with test"))
}
}
#[test]
fn test_verify_user() -> Result<(), Box<dyn Error>> {
let userdata = User::new()?;
if userdata.verify_user("test").is_err() {
Ok(())
} else {
Err(From::from("The user should not correspond with test"))
}
}
}