Compare commits
2 Commits
676a5218e6
...
1ab0adbc06
Author | SHA1 | Date | |
---|---|---|---|
1ab0adbc06 | |||
5000fba6e7 |
52
Cargo.lock
generated
52
Cargo.lock
generated
@ -3,3 +3,55 @@
|
||||
[[package]]
|
||||
name = "adduser"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
@ -7,3 +7,5 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
regex = "1"
|
||||
lazy_static = "1.4"
|
||||
|
@ -1,3 +1,6 @@
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
pub mod passwd;
|
||||
pub mod userlib_error;
|
||||
pub use passwd::{Password, Username};
|
||||
|
@ -7,6 +7,8 @@
|
||||
)]
|
||||
#![allow(clippy::non_ascii_literal)]
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use crate::userlib_error::UserLibError;
|
||||
use std::cmp::Eq;
|
||||
use std::convert::TryFrom;
|
||||
@ -37,7 +39,12 @@ pub struct Uid {
|
||||
pub struct Gid {
|
||||
gid: u32,
|
||||
}
|
||||
|
||||
/// The gecos field of a user.
|
||||
///
|
||||
/// In the `/etc/passwd` file this field is a `,` sepparated list of items.
|
||||
/// The first 4 values are more or less standardised to be full name, room, phone at work and phone at home. After that there can be some extra fields often containing the emailadress and even additional information.
|
||||
///
|
||||
/// This enum represents the first 4 values by name and adds the other values to a list of strings [`Gecos::Detail`]. If only one field is found and no `,` at all this value is used as a human readable comment [`Gecos::Simple`].
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Gecos<'a> {
|
||||
Detail {
|
||||
@ -254,7 +261,15 @@ impl Display for Username<'_> {
|
||||
impl<'a> TryFrom<&'a str> for Username<'a> {
|
||||
type Error = UserLibError;
|
||||
fn try_from(source: &'a str) -> std::result::Result<Self, Self::Error> {
|
||||
Ok(Self { username: source })
|
||||
lazy_static! {
|
||||
static ref USERVALIDATION: Regex =
|
||||
Regex::new("^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\\$)$").unwrap();
|
||||
}
|
||||
if USERVALIDATION.is_match(source) {
|
||||
Ok(Self { username: source })
|
||||
} else {
|
||||
Err(UserLibError::Message("Invalid username".into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,6 +396,37 @@ impl<'a> TryFrom<&'a str> for ShellPath<'a> {
|
||||
|
||||
// Tests ----------------------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn test_username_validation() {
|
||||
// Failing tests
|
||||
let umlauts = Username::try_from("täst"); // umlauts
|
||||
assert_eq!(
|
||||
Err(UserLibError::Message("Invalid username".into())),
|
||||
umlauts
|
||||
);
|
||||
let number_first = Username::try_from("11elf"); // numbers first
|
||||
assert_eq!(
|
||||
Err(UserLibError::Message("Invalid username".into())),
|
||||
number_first
|
||||
);
|
||||
let slashes = Username::try_from("test/name"); // slashes in the name
|
||||
assert_eq!(
|
||||
Err(UserLibError::Message("Invalid username".into())),
|
||||
slashes
|
||||
);
|
||||
let long = Username::try_from("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // maximum size 32 letters
|
||||
assert_eq!(Err(UserLibError::Message("Invalid username".into())), long);
|
||||
// Working tests
|
||||
let single = Username::try_from("t"); // single characters are ok
|
||||
assert_eq!(single.unwrap().username, "t");
|
||||
let normal = Username::try_from("superman"); // regular username
|
||||
assert_eq!(normal.unwrap().username, "superman");
|
||||
let normal = Username::try_from("anna3pete"); // regular username containing a number
|
||||
assert_eq!(normal.unwrap().username, "anna3pete");
|
||||
let normal = Username::try_from("enya$"); // regular username ending in a $
|
||||
assert_eq!(normal.unwrap().username, "enya$");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_user() {
|
||||
// Check if a user can be created.
|
||||
|
Loading…
Reference in New Issue
Block a user