lifetime error
This commit is contained in:
parent
5cff7bf64b
commit
a645ebac75
@ -17,7 +17,6 @@ fn main() {
|
|||||||
|
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
let line = line.unwrap();
|
let line = line.unwrap();
|
||||||
println!("{}", line);
|
|
||||||
println!("{}", User::new_from_string(&line).unwrap());
|
println!("{}", User::new_from_string(&line).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
)]
|
)]
|
||||||
#![allow(clippy::non_ascii_literal)]
|
#![allow(clippy::non_ascii_literal)]
|
||||||
|
|
||||||
|
use crate::userlib::NewFromString;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use regex::Regex;
|
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
|
/// Parse a line formatted like one in `/etc/shadow` and construct a matching `Shadow` instance
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -97,7 +98,7 @@ impl<'a> Group<'a> {
|
|||||||
///
|
///
|
||||||
/// # 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.
|
||||||
pub fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
|
fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
|
||||||
println!("{}", &line);
|
println!("{}", &line);
|
||||||
let elements: Vec<&str> = line.split(':').collect();
|
let elements: Vec<&str> = line.split(':').collect();
|
||||||
if elements.len() == 4 {
|
if elements.len() == 4 {
|
||||||
|
@ -2,6 +2,7 @@ pub mod gecos_fields;
|
|||||||
pub mod passwd_fields;
|
pub mod passwd_fields;
|
||||||
pub mod shadow_fields;
|
pub mod shadow_fields;
|
||||||
|
|
||||||
|
use crate::userlib::NewFromString;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ pub struct User<'a> {
|
|||||||
shell_path: crate::ShellPath<'a>, /* Shell program. */
|
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
|
/// Parse a line formatted like one in `/etc/passwd` and construct a matching [`adduser::User`] instance
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -31,7 +32,10 @@ impl<'a> User<'a> {
|
|||||||
///
|
///
|
||||||
/// # 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.
|
||||||
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();
|
let elements: Vec<&str> = line.split(':').collect();
|
||||||
if elements.len() == 7 {
|
if elements.len() == 7 {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -50,6 +54,9 @@ impl<'a> User<'a> {
|
|||||||
Err("Failed to parse: not enough elements".into())
|
Err("Failed to parse: not enough elements".into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> User<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn get_username(&self) -> &'a str {
|
pub const fn get_username(&self) -> &'a str {
|
||||||
self.username.username
|
self.username.username
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
)]
|
)]
|
||||||
#![allow(clippy::non_ascii_literal)]
|
#![allow(clippy::non_ascii_literal)]
|
||||||
|
|
||||||
|
use crate::userlib::NewFromString;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
use crate::userlib_error::UserLibError;
|
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
|
/// Parse a line formatted like one in `/etc/shadow` and construct a matching `Shadow` instance
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -90,7 +91,7 @@ impl<'a> Shadow<'a> {
|
|||||||
///
|
///
|
||||||
/// # 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.
|
||||||
pub fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
|
fn new_from_string(line: &'a str) -> Result<Self, UserLibError> {
|
||||||
println!("{}", &line);
|
println!("{}", &line);
|
||||||
let elements: Vec<&str> = line.split(':').collect();
|
let elements: Vec<&str> = line.split(':').collect();
|
||||||
if elements.len() == 9 {
|
if elements.len() == 9 {
|
||||||
|
@ -8,13 +8,33 @@
|
|||||||
#![allow(clippy::non_ascii_literal)]
|
#![allow(clippy::non_ascii_literal)]
|
||||||
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufReader, Read};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct UserDBLocal<'a> {
|
pub struct UserDBLocal<'a> {
|
||||||
|
source_files: Files,
|
||||||
pub passwd_entries: Vec<crate::User<'a>>,
|
pub passwd_entries: Vec<crate::User<'a>>,
|
||||||
pub shadow_entries: Vec<crate::Shadow<'a>>,
|
pub shadow_entries: Vec<crate::Shadow<'a>>,
|
||||||
pub group_entries: Vec<crate::Group<'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> {
|
impl<'a> UserDBLocal<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn import_from_strings(
|
pub fn import_from_strings(
|
||||||
@ -23,6 +43,11 @@ impl<'a> UserDBLocal<'a> {
|
|||||||
group_content: &'a str,
|
group_content: &'a str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let res = UserDBLocal {
|
let res = UserDBLocal {
|
||||||
|
source_files: Files {
|
||||||
|
passwd: None,
|
||||||
|
group: None,
|
||||||
|
shadow: None,
|
||||||
|
},
|
||||||
passwd_entries: passwd_content
|
passwd_entries: passwd_content
|
||||||
.lines()
|
.lines()
|
||||||
.filter_map(|line| {
|
.filter_map(|line| {
|
||||||
@ -57,6 +82,53 @@ impl<'a> UserDBLocal<'a> {
|
|||||||
};
|
};
|
||||||
res
|
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]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user