temp #2

Merged
dietrich merged 6 commits from temp into master 2020-10-07 17:11:11 +02:00
5 changed files with 87 additions and 7 deletions
Showing only changes of commit a645ebac75 - Show all commits

View File

@ -17,7 +17,6 @@ fn main() {
for line in reader.lines() {
let line = line.unwrap();
println!("{}", line);
println!("{}", User::new_from_string(&line).unwrap());
}

View File

@ -7,6 +7,7 @@
)]
#![allow(clippy::non_ascii_literal)]
use crate::userlib::NewFromString;
use log::warn;
use regex::Regex;
@ -84,7 +85,7 @@ impl<'a> Display for Group<'a> {
}
}
impl<'a> Group<'a> {
impl<'a> NewFromString<'a> for Group<'a> {
/// Parse a line formatted like one in `/etc/shadow` and construct a matching `Shadow` instance
///
/// # Example
@ -97,7 +98,7 @@ impl<'a> Group<'a> {
///
/// # Errors
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
pub fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
println!("{}", &line);
let elements: Vec<&str> = line.split(':').collect();
if elements.len() == 4 {

View File

@ -2,6 +2,7 @@ pub mod gecos_fields;
pub mod passwd_fields;
pub mod shadow_fields;
use crate::userlib::NewFromString;
use std::convert::TryFrom;
use std::fmt::{self, Display};
@ -18,7 +19,7 @@ pub struct User<'a> {
shell_path: crate::ShellPath<'a>, /* Shell program. */
}
impl<'a> User<'a> {
impl<'a> NewFromString<'a> for User<'a> {
/// Parse a line formatted like one in `/etc/passwd` and construct a matching [`adduser::User`] instance
///
/// # Example
@ -31,7 +32,10 @@ impl<'a> User<'a> {
///
/// # Errors
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
pub fn new_from_string(line: &'a str) -> Result<Self, crate::UserLibError> {
fn new_from_string(line: &'a str) -> Result<Self, crate::UserLibError>
where
Self: Sized,
{
let elements: Vec<&str> = line.split(':').collect();
if elements.len() == 7 {
Ok(Self {
@ -50,6 +54,9 @@ impl<'a> User<'a> {
Err("Failed to parse: not enough elements".into())
}
}
}
impl<'a> User<'a> {
#[must_use]
pub const fn get_username(&self) -> &'a str {
self.username.username

View File

@ -7,6 +7,7 @@
)]
#![allow(clippy::non_ascii_literal)]
use crate::userlib::NewFromString;
use log::warn;
use crate::userlib_error::UserLibError;
@ -77,7 +78,7 @@ fn show_option_duration(input: Option<chrono::Duration>) -> String {
}
}
impl<'a> Shadow<'a> {
impl<'a> NewFromString<'a> for Shadow<'a> {
/// Parse a line formatted like one in `/etc/shadow` and construct a matching `Shadow` instance
///
/// # Example
@ -90,7 +91,7 @@ impl<'a> Shadow<'a> {
///
/// # Errors
/// When parsing fails this function returns a `UserLibError::Message` containing some information as to why the function failed.
pub fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
println!("{}", &line);
let elements: Vec<&str> = line.split(':').collect();
if elements.len() == 9 {

View File

@ -8,13 +8,33 @@
#![allow(clippy::non_ascii_literal)]
use log::warn;
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::PathBuf;
pub struct UserDBLocal<'a> {
source_files: Files,
pub passwd_entries: Vec<crate::User<'a>>,
pub shadow_entries: Vec<crate::Shadow<'a>>,
pub group_entries: Vec<crate::Group<'a>>,
}
pub struct Files {
passwd: Option<PathBuf>,
shadow: Option<PathBuf>,
group: Option<PathBuf>,
}
impl Default for Files {
fn default() -> Self {
Self {
passwd: Some(PathBuf::from("/etc/passwd")),
shadow: Some(PathBuf::from("/etc/shadow")),
group: Some(PathBuf::from("/etc/group")),
}
}
}
impl<'a> UserDBLocal<'a> {
#[must_use]
pub fn import_from_strings(
@ -23,6 +43,11 @@ impl<'a> UserDBLocal<'a> {
group_content: &'a str,
) -> Self {
let res = UserDBLocal {
source_files: Files {
passwd: None,
group: None,
shadow: None,
},
passwd_entries: passwd_content
.lines()
.filter_map(|line| {
@ -57,6 +82,53 @@ impl<'a> UserDBLocal<'a> {
};
res
}
pub fn load_files(files: Files) -> Self {
let passwd_file =
File::open(files.group.expect("passwd file path cannot be None")).unwrap();
let mut passwd_reader = BufReader::new(passwd_file);
let mut my_passwd_lines = String::new();
passwd_reader.read_to_string(&mut my_passwd_lines).unwrap();
let group_file = File::open(files.group.expect("group file path cannot be None")).unwrap();
let mut group_reader = BufReader::new(group_file);
let mut my_group_lines = String::new();
group_reader.read_to_string(&mut my_group_lines).unwrap();
let shadow_file = File::open(files.shadow.expect("shadow file path cannot be None"))
.expect("Failed to read the shadow file. Most of the time root permissions are needed");
let mut shadow_reader = BufReader::new(group_file);
let mut my_shadow_lines = String::new();
shadow_reader.read_to_string(&mut my_shadow_lines).unwrap();
Self {
source_files: files,
passwd_entries: string_to(&my_passwd_lines),
group_entries: string_to(&my_group_lines),
shadow_entries: string_to(&my_shadow_lines),
}
}
}
pub trait NewFromString<'a> {
fn new_from_string(line: &'a str) -> Result<Self, crate::UserLibError>
where
Self: Sized;
}
fn string_to<'a, T>(source: &'a str) -> Vec<T>
where
T: NewFromString<'a>,
{
source
.lines()
.filter_map(|line| {
if line.len() > 5 {
println!("{}", line);
Some(T::new_from_string(line).expect("failed to read lines"))
} else {
None
}
})
.collect()
}
#[test]