From 70c94feced47db0e8ca8bb27f2a45d0a6a9f0616 Mon Sep 17 00:00:00 2001 From: Nadja Reitzenstein Date: Mon, 11 Jul 2022 12:27:51 +0200 Subject: [PATCH] Implement password change functionality --- bffhd/capnp/user.rs | 33 +++++++++++++++++++++++++-------- bffhd/users/db.rs | 17 ++++++++++++++--- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/bffhd/capnp/user.rs b/bffhd/capnp/user.rs index 3dcb1c6..4333a86 100644 --- a/bffhd/capnp/user.rs +++ b/bffhd/capnp/user.rs @@ -79,12 +79,21 @@ impl info::Server for User { impl manage::Server for User { fn pwd( &mut self, - _params: manage::PwdParams, + params: manage::PwdParams, _results: manage::PwdResults, ) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) + let params = pry!(params.get()); + let old_pw = pry!(params.get_old_pwd()); + let new_pw = pry!(params.get_new_pwd()); + + let uid = self.user.get_username(); + if let Some(mut user) = self.session.users.get_user(uid) { + if let Ok(true) = user.check_password(old_pw.as_bytes()) { + user.set_pw(new_pw.as_bytes()); + self.session.users.put_user(uid, &user); + } + } + Promise::ok(()) } } @@ -148,9 +157,17 @@ impl admin::Server for User { Promise::ok(()) } - fn pwd(&mut self, _: admin::PwdParams, _: admin::PwdResults) -> Promise<(), ::capnp::Error> { - Promise::err(::capnp::Error::unimplemented( - "method not implemented".to_string(), - )) + fn pwd( + &mut self, + param: admin::PwdParams, + _: admin::PwdResults, + ) -> Promise<(), ::capnp::Error> { + let new_pw = pry!(pry!(param.get()).get_new_pwd()); + let uid = self.user.get_username(); + if let Some(mut user) = self.session.users.get_user(uid) { + user.set_pw(new_pw.as_bytes()); + self.session.users.put_user(uid, &user); + } + Promise::ok(()) } } diff --git a/bffhd/users/db.rs b/bffhd/users/db.rs index ffd9816..a8a804a 100644 --- a/bffhd/users/db.rs +++ b/bffhd/users/db.rs @@ -27,6 +27,12 @@ pub struct User { pub userdata: UserData, } +fn hash_pw(pw: &[u8]) -> argon2::Result { + let config = argon2::Config::default(); + let salt: [u8; 16] = rand::random(); + argon2::hash_encoded(pw, &salt, &config) +} + impl User { pub fn check_password(&self, pwd: &[u8]) -> miette::Result { if let Some(ref encoded) = self.userdata.passwd { @@ -39,9 +45,7 @@ impl User { } pub fn new_with_plain_pw(username: &str, password: impl AsRef<[u8]>) -> Self { - let config = argon2::Config::default(); - let salt: [u8; 16] = rand::random(); - let hash = argon2::hash_encoded(password.as_ref(), &salt, &config) + let hash = hash_pw(password.as_ref()) .expect(&format!("Failed to hash password for {}: ", username)); tracing::debug!("Hashed pw for {} to {}", username, hash); @@ -53,6 +57,13 @@ impl User { }, } } + + pub fn set_pw(&mut self, password: impl AsRef<[u8]>) { + self.userdata.passwd = Some(hash_pw(password.as_ref()).expect(&format!( + "failed to update hashed password for {}", + &self.id + ))); + } } #[derive(