Skip to content

Commit f82d1b5

Browse files
committed
feat/role-validation-handler
1 parent e35705b commit f82d1b5

4 files changed

Lines changed: 124 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "email-sanitizer"
3-
version = "0.7.0+sprint3"
3+
version = "0.8.0+sprint4"
44
edition = "2024"
55

66
[dependencies]

readme.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ Follows RFC specifications by checking A/AAAA records if MX records are missing.
5858

5959
Checks among a list of 106,543 disposable email domains, the largest database of disposable emails out there, updated daily.
6060

61+
### Optional Role-Based Alias Detection and Validation
62+
63+
Identify and flag role-based email aliases (e.g., `admin@`, `support@`, `info@`) to prevent generic addresses from entering your system. This helps maintain high engagement rates and reduces the risk of emails being marked as spam.
64+
65+
- **Detection of Common Role Prefixes**: Checks for 50+ predefined role-based terms in the local-part (e.g., `admin`, `sales`, `contact`).
66+
67+
This feature is **optional** and can be enabled/disabled based on your requirements.
68+
6169
## 🛠 Tech Stack
6270

6371
| Category | Tools |

src/handlers/validation/role.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use mongodb::bson::{Document, doc};
2+
use mongodb::{Client, Collection};
3+
use std::env;
4+
use std::error::Error;
5+
6+
/// Checks if an email address uses a role-based alias by querying a MongoDB collection.
7+
///
8+
/// # Arguments
9+
/// * `email` - A string slice containing the email address to check
10+
///
11+
/// # Returns
12+
/// * `Ok(true)` if the alias is found in the role-based alias collection
13+
/// * `Ok(false)` if the alias is not found
14+
/// * `Err` containing an error message if any step fails
15+
///
16+
/// # Errors
17+
/// Returns an error if:
18+
/// - The email is missing '@' symbol (invalid format)
19+
/// - Environment variables are not properly configured
20+
/// - MongoDB connection or query fails
21+
///
22+
/// # Example
23+
/// ```
24+
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
25+
/// use email_sanitizer::handlers::validation::role_based::is_role_based_alias;
26+
/// let is_role_alias = is_role_based_alias("admin@example.com").await?;
27+
/// assert_eq!(is_role_alias, true);
28+
/// # Ok(())
29+
/// # }
30+
/// ```
31+
pub async fn is_role_based_alias(email: &str) -> Result<bool, Box<dyn Error>> {
32+
// Extract alias from email
33+
let (alias_part, _) = email
34+
.split_once('@')
35+
.ok_or("Invalid email format: missing '@'")?;
36+
let alias = alias_part.to_lowercase();
37+
38+
// Retrieve environment variables
39+
let mongo_uri = env::var("MONGODB_URI")?;
40+
let db_name = env::var("DB_NAME_PRODUCTION")?;
41+
let collection_name = env::var("DB_ROLE_BASED_ALIAS_COLLECTION")?;
42+
43+
// Connect to MongoDB
44+
let client = Client::with_uri_str(&mongo_uri).await?;
45+
let database = client.database(&db_name);
46+
let collection: Collection<Document> = database.collection(&collection_name);
47+
48+
// Check if alias exists in the collection
49+
let filter = doc! { "alias": alias };
50+
let exists = collection.find_one(filter).await?.is_some();
51+
52+
Ok(exists)
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use super::*;
58+
use mongodb::bson::{Document, doc};
59+
use std::env;
60+
61+
/// Helper function to set up test MongoDB collection
62+
async fn setup_collection() -> Collection<Document> {
63+
// Load environment variables from .env file
64+
dotenv::dotenv().ok();
65+
66+
let mongo_uri = env::var("MONGODB_URI").expect("MONGODB_URI must be set");
67+
let db_name = env::var("DB_NAME_TEST").expect("DB_NAME_TEST must be set");
68+
let collection_name = env::var("DB_ROLE_BASED_ALIAS_COLLECTION")
69+
.expect("DB_ROLE_BASED_ALIAS_COLLECTION must be set");
70+
71+
let client = Client::with_uri_str(&mongo_uri)
72+
.await
73+
.expect("Failed to connect to MongoDB");
74+
client.database(&db_name).collection(&collection_name)
75+
}
76+
77+
#[tokio::test]
78+
/// Tests recognition of role-based email aliases
79+
async fn test_role_based_alias() {
80+
let collection = setup_collection().await;
81+
82+
// Insert test role-based alias
83+
collection
84+
.insert_one(doc! { "alias": "admin" })
85+
.await
86+
.expect("Failed to insert test data");
87+
88+
// Test role-based alias
89+
let result = is_role_based_alias("admin@example.com").await;
90+
assert!(result.unwrap(), "Should recognize role-based alias");
91+
92+
// Cleanup
93+
collection
94+
.delete_many(doc! { "alias": "admin" })
95+
.await
96+
.expect("Failed to clean up test data");
97+
}
98+
99+
#[tokio::test]
100+
/// Tests recognition of non-role-based email aliases
101+
async fn test_non_role_based_alias() {
102+
let collection = setup_collection().await;
103+
104+
// Ensure test alias is removed
105+
collection
106+
.delete_many(doc! { "alias": "johndoe" })
107+
.await
108+
.expect("Failed to clean up test data");
109+
110+
// Test valid email
111+
let result = is_role_based_alias("johndoe@gmail.com").await;
112+
assert!(!result.unwrap(), "Should recognize non-role-based alias");
113+
}
114+
}

0 commit comments

Comments
 (0)