From 2333d898b93c1eb3d7617ac05e35e0b1a39dc396 Mon Sep 17 00:00:00 2001 From: fdb-hiroshima <35889323+fdb-hiroshima@users.noreply.github.com> Date: Thu, 3 Jan 2019 16:45:27 +0100 Subject: [PATCH] Add new subcomand for plm to reset password (#406) * Add new subcomand for plm to reset password * Verify user exist before asking for new password --- plume-cli/src/users.rs | 29 ++++++++++++++++++++++++++++- plume-models/src/users.rs | 7 +++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/plume-cli/src/users.rs b/plume-cli/src/users.rs index 6599cca..a9b48dc 100644 --- a/plume-cli/src/users.rs +++ b/plume-cli/src/users.rs @@ -4,6 +4,7 @@ use rpassword; use std::io::{self, Write}; use plume_models::{ Connection, + instance::Instance, users::*, }; @@ -43,13 +44,27 @@ pub fn command<'a, 'b>() -> App<'a, 'b> { .long("admin") .help("Makes the user an administrator of the instance") ).about("Create a new user on this instance")) + .subcommand(SubCommand::with_name("reset-password") + .arg(Arg::with_name("name") + .short("u") + .long("user") + .alias("username") + .takes_value(true) + .help("The username of the user to reset password to") + ).arg(Arg::with_name("password") + .short("p") + .long("password") + .takes_value(true) + .help("The password new for the user") + ).about("Reset user password")) } pub fn run<'a>(args: &ArgMatches<'a>, conn: &Connection) { let conn = conn; match args.subcommand() { ("new", Some(x)) => new(x, conn), - _ => println!("Unknwon subcommand"), + ("reset-password", Some(x)) => reset_password(x, conn), + _ => println!("Unknown subcommand"), } } @@ -76,3 +91,15 @@ fn new<'a>(args: &ArgMatches<'a>, conn: &Connection) { ).expect("Couldn't save new user") .update_boxes(conn).expect("Couldn't update ActivityPub informations for new user"); } + +fn reset_password<'a>(args: &ArgMatches<'a>, conn: &Connection) { + let username = args.value_of("name").map(String::from).unwrap_or_else(|| super::ask_for("Username")); + let user = User::find_by_name(conn, &username, Instance::get_local(conn).expect("Failed to get local instance").id) + .expect("Failed to get user"); + let password = args.value_of("password").map(String::from).unwrap_or_else(|| { + print!("Password: "); + io::stdout().flush().expect("Couldn't flush STDOUT"); + rpassword::read_password().expect("Couldn't read your password.") + }); + user.reset_password(conn, &password).expect("Failed to reset password"); +} diff --git a/plume-models/src/users.rs b/plume-models/src/users.rs index 1a2f1d2..37e8b7e 100644 --- a/plume-models/src/users.rs +++ b/plume-models/src/users.rs @@ -381,6 +381,13 @@ impl User { .unwrap_or(false) } + pub fn reset_password(&self, conn: &Connection, pass: &str) -> Result<()> { + diesel::update(self) + .set(users::hashed_password.eq(User::hash_pass(pass)?)) + .execute(conn)?; + Ok(()) + } + pub fn update_boxes(&self, conn: &Connection) -> Result<()> { let instance = self.get_instance(conn)?; if self.outbox_url.is_empty() {