Compare commits
No commits in common. "f33ba8e7675876d249d4ca660014adb733e554ee" and "134b97cfecd677c422e851d3cf8b6c97ad6cd5ec" have entirely different histories.
f33ba8e767
...
134b97cfec
@ -1,5 +1,11 @@
|
|||||||
extern crate adduser;
|
extern crate adduser;
|
||||||
|
|
||||||
|
use adduser::NewFromString;
|
||||||
|
use adduser::Shadow;
|
||||||
|
use adduser::User;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{prelude::*, BufReader};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
simplelog::CombinedLogger::init(vec![simplelog::TermLogger::new(
|
simplelog::CombinedLogger::init(vec![simplelog::TermLogger::new(
|
||||||
simplelog::LevelFilter::Warn,
|
simplelog::LevelFilter::Warn,
|
||||||
@ -7,11 +13,24 @@ fn main() {
|
|||||||
simplelog::TerminalMode::Mixed,
|
simplelog::TerminalMode::Mixed,
|
||||||
)])
|
)])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
use adduser::api::UserDBRead;
|
let file: File = File::open("/etc/passwd").unwrap();
|
||||||
|
let reader: BufReader<File> = BufReader::new(file);
|
||||||
|
|
||||||
let db = adduser::UserDBLocal::load_files(adduser::Files::default());
|
for line in reader.lines() {
|
||||||
|
let line: String = line.unwrap();
|
||||||
|
println!("{}", User::new_from_string(line).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
for u in db.get_all_users() {
|
let line = "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::".to_string();
|
||||||
println!("{}", u);
|
assert_eq!(
|
||||||
}
|
format!("{}", Shadow::new_from_string(line.clone()).unwrap()),
|
||||||
|
line
|
||||||
|
);
|
||||||
|
|
||||||
|
// let pwd = User::default();
|
||||||
|
// let pwd2 =
|
||||||
|
// User::new_from_string("howdy:notencrypted:1001:1001:not done:/home/test:/bin/bash");
|
||||||
|
// println!("Test struct: {}", pwd);
|
||||||
|
|
||||||
|
// assert_eq!(pwd, pwd2.unwrap())
|
||||||
}
|
}
|
||||||
|
@ -106,15 +106,15 @@ impl NewFromString for Group {
|
|||||||
/// use crate::adduser::api::GroupRead;
|
/// use crate::adduser::api::GroupRead;
|
||||||
/// use adduser::NewFromString;
|
/// use adduser::NewFromString;
|
||||||
/// let grp = adduser::Group::new_from_string(
|
/// let grp = adduser::Group::new_from_string(
|
||||||
/// "teste:x:1002:test,teste".to_owned(),
|
/// "teste:x:1002:test,teste".to_owned()
|
||||||
/// 0,
|
|
||||||
/// ).unwrap();
|
/// ).unwrap();
|
||||||
/// assert_eq!(grp.get_groupname().unwrap(), "teste");
|
/// assert_eq!(grp.get_groupname().unwrap(), "teste");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
|
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
|
||||||
fn new_from_string(line: String, position: u32) -> Result<Self, UserLibError> {
|
fn new_from_string(line: String) -> Result<Self, UserLibError> {
|
||||||
|
println!("{}", &line);
|
||||||
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 {
|
Ok(Self {
|
||||||
@ -150,19 +150,19 @@ fn parse_members_list(source: &str) -> Vec<crate::Username> {
|
|||||||
#[test]
|
#[test]
|
||||||
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::new_from_string(line.to_owned(), 0).unwrap();
|
let line2 = Group::new_from_string(line.to_owned()).unwrap();
|
||||||
assert_eq!(format!("{}", line2), line);
|
assert_eq!(format!("{}", line2), 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()).unwrap();
|
||||||
assert_eq!(line2.get_groupname().unwrap(), "teste");
|
assert_eq!(line2.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()).unwrap();
|
||||||
assert_eq!(line2.get_groupname().unwrap(), "root");
|
assert_eq!(line2.get_groupname().unwrap(), "root");
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,5 @@ pub use user::passwd_fields::{
|
|||||||
};
|
};
|
||||||
pub use user::shadow_fields::Shadow;
|
pub use user::shadow_fields::Shadow;
|
||||||
pub use user::User;
|
pub use user::User;
|
||||||
pub use userlib::{Files, NewFromString, UserDBLocal};
|
pub use userlib::NewFromString;
|
||||||
pub use userlib_error::UserLibError;
|
pub use userlib_error::UserLibError;
|
||||||
|
@ -205,6 +205,7 @@ fn test_gecos_getters() {
|
|||||||
assert_eq!(res_simple.get_comment(), Some("A böring comment →"));
|
assert_eq!(res_simple.get_comment(), Some("A böring comment →"));
|
||||||
|
|
||||||
assert_eq!(res_detail.get_comment(), None);
|
assert_eq!(res_detail.get_comment(), None);
|
||||||
|
println!("{:?}", res_detail);
|
||||||
assert_eq!(res_detail.get_full_name(), Some("Full Name"));
|
assert_eq!(res_detail.get_full_name(), Some("Full Name"));
|
||||||
assert_eq!(res_detail.get_room(), Some("504"));
|
assert_eq!(res_detail.get_room(), Some("504"));
|
||||||
assert_eq!(res_detail.get_phone_work(), Some("11345342"));
|
assert_eq!(res_detail.get_phone_work(), Some("11345342"));
|
||||||
|
@ -10,7 +10,6 @@ use std::fmt::{self, Display};
|
|||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
source: String,
|
source: String,
|
||||||
pos: u32,
|
|
||||||
username: crate::Username, /* Username. */
|
username: crate::Username, /* Username. */
|
||||||
pub(crate) password: crate::Password, /* Hashed passphrase, if shadow database not in use (see shadow.h). */
|
pub(crate) password: crate::Password, /* Hashed passphrase, if shadow database not in use (see shadow.h). */
|
||||||
uid: crate::Uid, /* User ID. */
|
uid: crate::Uid, /* User ID. */
|
||||||
@ -28,13 +27,13 @@ impl NewFromString for User {
|
|||||||
/// use crate::adduser::api::UserRead;
|
/// use crate::adduser::api::UserRead;
|
||||||
/// use adduser::NewFromString;
|
/// use adduser::NewFromString;
|
||||||
/// let pwd = adduser::User::new_from_string(
|
/// let pwd = adduser::User::new_from_string(
|
||||||
/// "testuser:testpassword:1001:1001:full Name,,,,:/home/test:/bin/test".to_string(), 0).unwrap();
|
/// "testuser:testpassword:1001:1001:full Name,,,,:/home/test:/bin/test".to_string()).unwrap();
|
||||||
/// assert_eq!(pwd.get_username().unwrap(), "testuser");
|
/// assert_eq!(pwd.get_username().unwrap(), "testuser");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// When parsing fails this function returns a [`UserLibError::Message`](crate::userlib_error::UserLibError::Message) containing some information as to why the function failed.
|
/// When parsing fails this function returns a [`UserLibError::Message`](crate::userlib_error::UserLibError::Message) containing some information as to why the function failed.
|
||||||
fn new_from_string(line: String, position: u32) -> Result<Self, crate::UserLibError>
|
fn new_from_string(line: String) -> Result<Self, crate::UserLibError>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
@ -42,7 +41,6 @@ impl NewFromString for User {
|
|||||||
if elements.len() == 7 {
|
if elements.len() == 7 {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
source: line,
|
source: line,
|
||||||
pos: position,
|
|
||||||
username: crate::Username::try_from(elements.get(0).unwrap().to_string())?,
|
username: crate::Username::try_from(elements.get(0).unwrap().to_string())?,
|
||||||
password: crate::Password::Encrypted(crate::EncryptedPassword::try_from(
|
password: crate::Password::Encrypted(crate::EncryptedPassword::try_from(
|
||||||
elements.get(1).unwrap().to_string(),
|
elements.get(1).unwrap().to_string(),
|
||||||
@ -114,23 +112,10 @@ impl crate::api::UserRead for User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for User {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
||||||
Some(self.pos.cmp(&other.pos))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for User {
|
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
||||||
self.pos.cmp(&other.pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for User {
|
impl Default for User {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
source: "".to_owned(),
|
source: "".to_owned(),
|
||||||
pos: u32::MAX,
|
|
||||||
username: crate::Username {
|
username: crate::Username {
|
||||||
username: "defaultuser".to_owned(),
|
username: "defaultuser".to_owned(),
|
||||||
},
|
},
|
||||||
@ -180,18 +165,17 @@ fn test_default_user() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_new_from_string() {
|
fn test_new_from_string() {
|
||||||
// Test if a single line can be parsed and if the resulting struct is populated correctly.
|
// Test if a single line can be parsed and if the resulting struct is populated correctly.
|
||||||
let fail = User::new_from_string("".into(), 0).err().unwrap();
|
let fail = User::new_from_string("".into()).err().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
fail,
|
fail,
|
||||||
crate::UserLibError::Message("Failed to parse: not enough elements".into())
|
crate::UserLibError::Message("Failed to parse: not enough elements".into())
|
||||||
);
|
);
|
||||||
let pwd = User::new_from_string(
|
let pwd = User::new_from_string(
|
||||||
"testuser:testpassword:1001:1001:testcomment:/home/test:/bin/test".into(),
|
"testuser:testpassword:1001:1001:testcomment:/home/test:/bin/test".into(),
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let pwd2 =
|
let pwd2 =
|
||||||
User::new_from_string("testuser:testpassword:1001:1001:full Name,004,000342,001-2312,myemail@test.com:/home/test:/bin/test".into(),0)
|
User::new_from_string("testuser:testpassword:1001:1001:full Name,004,000342,001-2312,myemail@test.com:/home/test:/bin/test".into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(pwd.username.username, "testuser");
|
assert_eq!(pwd.username.username, "testuser");
|
||||||
assert_eq!(pwd.home_dir.dir, "/home/test");
|
assert_eq!(pwd.home_dir.dir, "/home/test");
|
||||||
@ -226,10 +210,10 @@ fn test_parse_passwd() {
|
|||||||
let file = File::open("/etc/passwd").unwrap();
|
let file = File::open("/etc/passwd").unwrap();
|
||||||
let reader = BufReader::new(file);
|
let reader = BufReader::new(file);
|
||||||
|
|
||||||
for (n, line) in reader.lines().enumerate() {
|
for line in reader.lines() {
|
||||||
let lineorig: String = line.unwrap();
|
let lineorig: String = line.unwrap();
|
||||||
let linecopy = lineorig.clone();
|
let linecopy = lineorig.clone();
|
||||||
let pass_struc = User::new_from_string(linecopy, n as u32).unwrap();
|
let pass_struc = User::new_from_string(linecopy).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
// ignoring the numbers of `,` since the implementation does not (yet) reproduce a missing comment field.
|
// ignoring the numbers of `,` since the implementation does not (yet) reproduce a missing comment field.
|
||||||
lineorig,
|
lineorig,
|
||||||
|
@ -85,15 +85,15 @@ impl NewFromString for Shadow {
|
|||||||
/// ```
|
/// ```
|
||||||
/// use adduser::NewFromString;
|
/// use adduser::NewFromString;
|
||||||
/// let shad = adduser::Shadow::new_from_string(
|
/// let shad = adduser::Shadow::new_from_string(
|
||||||
/// "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::".to_string(),
|
/// "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::".to_string()
|
||||||
/// 0,
|
|
||||||
/// ).unwrap();
|
/// ).unwrap();
|
||||||
/// assert_eq!(shad.get_username(), "test");
|
/// assert_eq!(shad.get_username(), "test");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
|
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
|
||||||
fn new_from_string(line: String, position: u32) -> Result<Self, UserLibError> {
|
fn new_from_string(line: String) -> Result<Self, UserLibError> {
|
||||||
|
println!("{}", &line);
|
||||||
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() == 9 {
|
if elements.len() == 9 {
|
||||||
let extra = elements.get(8).unwrap();
|
let extra = elements.get(8).unwrap();
|
||||||
@ -144,7 +144,9 @@ fn duration_for_days(days_source: &str) -> Option<chrono::Duration> {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_and_back_identity() {
|
fn test_parse_and_back_identity() {
|
||||||
|
println!("Test");
|
||||||
let line = "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::";
|
let line = "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::";
|
||||||
let line2 = Shadow::new_from_string(line.to_owned(), 0).unwrap();
|
let line2 = Shadow::new_from_string(line.to_owned()).unwrap();
|
||||||
|
println!("{:#?}", line2);
|
||||||
assert_eq!(format!("{}", line2), line);
|
assert_eq!(format!("{}", line2), line);
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,7 @@ impl UserDBWrite for UserDBLocal {
|
|||||||
use crate::api::UserDBRead;
|
use crate::api::UserDBRead;
|
||||||
impl UserDBRead for UserDBLocal {
|
impl UserDBRead for UserDBLocal {
|
||||||
fn get_all_users(&self) -> Vec<&crate::User> {
|
fn get_all_users(&self) -> Vec<&crate::User> {
|
||||||
let mut res: Vec<&crate::User> = self.users.iter().map(|(_, x)| x).collect();
|
self.users.iter().map(|(_, x)| x).collect()
|
||||||
res.sort();
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_user_by_name(&self, name: &str) -> Option<&crate::User> {
|
fn get_user_by_name(&self, name: &str) -> Option<&crate::User> {
|
||||||
@ -260,7 +258,7 @@ fn user_vec_to_hashmap(users: Vec<crate::User>) -> HashMap<String, crate::User>
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
/// if the parsing failed a [`UserLibError::Message`](crate::userlib_error::UserLibError::Message) is returned containing a more detailed error message.
|
/// if the parsing failed a [`UserLibError::Message`](crate::userlib_error::UserLibError::Message) is returned containing a more detailed error message.
|
||||||
pub trait NewFromString {
|
pub trait NewFromString {
|
||||||
fn new_from_string(line: String, position: u32) -> Result<Self, crate::UserLibError>
|
fn new_from_string(line: String) -> Result<Self, crate::UserLibError>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
@ -272,10 +270,10 @@ where
|
|||||||
{
|
{
|
||||||
source
|
source
|
||||||
.lines()
|
.lines()
|
||||||
.enumerate()
|
.filter_map(|line| {
|
||||||
.filter_map(|(n, line)| {
|
|
||||||
if line.len() > 5 {
|
if line.len() > 5 {
|
||||||
Some(T::new_from_string(line.to_owned(), n as u32).expect("failed to read lines"))
|
//println!("{}", line);
|
||||||
|
Some(T::new_from_string(line.to_owned()).expect("failed to read lines"))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user