Skip to content

Commit e627ef9

Browse files
committed
refactor: use a third party package for email valildation
1 parent 734e6cb commit e627ef9

File tree

5 files changed

+83
-40
lines changed

5 files changed

+83
-40
lines changed

project-words.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ Cyberneering
1515
datetime
1616
DATETIME
1717
Dont
18+
dotless
1819
Grünwald
1920
hasher
2021
Hasher
2122
hexlify
2223
httpseeds
24+
ICANN
2325
imagoodboy
2426
imdl
2527
indexadmin

src/services/user.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::errors::ServiceError;
1313
use crate::mailer;
1414
use crate::mailer::VerifyClaims;
1515
use crate::models::user::{UserCompact, UserId, UserProfile};
16-
use crate::utils::regex::validate_email_address;
16+
use crate::utils::validation::validate_email_address;
1717
use crate::web::api::v1::contexts::user::forms::RegistrationForm;
1818

1919
/// Since user email could be optional, we need a way to represent "no email"

src/utils/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pub mod clock;
22
pub mod hex;
33
pub mod parse_torrent;
4-
pub mod regex;
4+
pub mod validation;

src/utils/regex.rs

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/utils/validation.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use std::str::FromStr;
2+
3+
use email_address::EmailAddress;
4+
use regex::Regex;
5+
6+
const MIN_DOMAIN_LENGTH: usize = 4;
7+
8+
/// Validates an email address.
9+
///
10+
/// # Panics
11+
///
12+
/// It panics if the email address is invalid. This should not happen
13+
/// because the email address is previously validated.
14+
#[must_use]
15+
pub fn validate_email_address(email_address_to_be_checked: &str) -> bool {
16+
if !EmailAddress::is_valid(email_address_to_be_checked) {
17+
return false;
18+
}
19+
20+
let email = EmailAddress::from_str(email_address_to_be_checked).expect("Invalid email address");
21+
22+
// We reject anyway the email if it's a dotless domain name.
23+
domain_has_extension(email.domain())
24+
}
25+
26+
/// Returns true if the string representing a domain has an extension.
27+
///
28+
/// It does not check if the extension is valid.
29+
fn domain_has_extension(domain: &str) -> bool {
30+
if domain.len() < MIN_DOMAIN_LENGTH {
31+
return false;
32+
}
33+
34+
Regex::new(r".*\..*").expect("Invalid regex").is_match(domain)
35+
}
36+
37+
#[cfg(test)]
38+
mod tests {
39+
40+
mod for_email_validation {
41+
use crate::utils::validation::validate_email_address;
42+
43+
#[test]
44+
fn it_should_accept_valid_email_addresses() {
45+
assert!(validate_email_address("[email protected]"));
46+
assert!(validate_email_address("[email protected]"));
47+
}
48+
49+
#[test]
50+
fn it_should_not_accept_invalid_email_addresses() {
51+
assert!(!validate_email_address("test"));
52+
assert!(!validate_email_address("test@"));
53+
assert!(!validate_email_address("test@torrust."));
54+
assert!(!validate_email_address("test@."));
55+
assert!(!validate_email_address("[email protected]"));
56+
57+
// Notice that local domain name with no TLD are valid,
58+
// although ICANN highly discourages dotless email addresses
59+
assert!(!validate_email_address("test@torrust"));
60+
}
61+
}
62+
63+
mod for_domain_validation {
64+
use crate::utils::validation::domain_has_extension;
65+
66+
#[test]
67+
fn it_should_accept_valid_domain_with_extension() {
68+
assert!(domain_has_extension("a.io"));
69+
assert!(domain_has_extension("a.com"));
70+
}
71+
72+
#[test]
73+
fn it_should_not_accept_dotless_domains() {
74+
assert!(!domain_has_extension(""));
75+
assert!(!domain_has_extension("."));
76+
assert!(!domain_has_extension("a."));
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)