Skip to content

Commit

Permalink
Also check password length in password reset flow
Browse files Browse the repository at this point in the history
  • Loading branch information
rien committed Sep 27, 2021
1 parent 5d38546 commit 5eed06e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
7 changes: 4 additions & 3 deletions src/controllers/users_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,10 @@ pub async fn reset_password_post<'r, 'o: 'r>(
if let Some(user) =
User::find_by_password_token(form.token.to_owned(), &db).await?
{
let changed = user
.change_password(&form.new_password, conf.bcrypt_cost, &db)
.await;
let change = ChangePassword {
password: form.new_password,
};
let changed = user.change_password(change, conf, &db).await;
match changed {
Ok(user) => {
let body = template!(
Expand Down
15 changes: 11 additions & 4 deletions src/models/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ lazy_static! {
pub struct NewUser {
#[validate(regex = "NEW_USER_REGEX")]
pub username: String,
#[validate(length(min = 8, message = "Password to short"))]
#[validate(length(min = 8, message = "Password too short"))]
pub password: String,
#[validate(length(min = 3, max = 254))]
pub full_name: String,
Expand Down Expand Up @@ -145,6 +145,12 @@ pub struct ChangeAdmin {
pub admin: bool,
}

#[derive(Validate, FromForm, Deserialize, Debug, Clone)]
pub struct ChangePassword {
#[validate(length(min = 8, message = "Password too short"))]
pub password: String,
}

impl User {
pub async fn all(db: &DbConn) -> Result<Vec<User>> {
let all_users =
Expand Down Expand Up @@ -374,11 +380,12 @@ impl User {

pub async fn change_password(
mut self,
new_password: &str,
bcrypt_cost: u32,
change: ChangePassword,
conf: &Config,
db: &DbConn,
) -> Result<Self> {
self.hashed_password = hash(new_password, bcrypt_cost)?;
change.validate()?;
self.hashed_password = hash(&change.password, conf.bcrypt_cost)?;
self.password_reset_token = None;
self.password_reset_expiry = None;
self.update(db).await
Expand Down
22 changes: 22 additions & 0 deletions tests/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,28 @@ async fn forgot_password() {
"should get reset password page"
);

let short_password = "pw";

common::dont_expect_mail(async || {
let response = http_client
.post(format!("/users/reset_password/"))
.header(ContentType::Form)
.header(Accept::HTML)
.body(format!(
"token={}&new_password={}",
&token, &short_password
))
.dispatch()
.await;

assert_eq!(
response.status(),
Status::UnprocessableEntity,
"should not accept short password"
);
})
.await;

let old_password_hash = user.hashed_password.clone();
let new_password = "passw0rd";

Expand Down

0 comments on commit 5eed06e

Please sign in to comment.