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
This commit is contained in:
fdb-hiroshima 2019-01-03 16:45:27 +01:00 committed by Igor Galić
parent dfa89e227a
commit 2333d898b9
2 changed files with 35 additions and 1 deletions

View file

@ -4,6 +4,7 @@ use rpassword;
use std::io::{self, Write}; use std::io::{self, Write};
use plume_models::{ use plume_models::{
Connection, Connection,
instance::Instance,
users::*, users::*,
}; };
@ -43,13 +44,27 @@ pub fn command<'a, 'b>() -> App<'a, 'b> {
.long("admin") .long("admin")
.help("Makes the user an administrator of the instance") .help("Makes the user an administrator of the instance")
).about("Create a new user on this 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) { pub fn run<'a>(args: &ArgMatches<'a>, conn: &Connection) {
let conn = conn; let conn = conn;
match args.subcommand() { match args.subcommand() {
("new", Some(x)) => new(x, conn), ("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") ).expect("Couldn't save new user")
.update_boxes(conn).expect("Couldn't update ActivityPub informations for 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");
}

View file

@ -381,6 +381,13 @@ impl User {
.unwrap_or(false) .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<()> { pub fn update_boxes(&self, conn: &Connection) -> Result<()> {
let instance = self.get_instance(conn)?; let instance = self.get_instance(conn)?;
if self.outbox_url.is_empty() { if self.outbox_url.is_empty() {