[core] fix permissions in forum and notes
This includes preventing silent failures when permission is denied, preventing unauthorized users from being shown the note edit form, patching typos, and extracting NOTES_REQUEST to its own permission
This commit is contained in:
parent
ac86cb1302
commit
aff227ac31
6 changed files with 59 additions and 76 deletions
|
@ -125,6 +125,7 @@ abstract class Permissions
|
|||
public const NOTES_ADMIN = "notes_admin";
|
||||
public const NOTES_CREATE = "notes_create";
|
||||
public const NOTES_EDIT = "notes_edit";
|
||||
public const NOTES_REQUEST = "notes_request";
|
||||
|
||||
public const POOLS_ADMIN = "pools_admin";
|
||||
public const POOLS_CREATE = "pools_create";
|
||||
|
|
|
@ -119,6 +119,7 @@ new UserClass("user", "base", [
|
|||
Permissions::FORUM_CREATE => true,
|
||||
Permissions::NOTES_CREATE => true,
|
||||
Permissions::NOTES_EDIT => true,
|
||||
Permissions::NOTES_REQUEST => true,
|
||||
Permissions::POOLS_CREATE => true,
|
||||
Permissions::POOLS_UPDATE => true,
|
||||
]);
|
||||
|
|
|
@ -102,7 +102,7 @@ class Forum extends Extension
|
|||
if ($event->page_matches("forum/index", paged: true)) {
|
||||
$pageNumber = $event->get_iarg('page_num', 1) - 1;
|
||||
$this->show_last_threads($page, $pageNumber, $user->can(Permissions::FORUM_ADMIN));
|
||||
if (!$user->can(Permissions::FORUM_CREATE)) {
|
||||
if ($user->can(Permissions::FORUM_CREATE)) {
|
||||
$this->theme->display_new_thread_composer($page);
|
||||
}
|
||||
}
|
||||
|
@ -119,62 +119,51 @@ class Forum extends Extension
|
|||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->theme->add_actions_block($page, $threadID);
|
||||
}
|
||||
if (!$user->can(Permissions::FORUM_CREATE)) {
|
||||
if ($user->can(Permissions::FORUM_CREATE)) {
|
||||
$this->theme->display_new_post_composer($page, $threadID);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("forum/new")) {
|
||||
if ($event->page_matches("forum/new", permission: Permissions::FORUM_CREATE)) {
|
||||
$this->theme->display_new_thread_composer($page);
|
||||
}
|
||||
if ($event->page_matches("forum/create")) {
|
||||
$redirectTo = "forum/index";
|
||||
if (!$user->can(Permissions::FORUM_CREATE)) {
|
||||
$errors = $this->sanity_check_new_thread();
|
||||
if ($event->page_matches("forum/create", permission: Permissions::FORUM_CREATE)) {
|
||||
$errors = $this->sanity_check_new_thread();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
throw new InvalidInput(implode("<br>", $errors));
|
||||
}
|
||||
|
||||
$newThreadID = $this->save_new_thread($user);
|
||||
$this->save_new_post($newThreadID, $user);
|
||||
$redirectTo = "forum/view/" . $newThreadID . "/1";
|
||||
if (count($errors) > 0) {
|
||||
throw new InvalidInput(implode("<br>", $errors));
|
||||
}
|
||||
|
||||
$newThreadID = $this->save_new_thread($user);
|
||||
$this->save_new_post($newThreadID, $user);
|
||||
$redirectTo = "forum/view/" . $newThreadID . "/1";
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link($redirectTo));
|
||||
}
|
||||
if ($event->page_matches("forum/delete/{threadID}/{postID}")) {
|
||||
if ($event->page_matches("forum/delete/{threadID}/{postID}", permission: Permissions::FORUM_ADMIN)) {
|
||||
$threadID = $event->get_iarg('threadID');
|
||||
$postID = $event->get_iarg('postID');
|
||||
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->delete_post($postID);
|
||||
}
|
||||
|
||||
$this->delete_post($postID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/view/" . $threadID));
|
||||
}
|
||||
if ($event->page_matches("forum/nuke/{threadID}")) {
|
||||
if ($event->page_matches("forum/nuke/{threadID}", permission: Permissions::FORUM_ADMIN)) {
|
||||
$threadID = $event->get_iarg('threadID');
|
||||
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->delete_thread($threadID);
|
||||
}
|
||||
|
||||
$this->delete_thread($threadID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/index"));
|
||||
}
|
||||
if ($event->page_matches("forum/answer")) {
|
||||
if ($event->page_matches("forum/answer", permission: Permissions::FORUM_CREATE)) {
|
||||
$threadID = int_escape($event->req_POST("threadID"));
|
||||
$total_pages = $this->get_total_pages_for_thread($threadID);
|
||||
if (!$user->can(Permissions::FORUM_CREATE)) {
|
||||
$errors = $this->sanity_check_new_post();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
throw new InvalidInput(implode("<br>", $errors));
|
||||
}
|
||||
$this->save_new_post($threadID, $user);
|
||||
$errors = $this->sanity_check_new_post();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
throw new InvalidInput(implode("<br>", $errors));
|
||||
}
|
||||
$this->save_new_post($threadID, $user);
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/view/" . $threadID . "/" . $total_pages));
|
||||
}
|
||||
|
|
|
@ -90,61 +90,46 @@ class Notes extends Extension
|
|||
if ($event->page_matches("note/history/{note_id}", paged: true)) {
|
||||
$this->get_history($event->get_iarg('note_id'), $event->get_iarg('page_num', 1) - 1);
|
||||
}
|
||||
if ($event->page_matches("note/revert/{noteID}/{reviewID}")) {
|
||||
if ($event->page_matches("note/revert/{noteID}/{reviewID}", permission: Permissions::NOTES_EDIT)) {
|
||||
$noteID = $event->get_iarg('noteID');
|
||||
$reviewID = $event->get_iarg('reviewID');
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->revert_history($noteID, $reviewID);
|
||||
}
|
||||
$this->revert_history($noteID, $reviewID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("note/updated"));
|
||||
}
|
||||
if ($event->page_matches("note/add_request")) {
|
||||
if ($event->page_matches("note/add_request", permission: Permissions::NOTES_REQUEST)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->add_note_request($image_id);
|
||||
}
|
||||
$this->add_note_request($image_id);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
if ($event->page_matches("note/nuke_requests")) {
|
||||
if ($event->page_matches("note/nuke_requests", permission: Permissions::NOTES_ADMIN)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->nuke_requests($image_id);
|
||||
}
|
||||
$this->nuke_requests($image_id);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
if ($event->page_matches("note/create_note")) {
|
||||
if ($event->page_matches("note/create_note", permission: Permissions::NOTES_CREATE)) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if (!$user->can(Permissions::NOTES_CREATE)) {
|
||||
$note_id = $this->add_new_note();
|
||||
$page->set_data(\Safe\json_encode([
|
||||
'status' => 'success',
|
||||
'note_id' => $note_id,
|
||||
]));
|
||||
}
|
||||
$note_id = $this->add_new_note();
|
||||
$page->set_data(\Safe\json_encode([
|
||||
'status' => 'success',
|
||||
'note_id' => $note_id,
|
||||
]));
|
||||
}
|
||||
if ($event->page_matches("note/update_note")) {
|
||||
if ($event->page_matches("note/update_note", permission: Permissions::NOTES_EDIT)) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if (!$user->can(Permissions::NOTES_EDIT)) {
|
||||
$this->update_note();
|
||||
$page->set_data(\Safe\json_encode(['status' => 'success']));
|
||||
}
|
||||
$this->update_note();
|
||||
$page->set_data(\Safe\json_encode(['status' => 'success']));
|
||||
}
|
||||
if ($event->page_matches("note/delete_note")) {
|
||||
if ($event->page_matches("note/delete_note", permission: Permissions::NOTES_ADMIN)) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->delete_note();
|
||||
$page->set_data(\Safe\json_encode(['status' => 'success']));
|
||||
}
|
||||
$this->delete_note();
|
||||
$page->set_data(\Safe\json_encode(['status' => 'success']));
|
||||
}
|
||||
if ($event->page_matches("note/nuke_notes")) {
|
||||
if ($event->page_matches("note/nuke_notes", permission: Permissions::NOTES_ADMIN)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->nuke_notes($image_id);
|
||||
}
|
||||
|
||||
$this->nuke_notes($image_id);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
|
@ -160,7 +145,7 @@ class Notes extends Extension
|
|||
|
||||
//display form on image event
|
||||
$notes = $this->get_notes($event->image->id);
|
||||
$this->theme->display_note_system($page, $event->image->id, $notes, $user->can(Permissions::NOTES_ADMIN));
|
||||
$this->theme->display_note_system($page, $event->image->id, $notes, $user->can(Permissions::NOTES_ADMIN), $user->can(Permissions::NOTES_EDIT));
|
||||
}
|
||||
|
||||
|
||||
|
@ -170,14 +155,17 @@ class Notes extends Extension
|
|||
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
if (!$user->can(Permissions::NOTES_CREATE)) {
|
||||
if ($user->can(Permissions::NOTES_CREATE)) {
|
||||
$event->add_part($this->theme->note_button($event->image->id));
|
||||
$event->add_part($this->theme->request_button($event->image->id));
|
||||
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$event->add_part($this->theme->nuke_notes_button($event->image->id));
|
||||
$event->add_part($this->theme->nuke_requests_button($event->image->id));
|
||||
}
|
||||
}
|
||||
if ($user->can(Permissions::NOTES_REQUEST)) {
|
||||
$event->add_part($this->theme->request_button($event->image->id));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,10 +48,13 @@ function renderNotes() {
|
|||
noteDiv.style.height = note.height * scale + 'px';
|
||||
let text = document.createElement('div');
|
||||
text.innerText = note.note;
|
||||
noteDiv.addEventListener('click', (e) => {
|
||||
noteBeingEdited = note.note_id;
|
||||
renderNotes();
|
||||
});
|
||||
// only add listener if user has edit permissions
|
||||
if (window.notes_edit) {
|
||||
noteDiv.addEventListener('click', (e) => {
|
||||
noteBeingEdited = note.note_id;
|
||||
renderNotes();
|
||||
});
|
||||
}
|
||||
noteDiv.appendChild(text);
|
||||
notesContainer.appendChild(noteDiv);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class NotesTheme extends Themelet
|
|||
/**
|
||||
* @param Note[] $recovered_notes
|
||||
*/
|
||||
public function display_note_system(Page $page, int $image_id, array $recovered_notes, bool $adminOptions): void
|
||||
public function display_note_system(Page $page, int $image_id, array $recovered_notes, bool $adminOptions, bool $editOptions): void
|
||||
{
|
||||
$to_json = [];
|
||||
foreach ($recovered_notes as $note) {
|
||||
|
@ -65,6 +65,7 @@ class NotesTheme extends Themelet
|
|||
window.notes = ".\Safe\json_encode($to_json).";
|
||||
window.notes_image_id = $image_id;
|
||||
window.notes_admin = ".($adminOptions ? "true" : "false").";
|
||||
window.notes_edit = ".($editOptions ? "true" : "false").";
|
||||
</script>");
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue