diff --git a/core/permissions.php b/core/permissions.php index a14b8205..eeabf41c 100644 --- a/core/permissions.php +++ b/core/permissions.php @@ -18,6 +18,7 @@ abstract class Permissions public const BAN_IP = "ban_ip"; public const CREATE_USER = "create_user"; + public const CREATE_OTHER_USER = "create_other_user"; public const EDIT_USER_NAME = "edit_user_name"; public const EDIT_USER_PASSWORD = "edit_user_password"; public const EDIT_USER_INFO = "edit_user_info"; # email address, etc diff --git a/core/userclass.php b/core/userclass.php index 4c9c4e0f..bc8fc2b2 100644 --- a/core/userclass.php +++ b/core/userclass.php @@ -118,6 +118,7 @@ new UserClass("admin", "base", [ Permissions::BAN_IP => true, Permissions::CREATE_USER => true, + Permissions::CREATE_OTHER_USER => true, Permissions::EDIT_USER_NAME => true, Permissions::EDIT_USER_PASSWORD => true, Permissions::EDIT_USER_INFO => true, diff --git a/ext/user/events.php b/ext/user/events.php index c9171df6..ad012a63 100644 --- a/ext/user/events.php +++ b/ext/user/events.php @@ -55,13 +55,16 @@ class UserCreationEvent extends Event public $password; /** @var string */ public $email; + /** @var bool */ + public $login; - public function __construct(string $name, string $pass, string $email) + public function __construct(string $name, string $pass, string $email, bool $login) { parent::__construct(); $this->username = $name; $this->password = $pass; $this->email = $email; + $this->login = $login; } } diff --git a/ext/user/main.php b/ext/user/main.php index 6b1bbc38..a9133cf3 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -109,6 +109,12 @@ class UserPage extends Extension $this->page_recover($_POST['username']); } elseif ($event->get_arg(0) == "create") { $this->page_create(); + } elseif ($event->get_arg(0) == "create_other") { + $uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email'], false); + send_event($uce); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("admin")); + $page->flash("Created new user"); } elseif ($event->get_arg(0) == "list") { $t = new UserTable($database->raw_db()); $t->token = $user->get_auth_token(); @@ -327,10 +333,21 @@ class UserPage extends Extension $event->add_link("Log Out", make_link("user_admin/logout"), 99); } + public function onAdminBuilding(AdminBuildingEvent $event) + { + global $user; + if ($user->can(Permissions::CREATE_OTHER_USER)) { + $this->theme->display_user_creator(); + } + } + public function onUserCreation(UserCreationEvent $event) { $this->check_user_creation($event); - $this->create_user($event); + $user = $this->create_user($event); + if ($event->login) { + send_event(new UserLoginEvent($user)); + } } public function onSearchTermParse(SearchTermParseEvent $event) @@ -364,7 +381,6 @@ class UserPage extends Extension } } - private function show_user_info() { global $user, $page; @@ -457,7 +473,7 @@ class UserPage extends Extension throw new UserCreationException("Error in captcha"); } - $uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email']); + $uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email'], true); send_event($uce); $this->set_login_cookie($uce->username, $uce->password); $page->set_mode(PageMode::REDIRECT); @@ -486,7 +502,7 @@ class UserPage extends Extension } } - private function create_user(UserCreationEvent $event) + private function create_user(UserCreationEvent $event): User { global $database, $user; @@ -503,9 +519,10 @@ class UserPage extends Extension $uid = $database->get_last_insert_id('users_id_seq'); $user = User::by_name($event->username); $user->set_password($event->password); - send_event(new UserLoginEvent($user)); log_info("user", "Created User #$uid ({$event->username})"); + + return $user; } private function set_login_cookie(string $name, string $pass) diff --git a/ext/user/theme.php b/ext/user/theme.php index 2fa232bd..dbab5ae2 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -105,6 +105,40 @@ class UserPageTheme extends Themelet $page->add_block(new Block("Signup", (string)$html)); } + public function display_user_creator() + { + global $page; + + $form = SHM_SIMPLE_FORM( + "user_admin/create_other", + TABLE( + ["class"=>"form"], + TBODY( + TR( + TH("Name"), + TD(INPUT(["type"=>'text', "name"=>'name', "required"=>true])) + ), + TR( + TH("Password"), + TD(INPUT(["type"=>'password', "name"=>'pass1', "required"=>true])) + ), + TR( + TH(rawHTML("Repeat Password")), + TD(INPUT(["type"=>'password', "name"=>'pass2', "required"=>true])) + ), + TR( + TH(rawHTML("Email (Optional)")), + TD(INPUT(["type"=>'email', "name"=>'email'])) + ), + ), + TFOOT( + TR(TD(["colspan"=>"2"], INPUT(["type"=>"submit", "value"=>"Create Account"]))) + ) + ) + ); + $page->add_block(new Block("Create User", (string)$form, "main", 75)); + } + public function display_signups_disabled(Page $page) { $page->set_title("Signups Disabled"); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 212d0140..34747d01 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -100,7 +100,7 @@ abstract class ShimmiePHPUnitTestCase extends TestCase { if (is_null(User::by_name($name))) { $userPage = new UserPage(); - $userPage->onUserCreation(new UserCreationEvent($name, $name, "")); + $userPage->onUserCreation(new UserCreationEvent($name, $name, "", false)); assert(!is_null(User::by_name($name)), "Creation of user $name failed"); } }