Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ binascii = "0.1"
axum = { version = "0.6.18", features = ["multipart"] }
hyper = "0.14.26"
tower-http = { version = "0.4.0", features = ["cors"] }
email_address = "0.2.4"

[dev-dependencies]
rand = "0.8"
Expand Down
2 changes: 2 additions & 0 deletions project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ Cyberneering
datetime
DATETIME
Dont
dotless
Grünwald
hasher
Hasher
hexlify
httpseeds
ICANN
imagoodboy
imdl
indexadmin
Expand Down
2 changes: 1 addition & 1 deletion src/services/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::errors::ServiceError;
use crate::mailer;
use crate::mailer::VerifyClaims;
use crate::models::user::{UserCompact, UserId, UserProfile};
use crate::utils::regex::validate_email_address;
use crate::utils::validation::validate_email_address;
use crate::web::api::v1::contexts::user::forms::RegistrationForm;

/// Since user email could be optional, we need a way to represent "no email"
Expand Down
2 changes: 1 addition & 1 deletion src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod clock;
pub mod hex;
pub mod parse_torrent;
pub mod regex;
pub mod validation;
38 changes: 0 additions & 38 deletions src/utils/regex.rs

This file was deleted.

79 changes: 79 additions & 0 deletions src/utils/validation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::str::FromStr;

use email_address::EmailAddress;
use regex::Regex;

const MIN_DOMAIN_LENGTH: usize = 4;

/// Validates an email address.
///
/// # Panics
///
/// It panics if the email address is invalid. This should not happen
/// because the email address is previously validated.
#[must_use]
pub fn validate_email_address(email_address_to_be_checked: &str) -> bool {
if !EmailAddress::is_valid(email_address_to_be_checked) {
return false;
}

let email = EmailAddress::from_str(email_address_to_be_checked).expect("Invalid email address");

// We reject anyway the email if it's a dotless domain name.
domain_has_extension(email.domain())
}

/// Returns true if the string representing a domain has an extension.
///
/// It does not check if the extension is valid.
fn domain_has_extension(domain: &str) -> bool {
if domain.len() < MIN_DOMAIN_LENGTH {
return false;
}

Regex::new(r".*\..*").expect("Invalid regex").is_match(domain)
}

#[cfg(test)]
mod tests {

mod for_email_validation {
use crate::utils::validation::validate_email_address;

#[test]
fn it_should_accept_valid_email_addresses() {
assert!(validate_email_address("[email protected]"));
assert!(validate_email_address("[email protected]"));
}

#[test]
fn it_should_not_accept_invalid_email_addresses() {
assert!(!validate_email_address("test"));
assert!(!validate_email_address("test@"));
assert!(!validate_email_address("test@torrust."));
assert!(!validate_email_address("test@."));
assert!(!validate_email_address("[email protected]"));

// Notice that local domain name with no TLD are valid,
// although ICANN highly discourages dotless email addresses
assert!(!validate_email_address("test@torrust"));
}
}

mod for_domain_validation {
use crate::utils::validation::domain_has_extension;

#[test]
fn it_should_accept_valid_domain_with_extension() {
assert!(domain_has_extension("a.io"));
assert!(domain_has_extension("a.com"));
}

#[test]
fn it_should_not_accept_dotless_domains() {
assert!(!domain_has_extension(""));
assert!(!domain_has_extension("."));
assert!(!domain_has_extension("a."));
}
}
}