[wiki] cleanups and security

This commit is contained in:
Shish 2024-02-10 16:40:38 +00:00
parent 7895978d93
commit 20a87576b9
4 changed files with 80 additions and 92 deletions

View file

@ -97,7 +97,7 @@ class ImageIO extends Extension
send_event(new ImageDeletionEvent($image));
if ($config->get_string(ImageConfig::ON_DELETE) === ImageConfig::ON_DELETE_NEXT) {
redirect_to_next_image($image, @$event->get_GET('search'));
redirect_to_next_image($image, $event->get_GET('search'));
} else {
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(referer_or(make_link(), ['post/view']));

View file

@ -182,65 +182,67 @@ class Wiki extends Extension
} else {
$title = $event->get_arg(0);
}
$action = $event->count_args() > 1 ? $event->get_arg(1) : "view";
$revision = -1;
if ($event->get_GET('revision')) {
$revision = int_escape($event->get_GET('revision'));
}
$content = $this->get_page($title, $revision);
$this->theme->display_page($page, $content, $this->get_page("wiki:sidebar"));
} elseif ($event->page_matches("wiki_admin/edit")) {
$content = $this->get_page($event->req_POST('title'));
$this->theme->display_page_editor($page, $content);
} elseif ($event->page_matches("wiki_admin/save")) {
$title = $event->req_POST('title');
$rev = int_escape($event->req_POST('revision'));
$body = $event->req_POST('body');
$lock = $user->can(Permissions::WIKI_ADMIN) && ($event->get_POST('lock') == "on");
if($action == "view") {
$revision = int_escape($event->get_GET('revision') ?? "-1");
$content = $this->get_page($title, $revision);
$this->theme->display_page($page, $content, $this->get_page("wiki:sidebar"));
} elseif($action == "history") {
$history = $this->get_history($title);
$this->theme->display_page_history($page, $title, $history);
} elseif($action == "edit") {
$content = $this->get_page($title);
if ($this->can_edit($user, $content)) {
$this->theme->display_page_editor($page, $content);
} else {
$this->theme->display_permission_denied();
}
} elseif($action == "save" && $user->check_auth_token()) {
$rev = int_escape($event->req_POST('revision'));
$body = $event->req_POST('body');
$lock = $user->can(Permissions::WIKI_ADMIN) && ($event->get_POST('lock') == "on");
if ($this->can_edit($user, $this->get_page($title))) {
$wikipage = $this->get_page($title);
$wikipage->revision = $rev;
$wikipage->body = $body;
$wikipage->locked = $lock;
send_event(new WikiUpdateEvent($user, $wikipage));
$u_title = url_escape($title);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title"));
} else {
$this->theme->display_permission_denied();
}
} elseif ($event->page_matches("wiki_admin/history")) {
$history = $this->get_history($event->get_GET('title'));
$this->theme->display_page_history($page, $event->get_GET('title'), $history);
} elseif ($event->page_matches("wiki_admin/delete_revision")) {
if ($user->can(Permissions::WIKI_ADMIN)) {
$title = $event->req_POST('title');
$revision = int_escape($event->req_POST('revision'));
send_event(new WikiDeleteRevisionEvent($title, $revision));
$u_title = url_escape($title);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title"));
}
} elseif ($event->page_matches("wiki_admin/delete_all")) {
if ($user->can(Permissions::WIKI_ADMIN)) {
$title = $event->req_POST('title');
send_event(new WikiDeletePageEvent($title));
$u_title = url_escape($title);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title"));
if ($this->can_edit($user, $this->get_page($title))) {
$wikipage = $this->get_page($title);
$wikipage->revision = $rev;
$wikipage->body = $body;
$wikipage->locked = $lock;
send_event(new WikiUpdateEvent($user, $wikipage));
$u_title = url_escape($title);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title"));
} else {
$this->theme->display_permission_denied();
}
} elseif($action == "delete_revision" && $user->check_auth_token()) {
$content = $this->get_page($title);
if ($user->can(Permissions::WIKI_ADMIN)) {
$revision = int_escape($event->req_POST('revision'));
send_event(new WikiDeleteRevisionEvent($title, $revision));
$u_title = url_escape($title);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title"));
} else {
$this->theme->display_permission_denied();
}
} elseif($action == "delete_all" && $user->check_auth_token()) {
if ($user->can(Permissions::WIKI_ADMIN)) {
send_event(new WikiDeletePageEvent($title));
$u_title = url_escape($title);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title"));
}
}
}
}
public function onPageNavBuilding(PageNavBuildingEvent $event): void
{
$event->add_nav_link("wiki", new Link('wiki'), "Wiki");
}
public function onPageSubNavBuilding(PageSubNavBuildingEvent $event): void
{
if ($event->parent == "wiki") {

View file

@ -13,44 +13,30 @@ class WikiTest extends ShimmiePHPUnitTestCase
$this->assert_text("This is a default page");
}
public function testAccess(): void
// By default users are read-only
public function testAccessUser(): void
{
global $config;
foreach (["anon", "user", "admin"] as $user) {
foreach ([false, true] as $allowed) {
// admin has no settings to set
if ($user != "admin") {
$config->set_bool("wiki_edit_$user", $allowed);
}
$this->log_in_as_user();
if ($user == "user") {
$this->log_in_as_user();
}
if ($user == "admin") {
$this->log_in_as_admin();
}
$this->get_page("wiki/test");
$this->assert_title("test");
$this->assert_text("This is a default page");
$this->get_page("wiki/test");
$this->assert_title("test");
$this->assert_text("This is a default page");
$this->get_page("wiki/test/edit");
$this->assert_no_text("Editor");
}
if ($allowed || $user == "admin") {
$this->post_page("wiki_admin/edit", ["title" => "test"]);
$this->assert_text("Editor");
}
/*
// Everyone can see the editor
else {
$this->post_page("wiki_admin/edit", ["title"=>"test"]);
$this->assert_no_text("Editor");
}
*/
// Admins can edit
public function testAccessAdmin(): void
{
$this->log_in_as_admin();
if ($user == "user" || $user == "admin") {
$this->log_out();
}
}
}
$this->get_page("wiki/test");
$this->assert_title("test");
$this->assert_text("This is a default page");
$this->get_page("wiki/test/edit");
$this->assert_text("Editor");
}
public function testDefault(): void
@ -107,6 +93,10 @@ class WikiTest extends ShimmiePHPUnitTestCase
$this->assert_text("Mooooo 2");
$this->assert_text("Revision 2");
$this->get_page("wiki/test/history");
$this->assert_title("test");
$this->assert_text("2");
send_event(new WikiDeleteRevisionEvent("test", 2));
$this->get_page("wiki/test");
$this->assert_text("Mooooo 1");

View file

@ -75,7 +75,7 @@ class WikiTheme extends Themelet
protected function create_edit_html(WikiPage $page): string
{
$h_title = html_escape($page->title);
$u_title = url_escape($page->title);
$i_revision = $page->revision + 1;
global $user;
@ -85,9 +85,7 @@ class WikiTheme extends Themelet
} else {
$lock = "";
}
return "
".make_form(make_link("wiki_admin/save"))."
<input type='hidden' name='title' value='$h_title'>
return make_form(make_link("wiki/$u_title/save"))."
<input type='hidden' name='revision' value='$i_revision'>
<textarea name='body' style='width: 100%' rows='20'>".html_escape($page->body)."</textarea>
$lock
@ -100,6 +98,7 @@ class WikiTheme extends Themelet
{
global $user;
$u_title = url_escape($page->title);
$owner = $page->get_owner();
$formatted_body = Wiki::format_tag_wiki_page($page);
@ -107,8 +106,7 @@ class WikiTheme extends Themelet
$edit = "<table><tr>";
$edit .= Wiki::can_edit($user, $page) ?
"
<td>".make_form(make_link("wiki_admin/edit"))."
<input type='hidden' name='title' value='".html_escape($page->title)."'>
<td>".make_form(make_link("wiki/$u_title/edit"))."
<input type='hidden' name='revision' value='".$page->revision."'>
<input type='submit' value='Edit'>
</form></td>
@ -116,13 +114,11 @@ class WikiTheme extends Themelet
"";
if ($user->can(Permissions::WIKI_ADMIN)) {
$edit .= "
<td>".make_form(make_link("wiki_admin/delete_revision"))."
<input type='hidden' name='title' value='".html_escape($page->title)."'>
<td>".make_form(make_link("wiki/$u_title/delete_revision"))."
<input type='hidden' name='revision' value='".$page->revision."'>
<input type='submit' value='Delete This Version'>
</form></td>
<td>".make_form(make_link("wiki_admin/delete_all"))."
<input type='hidden' name='title' value='".html_escape($page->title)."'>
<td>".make_form(make_link("wiki/$u_title/delete_all"))."
<input type='submit' value='Delete All'>
</form></td>
";
@ -134,7 +130,7 @@ class WikiTheme extends Themelet
$formatted_body
<hr>
<p class='wiki-footer'>
<a href='".make_link("wiki_admin/history", "title={$page->title}")."'>Revision {$page->revision}</a>
<a href='".make_link("wiki/$u_title/history")."'>Revision {$page->revision}</a>
by <a href='".make_link("user/{$owner->name}")."'>{$owner->name}</a>
at {$page->date}
$edit