Skip to content

Commit 39120cf

Browse files
committed
Add logging when user fails to verify password
We currently alert if we see too many errors, so we should write to the logs what is going on.
1 parent a8ccb81 commit 39120cf

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

crates/data-model/src/users.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
55
// Please see LICENSE files in the repository root for full details.
66

7-
use std::net::IpAddr;
7+
use std::{fmt::Display, net::IpAddr};
88

99
use chrono::{DateTime, Utc};
1010
use rand::Rng;
@@ -47,6 +47,14 @@ impl User {
4747
}
4848
}
4949

50+
impl Display for User {
51+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52+
// Format the user as their username, this is useful for logging and
53+
// debugging.
54+
self.username.fmt(f)
55+
}
56+
}
57+
5058
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
5159
pub struct Password {
5260
pub id: Ulid,

crates/handlers/src/views/login.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub(crate) async fn post(
166166
}
167167

168168
if !form_state.is_valid() {
169+
tracing::warn!("Invalid login form: {form_state:?}");
169170
PASSWORD_LOGIN_COUNTER.add(1, &[KeyValue::new(RESULT, "error")]);
170171
return render(
171172
locale,
@@ -189,6 +190,7 @@ pub(crate) async fn post(
189190
// First, lookup the user
190191
let Some(user) = get_user_by_email_or_by_username(site_config, &mut repo, username).await?
191192
else {
193+
tracing::warn!("User not found: {username}");
192194
let form_state = form_state.with_error_on_form(FormError::InvalidCredentials);
193195
PASSWORD_LOGIN_COUNTER.add(1, &[KeyValue::new(RESULT, "error")]);
194196
return render(
@@ -228,6 +230,7 @@ pub(crate) async fn post(
228230
let Some(user_password) = repo.user_password().active(&user).await? else {
229231
// There is no password for this user, but we don't want to disclose that. Show
230232
// a generic 'invalid credentials' error instead
233+
tracing::warn!("No password for user: {user}");
231234
let form_state = form_state.with_error_on_form(FormError::InvalidCredentials);
232235
PASSWORD_LOGIN_COUNTER.add(1, &[KeyValue::new(RESULT, "error")]);
233236
return render(
@@ -271,6 +274,7 @@ pub(crate) async fn post(
271274
}
272275
Ok(None) => user_password,
273276
Err(_) => {
277+
tracing::warn!("Failed to verify/upgrade password for user: {user}");
274278
let form_state = form_state.with_error_on_form(FormError::InvalidCredentials);
275279
PASSWORD_LOGIN_COUNTER.add(1, &[KeyValue::new(RESULT, "error")]);
276280
return render(
@@ -291,6 +295,7 @@ pub(crate) async fn post(
291295
// Now that we have checked the user password, we now want to show an error if
292296
// the user is locked or deactivated
293297
if user.deactivated_at.is_some() {
298+
tracing::warn!("User is deactivated: {user}");
294299
PASSWORD_LOGIN_COUNTER.add(1, &[KeyValue::new(RESULT, "error")]);
295300
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(&clock, &mut rng);
296301
let ctx = AccountInactiveContext::new(user)
@@ -301,6 +306,7 @@ pub(crate) async fn post(
301306
}
302307

303308
if user.locked_at.is_some() {
309+
tracing::warn!("User is locked: {user}");
304310
PASSWORD_LOGIN_COUNTER.add(1, &[KeyValue::new(RESULT, "error")]);
305311
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(&clock, &mut rng);
306312
let ctx = AccountInactiveContext::new(user)

0 commit comments

Comments
 (0)