Enum to discriminate primary and reg. memberships
This commit is contained in:
parent
93e958108b
commit
e9fbbd91ce
@ -9,7 +9,7 @@ What is working so far:
|
|||||||
* Parsing:
|
* Parsing:
|
||||||
* `/etc/passwd`
|
* `/etc/passwd`
|
||||||
* `/etc/shadow` (root permission needed)
|
* `/etc/shadow` (root permission needed)
|
||||||
* `/etc/group` (not yet really assigned to the users)
|
* `/etc/group`
|
||||||
* Modifying:
|
* Modifying:
|
||||||
* delete a user
|
* delete a user
|
||||||
* [x] passwd
|
* [x] passwd
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
extern crate umanux;
|
extern crate umanux;
|
||||||
|
use umanux::api::GroupRead;
|
||||||
use umanux::api::UserDBRead;
|
use umanux::api::UserDBRead;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -13,5 +14,23 @@ fn main() {
|
|||||||
|
|
||||||
for u in db.get_all_users() {
|
for u in db.get_all_users() {
|
||||||
println!("{}", u);
|
println!("{}", u);
|
||||||
|
println!(
|
||||||
|
"Groups: {:?}",
|
||||||
|
u.get_groups()
|
||||||
|
.iter()
|
||||||
|
.map(|group| {
|
||||||
|
(
|
||||||
|
format!("{:?}", group.0),
|
||||||
|
group.1.borrow().get_groupname().unwrap().to_owned(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<(String, String)>>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for group in db.get_all_groups() {
|
||||||
|
let gp = group.borrow();
|
||||||
|
println!("{}", gp);
|
||||||
|
println!("{:?}", gp.get_member_names())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,22 @@ use crate::userlib::NewFromString;
|
|||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
use crate::UserLibError;
|
use crate::UserLibError;
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::fmt::{self, Debug, Display};
|
use std::fmt::{self, Debug, Display};
|
||||||
|
use std::{cell::RefCell, convert::TryFrom};
|
||||||
use std::{cmp::Eq, rc::Rc};
|
use std::{cmp::Eq, rc::Rc};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Membership {
|
pub enum MembershipKind {
|
||||||
Primary,
|
Primary,
|
||||||
Member,
|
Member,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub struct Membership {
|
||||||
|
kind: MembershipKind,
|
||||||
|
username: crate::Username,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct Groupname {
|
pub struct Groupname {
|
||||||
groupname: String,
|
groupname: String,
|
||||||
@ -44,7 +50,7 @@ pub(crate) fn is_groupname_valid(name: &str) -> bool {
|
|||||||
crate::user::passwd_fields::is_username_valid(name)
|
crate::user::passwd_fields::is_username_valid(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Group = Rc<Inner>;
|
pub type Group = Rc<RefCell<Inner>>;
|
||||||
/// A record(line) in the user database `/etc/shadow` found in most linux systems.
|
/// A record(line) in the user database `/etc/shadow` found in most linux systems.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
@ -53,7 +59,7 @@ pub struct Inner {
|
|||||||
groupname: Groupname, /* Username. */
|
groupname: Groupname, /* Username. */
|
||||||
pub(crate) password: crate::Password, /* Usually not used (disabled with x) */
|
pub(crate) password: crate::Password, /* Usually not used (disabled with x) */
|
||||||
gid: crate::Gid, /* Group ID. */
|
gid: crate::Gid, /* Group ID. */
|
||||||
members: Vec<crate::Username>, /* Real name. */
|
members: Vec<Membership>, /* Real name. */
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
@ -65,6 +71,15 @@ impl Inner {
|
|||||||
.collect::<Vec<&str>>()
|
.collect::<Vec<&str>>()
|
||||||
.join("\n")
|
.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn append_user(&mut self, username: &str) {
|
||||||
|
self.members.push(Membership {
|
||||||
|
kind: MembershipKind::Primary,
|
||||||
|
username: crate::Username {
|
||||||
|
username: username.to_owned(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::api::GroupRead;
|
use crate::api::GroupRead;
|
||||||
@ -77,7 +92,7 @@ impl GroupRead for Inner {
|
|||||||
fn get_member_names(&self) -> Option<Vec<&str>> {
|
fn get_member_names(&self) -> Option<Vec<&str>> {
|
||||||
let mut r: Vec<&str> = Vec::new();
|
let mut r: Vec<&str> = Vec::new();
|
||||||
for u in &self.members {
|
for u in &self.members {
|
||||||
r.push(&u.username);
|
r.push(&u.username.username);
|
||||||
}
|
}
|
||||||
Some(r)
|
Some(r)
|
||||||
}
|
}
|
||||||
@ -101,14 +116,18 @@ impl Display for Inner {
|
|||||||
self.gid,
|
self.gid,
|
||||||
self.members
|
self.members
|
||||||
.iter()
|
.iter()
|
||||||
.map(|mem| format!("{}", mem))
|
.filter_map(|mem| if mem.kind == MembershipKind::Member {
|
||||||
|
Some(format!("{}", mem.username))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(",")
|
.join(",")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NewFromString for Rc<Inner> {
|
impl NewFromString for Group {
|
||||||
/// Parse a line formatted like one in `/etc/group` and construct a matching [`Group`] instance
|
/// Parse a line formatted like one in `/etc/group` and construct a matching [`Group`] instance
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -119,7 +138,7 @@ impl NewFromString for Rc<Inner> {
|
|||||||
/// "teste:x:1002:test,teste".to_owned(),
|
/// "teste:x:1002:test,teste".to_owned(),
|
||||||
/// 0,
|
/// 0,
|
||||||
/// ).unwrap();
|
/// ).unwrap();
|
||||||
/// assert_eq!(grp.get_groupname().unwrap(), "teste");
|
/// assert_eq!(grp.borrow().get_groupname().unwrap(), "teste");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
@ -127,14 +146,14 @@ impl NewFromString for Rc<Inner> {
|
|||||||
fn new_from_string(line: String, position: u32) -> Result<Self, UserLibError> {
|
fn new_from_string(line: String, position: u32) -> Result<Self, UserLibError> {
|
||||||
let elements: Vec<String> = line.split(':').map(ToString::to_string).collect();
|
let elements: Vec<String> = line.split(':').map(ToString::to_string).collect();
|
||||||
if elements.len() == 4 {
|
if elements.len() == 4 {
|
||||||
Ok(Self::new(Inner {
|
Ok(Self::new(RefCell::new(Inner {
|
||||||
pos: position,
|
pos: position,
|
||||||
source: line,
|
source: line,
|
||||||
groupname: Groupname::try_from(elements.get(0).unwrap().to_string())?,
|
groupname: Groupname::try_from(elements.get(0).unwrap().to_string())?,
|
||||||
password: crate::Password::Disabled,
|
password: crate::Password::Disabled,
|
||||||
gid: crate::Gid::try_from(elements.get(2).unwrap().to_string())?,
|
gid: crate::Gid::try_from(elements.get(2).unwrap().to_string())?,
|
||||||
members: parse_members_list(elements.get(3).unwrap()),
|
members: parse_members_list(elements.get(3).unwrap()),
|
||||||
}))
|
})))
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
Err(format!(
|
||||||
"Failed to parse: not enough elements ({}): {:?}",
|
"Failed to parse: not enough elements ({}): {:?}",
|
||||||
@ -146,7 +165,7 @@ impl NewFromString for Rc<Inner> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_members_list(source: &str) -> Vec<crate::Username> {
|
fn parse_members_list(source: &str) -> Vec<Membership> {
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
for mem in source.split(',').filter_map(|x| {
|
for mem in source.split(',').filter_map(|x| {
|
||||||
if x.is_empty() {
|
if x.is_empty() {
|
||||||
@ -155,7 +174,10 @@ fn parse_members_list(source: &str) -> Vec<crate::Username> {
|
|||||||
Some(x.to_string())
|
Some(x.to_string())
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
res.push(crate::Username::try_from(mem).expect("failed to parse username"));
|
res.push(Membership {
|
||||||
|
kind: MembershipKind::Member,
|
||||||
|
username: crate::Username::try_from(mem).expect("failed to parse username"),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@ -164,18 +186,18 @@ fn parse_members_list(source: &str) -> Vec<crate::Username> {
|
|||||||
fn test_parse_and_back_identity() {
|
fn test_parse_and_back_identity() {
|
||||||
let line = "teste:x:1002:test,teste";
|
let line = "teste:x:1002:test,teste";
|
||||||
let line2: Group = Group::new_from_string(line.to_owned(), 0).unwrap();
|
let line2: Group = Group::new_from_string(line.to_owned(), 0).unwrap();
|
||||||
assert_eq!(format!("{}", line2), line);
|
assert_eq!(format!("{}", line2.borrow()), line);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_groupname() {
|
fn test_groupname() {
|
||||||
let line = "teste:x:1002:test,teste";
|
let line = "teste:x:1002:test,teste";
|
||||||
let line2 = Group::new_from_string(line.to_owned(), 0).unwrap();
|
let line2 = Group::new_from_string(line.to_owned(), 0).unwrap();
|
||||||
assert_eq!(line2.get_groupname().unwrap(), "teste");
|
assert_eq!(line2.borrow().get_groupname().unwrap(), "teste");
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_root_group() {
|
fn test_root_group() {
|
||||||
let line = "root:x:0:";
|
let line = "root:x:0:";
|
||||||
let line2 = Group::new_from_string(line.to_owned(), 0).unwrap();
|
let line2 = Group::new_from_string(line.to_owned(), 0).unwrap();
|
||||||
assert_eq!(line2.get_groupname().unwrap(), "root");
|
assert_eq!(line2.borrow().get_groupname().unwrap(), "root");
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ pub struct User {
|
|||||||
gecos: crate::Gecos, /* Real name. */
|
gecos: crate::Gecos, /* Real name. */
|
||||||
home_dir: crate::HomeDir, /* Home directory. */
|
home_dir: crate::HomeDir, /* Home directory. */
|
||||||
shell_path: crate::ShellPath, /* Shell program. */
|
shell_path: crate::ShellPath, /* Shell program. */
|
||||||
groups: Vec<(crate::group::Membership, crate::Group)>,
|
groups: Vec<(crate::group::MembershipKind, crate::Group)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
@ -70,7 +70,7 @@ impl User {
|
|||||||
|
|
||||||
pub fn add_group(
|
pub fn add_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
group_type: crate::group::Membership,
|
group_type: crate::group::MembershipKind,
|
||||||
group: crate::Group,
|
group: crate::Group,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.groups.push((group_type, group));
|
self.groups.push((group_type, group));
|
||||||
@ -78,7 +78,7 @@ impl User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn get_groups(&self) -> &Vec<(crate::group::Membership, crate::Group)> {
|
pub const fn get_groups(&self) -> &Vec<(crate::group::MembershipKind, crate::Group)> {
|
||||||
&self.groups
|
&self.groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,9 @@ impl UserDBLocal {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let shadow_entries: Vec<crate::Shadow> = string_to(shadow_content);
|
let shadow_entries: Vec<crate::Shadow> = string_to(shadow_content);
|
||||||
let mut users = user_vec_to_hashmap(string_to(passwd_content));
|
let mut users = user_vec_to_hashmap(string_to(passwd_content));
|
||||||
let groups = string_to(group_content);
|
let mut groups = string_to(group_content);
|
||||||
shadow_to_users(&mut users, shadow_entries);
|
shadow_to_users(&mut users, shadow_entries);
|
||||||
groups_to_users(&mut users, &groups);
|
groups_to_users(&mut users, &mut groups);
|
||||||
Self {
|
Self {
|
||||||
source_files: files::Files {
|
source_files: files::Files {
|
||||||
passwd: None,
|
passwd: None,
|
||||||
@ -65,9 +65,9 @@ impl UserDBLocal {
|
|||||||
|
|
||||||
let mut users = user_vec_to_hashmap(string_to(&my_passwd_lines));
|
let mut users = user_vec_to_hashmap(string_to(&my_passwd_lines));
|
||||||
let passwds: Vec<crate::Shadow> = string_to(&my_shadow_lines);
|
let passwds: Vec<crate::Shadow> = string_to(&my_shadow_lines);
|
||||||
let groups: Vec<crate::Group> = string_to(&my_group_lines);
|
let mut groups: Vec<crate::Group> = string_to(&my_group_lines);
|
||||||
shadow_to_users(&mut users, passwds);
|
shadow_to_users(&mut users, passwds);
|
||||||
groups_to_users(&mut users, &groups);
|
groups_to_users(&mut users, &mut groups);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
source_files: files,
|
source_files: files,
|
||||||
users,
|
users,
|
||||||
@ -119,7 +119,7 @@ impl UserDBLocal {
|
|||||||
group_file_content: &str,
|
group_file_content: &str,
|
||||||
locked_g: &mut files::LockedFileGuard,
|
locked_g: &mut files::LockedFileGuard,
|
||||||
) -> Result<(), UserLibError> {
|
) -> Result<(), UserLibError> {
|
||||||
let modified_g = group.remove_in(group_file_content);
|
let modified_g = group.borrow().remove_in(group_file_content);
|
||||||
let replace_result = locked_g.replace_contents(modified_g);
|
let replace_result = locked_g.replace_contents(modified_g);
|
||||||
match replace_result {
|
match replace_result {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
@ -147,7 +147,7 @@ impl UserDBLocal {
|
|||||||
|
|
||||||
fn get_group_pos_by_id(&self, id: u32) -> Option<(&crate::Group, usize)> {
|
fn get_group_pos_by_id(&self, id: u32) -> Option<(&crate::Group, usize)> {
|
||||||
for (i, group) in self.groups.iter().enumerate() {
|
for (i, group) in self.groups.iter().enumerate() {
|
||||||
if group.get_gid()? == id {
|
if group.borrow().get_gid()? == id {
|
||||||
return Some((group, i));
|
return Some((group, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,6 +197,7 @@ impl UserDBWrite for UserDBLocal {
|
|||||||
let group = self.get_group_pos_by_id(user.get_gid());
|
let group = self.get_group_pos_by_id(user.get_gid());
|
||||||
if let Some((group, id)) = group {
|
if let Some((group, id)) = group {
|
||||||
if group
|
if group
|
||||||
|
.borrow()
|
||||||
.get_member_names()
|
.get_member_names()
|
||||||
.expect("groups have to have members")
|
.expect("groups have to have members")
|
||||||
.len()
|
.len()
|
||||||
@ -207,7 +208,7 @@ impl UserDBWrite for UserDBLocal {
|
|||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
"The primary group {} was not empty and is thus not removed.",
|
"The primary group {} was not empty and is thus not removed.",
|
||||||
group.get_groupname().unwrap()
|
group.borrow().get_groupname().unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -293,7 +294,7 @@ impl UserDBRead for UserDBLocal {
|
|||||||
|
|
||||||
fn get_group_by_name(&self, name: &str) -> Option<&crate::Group> {
|
fn get_group_by_name(&self, name: &str) -> Option<&crate::Group> {
|
||||||
for group in &self.groups {
|
for group in &self.groups {
|
||||||
if group.get_groupname()? == name {
|
if group.borrow().get_groupname()? == name {
|
||||||
return Some(group);
|
return Some(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,7 +303,7 @@ impl UserDBRead for UserDBLocal {
|
|||||||
|
|
||||||
fn get_group_by_id(&self, id: u32) -> Option<&crate::Group> {
|
fn get_group_by_id(&self, id: u32) -> Option<&crate::Group> {
|
||||||
for group in &self.groups {
|
for group in &self.groups {
|
||||||
if group.get_gid()? == id {
|
if group.borrow().get_gid()? == id {
|
||||||
return Some(group);
|
return Some(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,7 +327,9 @@ impl UserDBValidation for UserDBLocal {
|
|||||||
|
|
||||||
fn is_gid_valid_and_free(&self, gid: u32) -> bool {
|
fn is_gid_valid_and_free(&self, gid: u32) -> bool {
|
||||||
warn!("No valid check, only free check");
|
warn!("No valid check, only free check");
|
||||||
self.groups.iter().all(|x| x.get_gid().unwrap() != gid)
|
self.groups
|
||||||
|
.iter()
|
||||||
|
.all(|x| x.borrow().get_gid().unwrap() != gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_groupname_valid_and_free(&self, name: &str) -> bool {
|
fn is_groupname_valid_and_free(&self, name: &str) -> bool {
|
||||||
@ -334,7 +337,7 @@ impl UserDBValidation for UserDBLocal {
|
|||||||
let free = self
|
let free = self
|
||||||
.groups
|
.groups
|
||||||
.iter()
|
.iter()
|
||||||
.all(|x| x.get_groupname().unwrap() != name);
|
.all(|x| x.borrow().get_groupname().unwrap() != name);
|
||||||
valid && free
|
valid && free
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,28 +353,39 @@ fn file_to_string(file: &File) -> Result<String, crate::UserLibError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn groups_to_users<'a>(users: &'a mut UserList, groups: &'a [crate::Group]) -> &'a mut UserList {
|
fn groups_to_users<'a>(
|
||||||
for group in groups {
|
users: &'a mut UserList,
|
||||||
match group.get_member_names() {
|
groups: &'a mut [crate::Group],
|
||||||
|
) -> &'a mut UserList {
|
||||||
|
// Populate the regular groups
|
||||||
|
|
||||||
|
for group in groups.iter() {
|
||||||
|
match group.borrow().get_member_names() {
|
||||||
Some(usernames) => {
|
Some(usernames) => {
|
||||||
for username in usernames {
|
for username in usernames {
|
||||||
if let Some(user) = users.get_mut(username) {
|
if let Some(user) = users.get_mut(username) {
|
||||||
user.add_group(crate::group::Membership::Member, group.clone());
|
user.add_group(crate::group::MembershipKind::Member, group.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => continue,
|
None => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate the primary membership
|
||||||
for user in users.values_mut() {
|
for user in users.values_mut() {
|
||||||
let gid = user.get_gid();
|
let gid = user.get_gid();
|
||||||
let grouplist: Vec<&crate::Group> = groups
|
let grouplist: Vec<&crate::Group> = groups
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|g| g.get_gid().unwrap() == gid)
|
.filter(|g| g.borrow().get_gid().unwrap() == gid)
|
||||||
.collect();
|
.collect();
|
||||||
if grouplist.len() == 1 {
|
if grouplist.len() == 1 {
|
||||||
let group = *grouplist.first().unwrap();
|
let group = *grouplist.first().unwrap();
|
||||||
user.add_group(crate::group::Membership::Primary, group.clone());
|
group.borrow_mut().append_user(
|
||||||
|
user.get_username()
|
||||||
|
.expect("Users without username are not supported"),
|
||||||
|
);
|
||||||
|
user.add_group(crate::group::MembershipKind::Primary, group.clone());
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
"Somehow the group with gid {} was found {} times",
|
"Somehow the group with gid {} was found {} times",
|
||||||
@ -457,10 +471,10 @@ fn test_creator_user_db_local() {
|
|||||||
let (member_group1, group1) = user.get_groups().first().unwrap();
|
let (member_group1, group1) = user.get_groups().first().unwrap();
|
||||||
let (member_group2, group2) = user.get_groups().get(1).unwrap();
|
let (member_group2, group2) = user.get_groups().get(1).unwrap();
|
||||||
|
|
||||||
assert_eq!(*member_group1, crate::group::Membership::Member);
|
assert_eq!(*member_group1, crate::group::MembershipKind::Member);
|
||||||
assert_eq!(group1.get_groupname(), Some("another"));
|
assert_eq!(group1.borrow().get_groupname(), Some("another"));
|
||||||
assert_eq!(*member_group2, crate::group::Membership::Primary);
|
assert_eq!(*member_group2, crate::group::MembershipKind::Primary);
|
||||||
assert_eq!(group2.get_groupname(), Some("teste"));
|
assert_eq!(group2.borrow().get_groupname(), Some("teste"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,7 +487,15 @@ fn test_parsing_local_database() {
|
|||||||
let my_passwd_lines = file_to_string(&pwdfile).unwrap();
|
let my_passwd_lines = file_to_string(&pwdfile).unwrap();
|
||||||
let my_group_lines = file_to_string(&grpfile).unwrap();
|
let my_group_lines = file_to_string(&grpfile).unwrap();
|
||||||
let data = UserDBLocal::import_from_strings(&my_passwd_lines, "", &my_group_lines);
|
let data = UserDBLocal::import_from_strings(&my_passwd_lines, "", &my_group_lines);
|
||||||
assert_eq!(data.groups.get(0).unwrap().get_groupname().unwrap(), "root");
|
assert_eq!(
|
||||||
|
data.groups
|
||||||
|
.get(0)
|
||||||
|
.unwrap()
|
||||||
|
.borrow()
|
||||||
|
.get_groupname()
|
||||||
|
.unwrap(),
|
||||||
|
"root"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -495,11 +517,19 @@ fn test_user_db_read_implementation() {
|
|||||||
assert!(data.get_all_groups().len() > 10);
|
assert!(data.get_all_groups().len() > 10);
|
||||||
assert!(data.get_group_by_name("root").is_some());
|
assert!(data.get_group_by_name("root").is_some());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
data.get_group_by_name("root").unwrap().get_gid().unwrap(),
|
data.get_group_by_name("root")
|
||||||
|
.unwrap()
|
||||||
|
.borrow()
|
||||||
|
.get_gid()
|
||||||
|
.unwrap(),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
data.get_group_by_id(0).unwrap().get_groupname().unwrap(),
|
data.get_group_by_id(0)
|
||||||
|
.unwrap()
|
||||||
|
.borrow()
|
||||||
|
.get_groupname()
|
||||||
|
.unwrap(),
|
||||||
"root"
|
"root"
|
||||||
);
|
);
|
||||||
assert!(data.get_user_by_name("norealnameforsure").is_none());
|
assert!(data.get_user_by_name("norealnameforsure").is_none());
|
||||||
|
Loading…
Reference in New Issue
Block a user