api: implement auth/change_pw

This commit is contained in:
Peter Cai 2020-02-20 21:01:14 +08:00
parent 77517147c8
commit 92f8a72117
No known key found for this signature in database
GPG Key ID: 71F5FB4E4F3FD54F
2 changed files with 37 additions and 0 deletions

View File

@ -9,6 +9,7 @@ use std::vec::Vec;
pub fn routes() -> impl Into<Vec<rocket::Route>> {
routes![
auth,
auth_change_pw,
auth_sign_in,
auth_params
]
@ -99,4 +100,23 @@ fn auth_params(db: DbConn, email: String) -> Custom<JsonResp<AuthParams>> {
Err(user::UserOpError(e)) =>
error_resp(Status::InternalServerError, vec![e])
}
}
#[derive(Deserialize)]
struct ChangePwParams {
email: String,
password: String,
current_password: String
}
#[post("/auth/change_pw", format = "json", data = "<params>")]
fn auth_change_pw(db: DbConn, params: Json<ChangePwParams>) -> Custom<JsonResp<()>> {
let res = user::User::find_user_by_email(&db, &params.email)
.and_then(|u|
u.change_pw(&db, &params.current_password, &params.password));
match res {
Ok(_) => Custom(Status::NoContent, Json(Response::Success(()))),
Err(user::UserOpError(e)) =>
error_resp(Status::InternalServerError, vec![e])
}
}

View File

@ -82,4 +82,21 @@ impl User {
.map_err(|_| UserOpError::new("Failed to generate token"))
}
}
// Change the password in database, if old password is provided
// The current instance of User model will not be mutated
pub fn change_pw(&self, db: &SqliteConnection, passwd: &str, new_passwd: &str) -> Result<(), UserOpError> {
if passwd != self.password {
Err(UserOpError::new("Password mismatch"))
} else {
// Update database
// TODO: Maybe we should revoke all JWTs somehow?
// maybe we can record when the user last changed?
diesel::update(users.find(self.id))
.set(password.eq(new_passwd))
.execute(db)
.map(|_| ())
.map_err(|_| UserOpError::new("Database error"))
}
}
}