[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_ADMIN = "notes_admin";
|
||||||
public const NOTES_CREATE = "notes_create";
|
public const NOTES_CREATE = "notes_create";
|
||||||
public const NOTES_EDIT = "notes_edit";
|
public const NOTES_EDIT = "notes_edit";
|
||||||
|
public const NOTES_REQUEST = "notes_request";
|
||||||
|
|
||||||
public const POOLS_ADMIN = "pools_admin";
|
public const POOLS_ADMIN = "pools_admin";
|
||||||
public const POOLS_CREATE = "pools_create";
|
public const POOLS_CREATE = "pools_create";
|
||||||
|
|
|
@ -119,6 +119,7 @@ new UserClass("user", "base", [
|
||||||
Permissions::FORUM_CREATE => true,
|
Permissions::FORUM_CREATE => true,
|
||||||
Permissions::NOTES_CREATE => true,
|
Permissions::NOTES_CREATE => true,
|
||||||
Permissions::NOTES_EDIT => true,
|
Permissions::NOTES_EDIT => true,
|
||||||
|
Permissions::NOTES_REQUEST => true,
|
||||||
Permissions::POOLS_CREATE => true,
|
Permissions::POOLS_CREATE => true,
|
||||||
Permissions::POOLS_UPDATE => true,
|
Permissions::POOLS_UPDATE => true,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -102,7 +102,7 @@ class Forum extends Extension
|
||||||
if ($event->page_matches("forum/index", paged: true)) {
|
if ($event->page_matches("forum/index", paged: true)) {
|
||||||
$pageNumber = $event->get_iarg('page_num', 1) - 1;
|
$pageNumber = $event->get_iarg('page_num', 1) - 1;
|
||||||
$this->show_last_threads($page, $pageNumber, $user->can(Permissions::FORUM_ADMIN));
|
$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);
|
$this->theme->display_new_thread_composer($page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,62 +119,51 @@ class Forum extends Extension
|
||||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||||
$this->theme->add_actions_block($page, $threadID);
|
$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);
|
$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);
|
$this->theme->display_new_thread_composer($page);
|
||||||
}
|
}
|
||||||
if ($event->page_matches("forum/create")) {
|
if ($event->page_matches("forum/create", permission: Permissions::FORUM_CREATE)) {
|
||||||
$redirectTo = "forum/index";
|
$errors = $this->sanity_check_new_thread();
|
||||||
if (!$user->can(Permissions::FORUM_CREATE)) {
|
|
||||||
$errors = $this->sanity_check_new_thread();
|
|
||||||
|
|
||||||
if (count($errors) > 0) {
|
if (count($errors) > 0) {
|
||||||
throw new InvalidInput(implode("<br>", $errors));
|
throw new InvalidInput(implode("<br>", $errors));
|
||||||
}
|
|
||||||
|
|
||||||
$newThreadID = $this->save_new_thread($user);
|
|
||||||
$this->save_new_post($newThreadID, $user);
|
|
||||||
$redirectTo = "forum/view/" . $newThreadID . "/1";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$newThreadID = $this->save_new_thread($user);
|
||||||
|
$this->save_new_post($newThreadID, $user);
|
||||||
|
$redirectTo = "forum/view/" . $newThreadID . "/1";
|
||||||
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link($redirectTo));
|
$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');
|
$threadID = $event->get_iarg('threadID');
|
||||||
$postID = $event->get_iarg('postID');
|
$postID = $event->get_iarg('postID');
|
||||||
|
$this->delete_post($postID);
|
||||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
|
||||||
$this->delete_post($postID);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("forum/view/" . $threadID));
|
$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');
|
$threadID = $event->get_iarg('threadID');
|
||||||
|
$this->delete_thread($threadID);
|
||||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
|
||||||
$this->delete_thread($threadID);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("forum/index"));
|
$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"));
|
$threadID = int_escape($event->req_POST("threadID"));
|
||||||
$total_pages = $this->get_total_pages_for_thread($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) {
|
$errors = $this->sanity_check_new_post();
|
||||||
throw new InvalidInput(implode("<br>", $errors));
|
|
||||||
}
|
if (count($errors) > 0) {
|
||||||
$this->save_new_post($threadID, $user);
|
throw new InvalidInput(implode("<br>", $errors));
|
||||||
}
|
}
|
||||||
|
$this->save_new_post($threadID, $user);
|
||||||
|
|
||||||
$page->set_mode(PageMode::REDIRECT);
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("forum/view/" . $threadID . "/" . $total_pages));
|
$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)) {
|
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);
|
$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');
|
$noteID = $event->get_iarg('noteID');
|
||||||
$reviewID = $event->get_iarg('reviewID');
|
$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_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("note/updated"));
|
$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"));
|
$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_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("post/view/$image_id"));
|
$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"));
|
$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_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("post/view/$image_id"));
|
$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);
|
$page->set_mode(PageMode::DATA);
|
||||||
if (!$user->can(Permissions::NOTES_CREATE)) {
|
$note_id = $this->add_new_note();
|
||||||
$note_id = $this->add_new_note();
|
$page->set_data(\Safe\json_encode([
|
||||||
$page->set_data(\Safe\json_encode([
|
'status' => 'success',
|
||||||
'status' => 'success',
|
'note_id' => $note_id,
|
||||||
'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);
|
$page->set_mode(PageMode::DATA);
|
||||||
if (!$user->can(Permissions::NOTES_EDIT)) {
|
$this->update_note();
|
||||||
$this->update_note();
|
$page->set_data(\Safe\json_encode(['status' => 'success']));
|
||||||
$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);
|
$page->set_mode(PageMode::DATA);
|
||||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
$this->delete_note();
|
||||||
$this->delete_note();
|
$page->set_data(\Safe\json_encode(['status' => 'success']));
|
||||||
$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"));
|
$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_mode(PageMode::REDIRECT);
|
||||||
$page->set_redirect(make_link("post/view/$image_id"));
|
$page->set_redirect(make_link("post/view/$image_id"));
|
||||||
}
|
}
|
||||||
|
@ -160,7 +145,7 @@ class Notes extends Extension
|
||||||
|
|
||||||
//display form on image event
|
//display form on image event
|
||||||
$notes = $this->get_notes($event->image->id);
|
$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
|
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event): void
|
||||||
{
|
{
|
||||||
global $user;
|
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->note_button($event->image->id));
|
||||||
$event->add_part($this->theme->request_button($event->image->id));
|
|
||||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||||
$event->add_part($this->theme->nuke_notes_button($event->image->id));
|
$event->add_part($this->theme->nuke_notes_button($event->image->id));
|
||||||
$event->add_part($this->theme->nuke_requests_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';
|
noteDiv.style.height = note.height * scale + 'px';
|
||||||
let text = document.createElement('div');
|
let text = document.createElement('div');
|
||||||
text.innerText = note.note;
|
text.innerText = note.note;
|
||||||
noteDiv.addEventListener('click', (e) => {
|
// only add listener if user has edit permissions
|
||||||
noteBeingEdited = note.note_id;
|
if (window.notes_edit) {
|
||||||
renderNotes();
|
noteDiv.addEventListener('click', (e) => {
|
||||||
});
|
noteBeingEdited = note.note_id;
|
||||||
|
renderNotes();
|
||||||
|
});
|
||||||
|
}
|
||||||
noteDiv.appendChild(text);
|
noteDiv.appendChild(text);
|
||||||
notesContainer.appendChild(noteDiv);
|
notesContainer.appendChild(noteDiv);
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class NotesTheme extends Themelet
|
||||||
/**
|
/**
|
||||||
* @param Note[] $recovered_notes
|
* @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 = [];
|
$to_json = [];
|
||||||
foreach ($recovered_notes as $note) {
|
foreach ($recovered_notes as $note) {
|
||||||
|
@ -65,6 +65,7 @@ class NotesTheme extends Themelet
|
||||||
window.notes = ".\Safe\json_encode($to_json).";
|
window.notes = ".\Safe\json_encode($to_json).";
|
||||||
window.notes_image_id = $image_id;
|
window.notes_image_id = $image_id;
|
||||||
window.notes_admin = ".($adminOptions ? "true" : "false").";
|
window.notes_admin = ".($adminOptions ? "true" : "false").";
|
||||||
|
window.notes_edit = ".($editOptions ? "true" : "false").";
|
||||||
</script>");
|
</script>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue