fix(clippy): remove unnecessary u32 cast (final take)
Some checks failed
Lint and Build / lint-and-build (push) Failing after 5m33s

This commit is contained in:
goose 2026-03-13 11:31:39 -03:00
parent 614039bfc9
commit bd34ee1618

View file

@ -1,122 +1,119 @@
### /home/asoliver/desarrollo/normogen/backend/src/security/account_lockout.rs use anyhow::Result;
```rust use mongodb::bson::{doc, DateTime};
1: use anyhow::Result; use mongodb::Collection;
2: use mongodb::bson::{doc, DateTime}; use std::sync::Arc;
3: use mongodb::Collection; use tokio::sync::RwLock;
4: use std::sync::Arc;
5: use tokio::sync::RwLock; #[derive(Clone)]
6: pub struct AccountLockout {
7: #[derive(Clone)] user_collection: Arc<RwLock<Collection<mongodb::bson::Document>>>,
8: pub struct AccountLockout { max_attempts: u32,
9: user_collection: Arc<RwLock<Collection<mongodb::bson::Document>>>, base_duration_minutes: u32,
10: max_attempts: u32, max_duration_minutes: u32,
11: base_duration_minutes: u32, }
12: max_duration_minutes: u32,
13: } impl AccountLockout {
14: pub fn new(
15: impl AccountLockout { user_collection: Collection<mongodb::bson::Document>,
16: pub fn new( max_attempts: u32,
17: user_collection: Collection<mongodb::bson::Document>, base_duration_minutes: u32,
18: max_attempts: u32, max_duration_minutes: u32,
19: base_duration_minutes: u32, ) -> Self {
20: max_duration_minutes: u32, Self {
21: ) -> Self { user_collection: Arc::new(RwLock::new(user_collection)),
22: Self { max_attempts,
23: user_collection: Arc::new(RwLock::new(user_collection)), base_duration_minutes,
24: max_attempts, max_duration_minutes,
25: base_duration_minutes, }
26: max_duration_minutes, }
27: }
28: } pub async fn check_lockout(&self, email: &str) -> Result<bool> {
29: let collection = self.user_collection.read().await;
30: pub async fn check_lockout(&self, email: &str) -> Result<bool> { let user = collection.find_one(doc! { "email": email }, None).await?;
31: let collection = self.user_collection.read().await;
32: let user = collection.find_one(doc! { "email": email }, None).await?; if let Some(user_doc) = user {
33: if let Some(locked_until_val) = user_doc.get("locked_until") {
34: if let Some(user_doc) = user { if let Some(dt) = locked_until_val.as_datetime() {
35: if let Some(locked_until_val) = user_doc.get("locked_until") { let now = DateTime::now();
36: if let Some(dt) = locked_until_val.as_datetime() { if dt.timestamp_millis() > now.timestamp_millis() {
37: let now = DateTime::now(); return Ok(true); // Account is locked
38: if dt.timestamp_millis() > now.timestamp_millis() { }
39: return Ok(true); // Account is locked }
40: } }
41: } }
42: }
43: } Ok(false) // Account is not locked
44: }
45: Ok(false) // Account is not locked
46: } pub async fn record_failed_attempt(&self, email: &str) -> Result<bool> {
47: let collection = self.user_collection.write().await;
48: pub async fn record_failed_attempt(&self, email: &str) -> Result<bool> {
49: let collection = self.user_collection.write().await; // Get current failed attempts
50: let user = collection.find_one(doc! { "email": email }, None).await?;
51: // Get current failed attempts
52: let user = collection.find_one(doc! { "email": email }, None).await?; let current_attempts = if let Some(user_doc) = user {
53: user_doc
54: let current_attempts = if let Some(user_doc) = user { .get("failed_login_attempts")
55: user_doc .and_then(|v| v.as_i64())
56: .get("failed_login_attempts") .unwrap_or(0) as u32
57: .and_then(|v| v.as_i64()) } else {
58: .unwrap_or(0) as u32 0
59: } else { };
60: 0
61: }; let new_attempts = current_attempts + 1;
62: let should_lock = new_attempts >= self.max_attempts;
63: let new_attempts = current_attempts + 1;
64: let should_lock = new_attempts >= self.max_attempts; // Calculate lockout duration
65: let lock_duration = if should_lock {
66: // Calculate lockout duration let multiplier = new_attempts.saturating_sub(self.max_attempts) + 1;
67: let lock_duration = if should_lock { let duration = self.base_duration_minutes * multiplier;
68: let multiplier = new_attempts.saturating_sub(self.max_attempts).saturating_sub(self.max_attempts) + 1; std::cmp::min(duration, self.max_duration_minutes)
69: let duration = self.base_duration_minutes * multiplier; } else {
70: std::cmp::min(duration, self.max_duration_minutes) 0
71: } else { };
72: 0
73: }; let locked_until = if lock_duration > 0 {
74: let now = DateTime::now();
75: let locked_until = if lock_duration > 0 { let duration_millis = lock_duration as u64 * 60 * 1000;
76: let now = DateTime::now(); DateTime::from_millis(now.timestamp_millis() + duration_millis as i64)
77: let duration_millis = lock_duration as u64 * 60 * 1000; } else {
78: DateTime::from_millis(now.timestamp_millis() + duration_millis as i64) DateTime::now()
79: } else { };
80: DateTime::now()
81: }; // Update user
82: collection
83: // Update user .update_one(
84: collection doc! { "email": email },
85: .update_one( doc! {
86: doc! { "email": email }, "$set": {
87: doc! { "failed_login_attempts": new_attempts as i32,
88: "$set": { "last_failed_login": DateTime::now(),
89: "failed_login_attempts": new_attempts as i32, "locked_until": locked_until,
90: "last_failed_login": DateTime::now(), }
91: "locked_until": locked_until, },
92: } None,
93: }, )
94: None, .await?;
95: )
96: .await?; Ok(should_lock)
97: }
98: Ok(should_lock)
99: } pub async fn reset_attempts(&self, email: &str) -> Result<()> {
100: let collection = self.user_collection.write().await;
101: pub async fn reset_attempts(&self, email: &str) -> Result<()> {
102: let collection = self.user_collection.write().await; collection
103: .update_one(
104: collection doc! { "email": email },
105: .update_one( doc! {
106: doc! { "email": email }, "$set": {
107: doc! { "failed_login_attempts": 0,
108: "$set": { "locked_until": null,
109: "failed_login_attempts": 0, }
110: "locked_until": null, },
111: } None,
112: }, )
113: None, .await?;
114: )
115: .await?; Ok(())
116: }
117: Ok(()) }
118: }
119: }
```