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