_send_reset(); } else { print $this->_reset_form(); } } public function do_reset() { if (request::method() == "post") { $this->_change_password(); } else { $user = user::lookup_by_hash(Input::instance()->get("key")); if (!empty($user)) { print $this->_new_password_form($user->hash); } else { throw new Exception("@todo FORBIDDEN", 503); } } } private function _send_reset() { $form = $this->_reset_form(); $valid = $form->validate(); if ($valid) { $user = user::lookup_by_name($form->reset->inputs["name"]->value); if (!$user->loaded() || empty($user->email)) { $form->reset->inputs["name"]->add_error("no_email", 1); $valid = false; } } if ($valid) { $user->hash = md5(rand()); $user->save(); $message = new View("reset_password.html"); $message->confirm_url = url::abs_site("password/do_reset?key=$user->hash"); $message->user = $user; Sendmail::factory() ->to($user->email) ->subject(t("Password Reset Request")) ->header("Mime-Version", "1.0") ->header("Content-type", "text/html; charset=iso-8859-1") ->message($message->render()) ->send(); log::success( "user", t("Password reset email sent for user %name", array("name" => $user->name))); } else { // Don't include the username here until you're sure that it's XSS safe log::warning( "user", "Password reset email requested for bogus user"); } message::success(t("Password reset email sent")); print json_encode( array("result" => "success")); } private function _reset_form() { $form = new Forge(url::current(true), "", "post", array("id" => "g-reset-form")); $group = $form->group("reset")->label(t("Reset Password")); $group->input("name")->label(t("Username"))->id("g-name")->class(null)->rules("required"); $group->inputs["name"]->error_messages("no_email", t("No email, unable to reset password")); $group->submit("")->value(t("Reset")); return $form; } private function _new_password_form($hash=null) { $template = new Theme_View("page.html", "other", "reset"); $form = new Forge("password/do_reset", "", "post", array("id" => "g-change-password-form")); $group = $form->group("reset")->label(t("Change Password")); $hidden = $group->hidden("hash"); if (!empty($hash)) { $hidden->value($hash); } $minimum_length = module::get_var("user", "mininum_password_length", 5); $input_password = $group->password("password")->label(t("Password"))->id("g-password") ->rules($minimum_length ? "required|length[$minimum_length, 40]" : "length[40]"); $group->password("password2")->label(t("Confirm Password"))->id("g-password2") ->matches($group->password); $group->inputs["password2"]->error_messages( "mistyped", t("The password and the confirm password must match")); $group->submit("")->value(t("Update")); $template->content = new View("user_form.html"); $template->content->form = $form; return $template; } private function _change_password() { $view = $this->_new_password_form(); if ($view->content->form->validate()) { $user = user::lookup_by_hash(Input::instance()->post("hash")); if (empty($user)) { throw new Exception("@todo FORBIDDEN", 503); } $user->password = $view->content->form->reset->password->value; $user->hash = null; $user->save(); message::success(t("Password reset successfully")); url::redirect(item::root()->abs_url()); } else { print $view; } } }