use std::collections::HashMap;
use std::ffi::OsStr;
use std::sync::Arc;
pub use libc::{uid_t, gid_t};
pub use base::{User, Group};
pub use traits::{Users, Groups};
pub struct MockUsers {
users: HashMap<uid_t, Arc<User>>,
groups: HashMap<gid_t, Arc<Group>>,
uid: uid_t,
}
impl MockUsers {
pub fn with_current_uid(current_uid: uid_t) -> Self {
Self {
users: HashMap::new(),
groups: HashMap::new(),
uid: current_uid,
}
}
pub fn add_user(&mut self, user: User) -> Option<Arc<User>> {
self.users.insert(user.uid(), Arc::new(user))
}
pub fn add_group(&mut self, group: Group) -> Option<Arc<Group>> {
self.groups.insert(group.gid(), Arc::new(group))
}
}
impl Users for MockUsers {
fn get_user_by_uid(&self, uid: uid_t) -> Option<Arc<User>> {
self.users.get(&uid).cloned()
}
fn get_user_by_name<S: AsRef<OsStr> + ?Sized>(&self, username: &S) -> Option<Arc<User>> {
self.users.values().find(|u| u.name() == username.as_ref()).cloned()
}
fn get_current_uid(&self) -> uid_t {
self.uid
}
fn get_current_username(&self) -> Option<Arc<OsStr>> {
self.users.get(&self.uid).map(|u| Arc::clone(&u.name_arc))
}
fn get_effective_uid(&self) -> uid_t {
self.uid
}
fn get_effective_username(&self) -> Option<Arc<OsStr>> {
self.users.get(&self.uid).map(|u| Arc::clone(&u.name_arc))
}
}
impl Groups for MockUsers {
fn get_group_by_gid(&self, gid: gid_t) -> Option<Arc<Group>> {
self.groups.get(&gid).cloned()
}
fn get_group_by_name<S: AsRef<OsStr> + ?Sized>(&self, group_name: &S) -> Option<Arc<Group>> {
self.groups.values().find(|g| g.name() == group_name.as_ref()).cloned()
}
fn get_current_gid(&self) -> uid_t {
self.uid
}
fn get_current_groupname(&self) -> Option<Arc<OsStr>> {
self.groups.get(&self.uid).map(|u| Arc::clone(&u.name_arc))
}
fn get_effective_gid(&self) -> uid_t {
self.uid
}
fn get_effective_groupname(&self) -> Option<Arc<OsStr>> {
self.groups.get(&self.uid).map(|u| Arc::clone(&u.name_arc))
}
}
#[cfg(test)]
mod test {
use super::MockUsers;
use base::{User, Group};
use traits::{Users, Groups};
use std::ffi::OsStr;
use std::sync::Arc;
#[test]
fn current_username() {
let mut users = MockUsers::with_current_uid(1337);
users.add_user(User::new(1337, "fred", 101));
assert_eq!(Some(Arc::from(OsStr::new("fred"))),
users.get_current_username())
}
#[test]
fn no_current_username() {
let users = MockUsers::with_current_uid(1337);
assert_eq!(None, users.get_current_username())
}
#[test]
fn uid() {
let mut users = MockUsers::with_current_uid(0);
users.add_user(User::new(1337, "fred", 101));
assert_eq!(Some(Arc::from(OsStr::new("fred"))),
users.get_user_by_uid(1337).map(|u| Arc::clone(&u.name_arc)))
}
#[test]
fn username() {
let mut users = MockUsers::with_current_uid(1337);
users.add_user(User::new(1440, "fred", 101));
assert_eq!(Some(1440),
users.get_user_by_name("fred").map(|u| u.uid()))
}
#[test]
fn no_username() {
let mut users = MockUsers::with_current_uid(1337);
users.add_user(User::new(1337, "fred", 101));
assert_eq!(None,
users.get_user_by_name("criminy").map(|u| u.uid()))
}
#[test]
fn no_uid() {
let users = MockUsers::with_current_uid(0);
assert_eq!(None,
users.get_user_by_uid(1337).map(|u| Arc::clone(&u.name_arc)))
}
#[test]
fn gid() {
let mut users = MockUsers::with_current_uid(0);
users.add_group(Group::new(1337, "fred"));
assert_eq!(Some(Arc::from(OsStr::new("fred"))),
users.get_group_by_gid(1337).map(|g| Arc::clone(&g.name_arc)))
}
#[test]
fn group_name() {
let mut users = MockUsers::with_current_uid(0);
users.add_group(Group::new(1337, "fred"));
assert_eq!(Some(1337),
users.get_group_by_name("fred").map(|g| g.gid()))
}
#[test]
fn no_group_name() {
let mut users = MockUsers::with_current_uid(0);
users.add_group(Group::new(1337, "fred"));
assert_eq!(None,
users.get_group_by_name("santa").map(|g| g.gid()))
}
#[test]
fn no_gid() {
let users = MockUsers::with_current_uid(0);
assert_eq!(None,
users.get_group_by_gid(1337).map(|g| Arc::clone(&g.name_arc)))
}
}