pub mod snmp;
use rocket::form::{self, FromFormField, ValueField};
use eui48::MacAddress;
use validator::ValidateEmail;
#[derive(Debug)]
pub struct MAC(pub MacAddress);
#[rocket::async_trait]
impl<'v> FromFormField<'v> for MAC {
fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> {
let s = field.value;
match MacAddress::parse_str(s) {
Ok(ma) => Ok(Self(ma)),
Err(e) => {
let error =
form::Error::validation(format!("Unable to parse MAC address; {e}"));
Err(error)?
}
}
}
}
#[derive(Debug)]
pub struct ObjName(pub String);
impl<'r> FromFormField<'r> for ObjName {
fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> {
let s = field.value;
if let Err(e) = orphanage::strx::validate_objname(s) {
if let orphanage::Error::BadFormat(err) = e {
Err(form::Error::validation(err))?;
}
Err(form::Error::validation("invalid object name format"))?;
}
Ok(Self(s.to_string()))
}
}
#[derive(Debug)]
pub struct ObjNameRef<'r>(pub &'r str);
impl<'r> FromFormField<'r> for ObjNameRef<'r> {
fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> {
let s = field.value;
if let Err(e) = orphanage::strx::validate_objname(s) {
if let orphanage::Error::BadFormat(err) = e {
Err(form::Error::validation(err))?;
}
Err(form::Error::validation("invalid object name format"))?;
}
Ok(ObjNameRef(s))
}
}
#[derive(Debug)]
pub struct OptPass(pub String);
impl<'v> FromFormField<'v> for OptPass {
fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> {
let s = field.value;
Ok(Self(s.to_string()))
}
}
#[derive(Debug)]
pub struct ReqPass(pub String);
impl<'v> FromFormField<'v> for ReqPass {
fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> {
let s = field.value;
if s.is_empty() {
let error = form::Error::validation("Passphrase must not be empty");
Err(error)?
} else {
Ok(Self(s.to_string()))
}
}
}
#[derive(Debug)]
pub struct ReqStrongPass(pub String);
impl PartialEq for ReqStrongPass {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<'v> FromFormField<'v> for ReqStrongPass {
fn from_value(field: ValueField<'v>) -> form::Result<'v, Self> {
let s = field.value;
if s.len() < 12 {
let error = form::Error::validation(
"Passphrase too short; must be at least 12 characters long"
);
Err(error)?
} else {
let mut lowercase = false;
let mut uppercase = false;
let mut numeric = false;
let mut special = false;
let mut classes = 0;
for c in s.chars() {
if c.is_ascii_uppercase() {
if !uppercase {
classes += 1;
uppercase = true;
}
} else if c.is_ascii_lowercase() {
if !lowercase {
classes += 1;
lowercase = true;
}
} else if c.is_ascii_digit() {
if !numeric {
classes += 1;
numeric = true;
}
} else if !special {
classes += 1;
special = true;
}
if classes == 3 {
break;
}
}
if classes < 3 {
return Err(From::from(form::Error::validation(
"Passphrase too weak; must contain at least three of the four \
character classes: upper-case letter, lower-case letter, digit, \
special character"
)));
}
Ok(Self(s.to_string()))
}
}
}
#[derive(Debug)]
pub struct Email<'r>(pub &'r str);
impl<'r> FromFormField<'r> for Email<'r> {
fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> {
let s = field.value;
if s.validate_email() {
Ok(Email(s))
} else {
Err(From::from(form::Error::validation("Invalid email format")))
}
}
}