From 0589f9d72e94af74557cbb92a283c0aafd113121 Mon Sep 17 00:00:00 2001 From: Shish Date: Tue, 7 Feb 2012 15:15:18 +0000 Subject: [PATCH] fine grained permission bits --- core/imageboard.pack.php | 2 +- core/user.class.php | 78 +++++++++++++++++++++++++++++++++----- ext/alias_editor/main.php | 10 ++--- ext/alias_editor/theme.php | 13 ++++--- ext/comment/main.php | 2 +- ext/comment/theme.php | 5 +-- ext/ext_manager/main.php | 4 +- ext/image/main.php | 8 ++-- ext/setup/main.php | 4 +- ext/tag_edit/main.php | 16 ++++---- ext/upload/main.php | 4 +- ext/user/main.php | 14 +++---- ext/user/theme.php | 4 +- ext/view/theme.php | 2 +- lib/shimmie.js | 27 +------------ 15 files changed, 114 insertions(+), 79 deletions(-) diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index 73eb31f3..ca198452 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -119,7 +119,7 @@ class Image { if($limit < 1) $limit = 1; if(SPEED_HAX) { - if($user->is_anonymous() and count($tags) > 3) { + if(!$user->can("big_search") and count($tags) > 3) { die("Anonymous users may only search for up to 3 tags at a time"); // FIXME: throw an exception? } } diff --git a/core/user.class.php b/core/user.class.php index 653a6929..39204ff6 100644 --- a/core/user.class.php +++ b/core/user.class.php @@ -4,10 +4,6 @@ function _new_user($row) { return new User($row); } -$_perm_map = array( - "override_config" => "admin", -); - /** * An object representing a row in the "users" table. @@ -96,12 +92,74 @@ class User { * useful user object functions start here */ public function can($ability) { - global $_perm_map; - $needed = $_perm_map[$ability]; - if($needed == "admin" && $this->is_admin()) return true; - if($needed == "user" && $this->is_logged_in()) return true; - if($needed == "anon") return true; - return false; + global $config; + + // TODO: make this into an editable database table + $user_classes = array( + "anonymous" => array( + "change_setting" => False, # web-level settings, eg the config table + "override_config" => False, # sys-level config, eg config.php + "big_search" => False, # more than 3 tags (speed mode only) + "lock_image" => False, + "view_ip" => False, # view IP addresses associated with things + "change_password" => False, + "change_user_info" => False, + "delete_user" => False, + "delete_image" => False, + "delete_comment" => False, + "replace_image" => False, + "manage_extension_list" => False, + "manage_alias_list" => False, + "edit_tag" => $config->get_bool("tag_edit_anon"), + "edit_source" => $config->get_bool("source_edit_anon"), + "mass_tag_edit" => False, + ), + "user" => array( + "change_setting" => False, + "override_config" => False, + "big_search" => True, + "lock_image" => False, + "view_ip" => False, + "change_password" => False, + "change_user_info" => False, + "delete_user" => False, + "delete_image" => False, + "delete_comment" => False, + "replace_image" => False, + "manage_extension_list" => False, + "manage_alias_list" => False, + "edit_tag" => True, + "edit_source" => True, + "mass_tag_edit" => False, + ), + "admin" => array( + "change_setting" => True, + "override_config" => True, + "big_search" => True, + "lock_image" => True, + "view_ip" => True, + "change_password" => True, + "change_user_info" => True, + "delete_user" => True, + "delete_image" => True, + "delete_comment" => True, + "replace_image" => True, + "manage_extension_list" => True, + "manage_alias_list" => True, + "edit_tag" => True, + "edit_source" => True, + "mass_tag_edit" => True, + ), + ); + + return $user_classes[$this->get_class()][$action]; + } + + // FIXME: this should be a column in the users table + public function get_class() { + if($this->is_admin()) return "admin"; + else if($this->is_logged_in()) return "user"; + else return"anonymous"; } diff --git a/ext/alias_editor/main.php b/ext/alias_editor/main.php index 2942809d..7a246144 100755 --- a/ext/alias_editor/main.php +++ b/ext/alias_editor/main.php @@ -28,7 +28,7 @@ class AliasEditor extends SimpleExtension { if($event->page_matches("alias")) { if($event->get_arg(0) == "add") { - if($user->is_admin()) { + if($user->can("manage_alias_list")) { if(isset($_POST['oldtag']) && isset($_POST['newtag'])) { try { $aae = new AddAliasEvent($_POST['oldtag'], $_POST['newtag']); @@ -43,7 +43,7 @@ class AliasEditor extends SimpleExtension { } } else if($event->get_arg(0) == "remove") { - if($user->is_admin()) { + if($user->can("manage_alias_list")) { if(isset($_POST['oldtag'])) { $database->execute("DELETE FROM aliases WHERE oldtag=:oldtag", array("oldtag" => $_POST['oldtag'])); log_info("alias_editor", "Deleted alias for ".$_POST['oldtag']); @@ -74,7 +74,7 @@ class AliasEditor extends SimpleExtension { $total_pages = ceil($database->get_one("SELECT COUNT(*) FROM aliases") / $alias_per_page); - $this->theme->display_aliases($page, $alias, $user->is_admin(), $page_number + 1, $total_pages); + $this->theme->display_aliases($alias, $page_number + 1, $total_pages); } else if($event->get_arg(0) == "export") { $page->set_mode("data"); @@ -82,7 +82,7 @@ class AliasEditor extends SimpleExtension { $page->set_data($this->get_alias_csv($database)); } else if($event->get_arg(0) == "import") { - if($user->is_admin()) { + if($user->can("manage_alias_list")) { if(count($_FILES) > 0) { $tmp = $_FILES['alias_file']['tmp_name']; $contents = file_get_contents($tmp); @@ -115,7 +115,7 @@ class AliasEditor extends SimpleExtension { public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if($user->is_admin()) { + if($user->can("manage_alias_list")) { $event->add_link("Alias Editor", make_link("alias/list")); } } diff --git a/ext/alias_editor/theme.php b/ext/alias_editor/theme.php index cec35af0..7b6bfb49 100644 --- a/ext/alias_editor/theme.php +++ b/ext/alias_editor/theme.php @@ -5,10 +5,13 @@ class AliasEditorTheme extends Themelet { * Show a page of aliases: * * $aliases = an array of ($old_tag => $new_tag) - * $is_admin = whether things like "add new alias" should be shown + * $can_manage = whether things like "add new alias" should be shown */ - public function display_aliases(Page $page, $aliases, $is_admin, $pageNumber, $totalPages) { - if($is_admin) { + public function display_aliases($aliases, $pageNumber, $totalPages) { + global $page, $user; + + $can_manage = $user->can("manage_alias_list"); + if($can_manage) { $action = "Action"; $add = " @@ -33,7 +36,7 @@ class AliasEditorTheme extends Themelet { $oe = ($n++ % 2 == 0) ? "even" : "odd"; $h_aliases .= "$h_old$h_new"; - if($is_admin) { + if($can_manage) { $h_aliases .= " ".make_form(make_link("alias/remove"))." @@ -70,7 +73,7 @@ class AliasEditorTheme extends Themelet { $page->set_heading("Alias List"); $page->add_block(new NavBlock()); $page->add_block(new Block("Aliases", $html)); - if($is_admin) { + if($can_manage) { $page->add_block(new Block("Bulk Upload", $bulk_html, "main", 51)); } diff --git a/ext/comment/main.php b/ext/comment/main.php index 0a1aaebf..b64a8984 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -128,7 +128,7 @@ class CommentList extends SimpleExtension { } } else if($event->get_arg(0) === "delete") { - if($user->is_admin()) { + if($user->can("delete_comment")) { // FIXME: post, not args if($event->count_args() === 3) { send_event(new CommentDeletionEvent($event->get_arg(1))); diff --git a/ext/comment/theme.php b/ext/comment/theme.php index c0f8ca0b..d594ebe8 100644 --- a/ext/comment/theme.php +++ b/ext/comment/theme.php @@ -170,10 +170,9 @@ class CommentListTheme extends Themelet { $hash = md5(strtolower($comment->owner_email)); $avatar = "
"; } - $a = $user->is_admin(); $h_reply = " - Reply"; - $h_ip = $a ? "
$h_poster_ip" : ""; - $h_del = $a ? + $h_ip = $user->can("view_ip") ? "
$h_poster_ip" : ""; + $h_del = $user->can("delete_comment") ? ' - Del' : ''; return ' diff --git a/ext/ext_manager/main.php b/ext/ext_manager/main.php index 1b90ef0a..3500401c 100644 --- a/ext/ext_manager/main.php +++ b/ext/ext_manager/main.php @@ -91,7 +91,7 @@ class ExtManager extends SimpleExtension { public function onPageRequest(PageRequestEvent $event) { global $page, $user; if($event->page_matches("ext_manager")) { - if($user->is_admin()) { + if($user->can("manage_extension_list")) { if($event->get_arg(0) == "set" && $user->check_auth_token()) { if(is_writable("ext")) { $this->set_things($_POST); @@ -130,7 +130,7 @@ class ExtManager extends SimpleExtension { public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if($user->is_admin()) { + if($user->can("manage_extension_list")) { $event->add_link("Extension Manager", make_link("ext_manager")); } else { diff --git a/ext/image/main.php b/ext/image/main.php index 0fde1e24..d0288131 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -162,7 +162,7 @@ class ImageIO extends SimpleExtension { } if($event->page_matches("image_admin/delete")) { global $page, $user; - if($user->is_admin() && isset($_POST['image_id']) && $user->check_auth_token()) { + if($user->can("delete_image") && isset($_POST['image_id']) && $user->check_auth_token()) { $image = Image::by_id($_POST['image_id']); if($image) { send_event(new ImageDeletionEvent($image)); @@ -173,7 +173,7 @@ class ImageIO extends SimpleExtension { } if($event->page_matches("image_admin/replace")) { global $page, $user; - if($user->is_admin() && isset($_POST['image_id']) && $user->check_auth_token()) { + if($user->can("replace_image") && isset($_POST['image_id']) && $user->check_auth_token()) { $image = Image::by_id($_POST['image_id']); if($image) { $page->set_mode("redirect"); @@ -190,11 +190,11 @@ class ImageIO extends SimpleExtension { global $user; global $config; - if($user->is_admin()) { + if($user->can("delete_image")) { $event->add_part($this->theme->get_deleter_html($event->image->id)); } /* In the future, could perhaps allow users to replace images that they own as well... */ - if ($user->is_admin() && $config->get_bool("upload_replace")) { + if ($user->can("replace_image") && $config->get_bool("upload_replace")) { $event->add_part($this->theme->get_replace_html($event->image->id)); } } diff --git a/ext/setup/main.php b/ext/setup/main.php index f93ac7fa..4e5b950a 100644 --- a/ext/setup/main.php +++ b/ext/setup/main.php @@ -187,7 +187,7 @@ class Setup extends SimpleExtension { } if($event->page_matches("setup")) { - if(!$user->is_admin()) { + if(!$user->can("change_setting")) { $this->theme->display_permission_denied($page); } else { @@ -329,7 +329,7 @@ class Setup extends SimpleExtension { public function onUserBlockBuilding(UserBlockBuildingEvent $event) { global $user; - if($user->is_admin()) { + if($user->can("change_setting")) { $event->add_link("Board Config", make_link("setup")); } } diff --git a/ext/tag_edit/main.php b/ext/tag_edit/main.php index a06425c1..184a5dba 100644 --- a/ext/tag_edit/main.php +++ b/ext/tag_edit/main.php @@ -60,7 +60,7 @@ class TagEdit extends SimpleExtension { global $user, $page; if($event->page_matches("tag_edit")) { if($event->get_arg(0) == "replace") { - if($user->is_admin() && isset($_POST['search']) && isset($_POST['replace'])) { + if($user->can("mass_tag_edit") && isset($_POST['search']) && isset($_POST['replace'])) { $search = $_POST['search']; $replace = $_POST['replace']; $this->mass_tag_edit($search, $replace); @@ -82,7 +82,7 @@ class TagEdit extends SimpleExtension { else { $this->theme->display_error($page, "Error", "Anonymous tag editing is disabled"); } - if($user->is_admin()) { + if($user->can("lock_image")) { $locked = isset($_POST['tag_edit__locked']) && $_POST['tag_edit__locked']=="on"; send_event(new LockSetEvent($event->image, $locked)); } @@ -90,21 +90,21 @@ class TagEdit extends SimpleExtension { public function onTagSet(TagSetEvent $event) { global $user; - if($user->is_admin() || !$event->image->is_locked()) { + if($user->can("edit_tag") || !$event->image->is_locked()) { $event->image->set_tags($event->tags); } } public function onSourceSet(SourceSetEvent $event) { global $user; - if($user->is_admin() || !$event->image->is_locked()) { + if($user->can("edit_tag") || !$event->image->is_locked()) { $event->image->set_source($event->source); } } public function onLockSet(LockSetEvent $event) { global $user; - if($user->is_admin()) { + if($user->can("lock_image")) { $event->image->set_locked($event->locked); } } @@ -130,7 +130,7 @@ class TagEdit extends SimpleExtension { if($this->can_source($event->image)) { $event->add_part($this->theme->get_source_editor_html($event->image), 41); } - if($user->is_admin()) { + if($user->can("lock_image")) { $event->add_part($this->theme->get_lock_editor_html($event->image), 42); } } @@ -147,7 +147,7 @@ class TagEdit extends SimpleExtension { global $config, $user; return ( ($config->get_bool("tag_edit_anon") || !$user->is_anonymous()) && - ($user->is_admin() || !$image->is_locked()) + ($user->can("edit_tag") || !$image->is_locked()) ); } @@ -155,7 +155,7 @@ class TagEdit extends SimpleExtension { global $config, $user; return ( ($config->get_bool("source_edit_anon") || !$user->is_anonymous()) && - ($user->is_admin() || !$image->is_locked()) + ($user->can("edit_source") || !$image->is_locked()) ); } diff --git a/ext/upload/main.php b/ext/upload/main.php index 979ab413..938a27fa 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -120,7 +120,7 @@ class Upload extends SimpleExtension { } // check if the user is an administrator and can upload files. - if(!$user->is_admin()) { + if(!$user->can("replace_image")) { $this->theme->display_permission_denied($page); } else { @@ -308,7 +308,7 @@ class Upload extends SimpleExtension { } // Checks if user is admin > check if you want locked. - if($user->is_admin() && !empty($_GET['locked'])){ + if($user->can("lock_image") && !empty($_GET['locked'])){ $locked = bool_escape($_GET['locked']); } diff --git a/ext/user/main.php b/ext/user/main.php index b5c9dc64..678b5b9c 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -187,7 +187,7 @@ class UserPage extends SimpleExtension { $this->theme->display_user_links($page, $user, $ubbe->parts); } if( - ($user->is_admin() || ($user->is_logged_in() && $user->id == $event->display_user->id)) && # admin or self-user + ($user->can("view_ip") || ($user->is_logged_in() && $user->id == $event->display_user->id)) && # admin or self-user ($event->display_user->id != $config->get_int('anon_id')) # don't show anon's IP list, it is le huge ) { $this->theme->display_ip_list( @@ -256,7 +256,7 @@ class UserPage extends SimpleExtension { $user_id = int_escape($matches[2]); $event->add_querylet(new Querylet("images.owner_id = $user_id")); } - else if($user->is_admin() && preg_match("/^(poster|user)_ip=([0-9\.]+)$/i", $event->term, $matches)) { + else if($user->can("view_ip") && preg_match("/^(poster|user)_ip=([0-9\.]+)$/i", $event->term, $matches)) { $user_ip = $matches[2]; // FIXME: ip_escape? $event->add_querylet(new Querylet("images.owner_ip = '$user_ip'")); } @@ -354,7 +354,7 @@ class UserPage extends SimpleExtension { $duser = User::by_id($id); - if((!$user->is_admin()) && ($duser->name != $user->name)) { + if((!$user->can("change_user_info")) && ($duser->name != $user->name)) { $this->theme->display_error($page, "Error", "You need to be an admin to change other people's passwords"); } @@ -392,7 +392,7 @@ class UserPage extends SimpleExtension { $duser = User::by_id($id); - if((!$user->is_admin()) && ($duser->name != $user->name)) { + if((!$user->can("change_user_info")) && ($duser->name != $user->name)) { $this->theme->display_error($page, "Error", "You need to be an admin to change other people's addressess"); } @@ -419,7 +419,7 @@ class UserPage extends SimpleExtension { $page->set_title("Error"); $page->set_heading("Error"); $page->add_block(new NavBlock()); - if(!$user->is_admin()) { + if(!$user->can("change_user_info")) { $page->add_block(new Block("Not Admin", "Only admins can edit accounts")); } else if(!isset($_POST['id']) || !is_numeric($_POST['id'])) { @@ -479,7 +479,7 @@ class UserPage extends SimpleExtension { $page->set_heading("Error"); $page->add_block(new NavBlock()); - if (!$user->is_admin()) { + if (!$user->can("delete_user")) { $page->add_block(new Block("Not Admin", "Only admins can delete accounts")); } else if(!isset($_POST['id']) || !is_numeric($_POST['id'])) { @@ -510,7 +510,7 @@ class UserPage extends SimpleExtension { $page->set_heading("Error"); $page->add_block(new NavBlock()); - if (!$user->is_admin()) { + if (!$user->can("delete_user") || !$user->can("delete_image")) { $page->add_block(new Block("Not Admin", "Only admins can delete accounts")); } else if(!isset($_POST['id']) || !is_numeric($_POST['id'])) { diff --git a/ext/user/theme.php b/ext/user/theme.php index df6b7553..69b852fc 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -141,7 +141,7 @@ class UserPageTheme extends Themelet { $page->add_block(new Block("Stats", join("
", $stats), "main", 0)); if(!$user->is_anonymous()) { - if($user->id == $duser->id || $user->is_admin()) { + if($user->id == $duser->id || $user->can("change_user_info")) { $page->add_block(new Block("Options", $this->build_options($duser), "main", 20)); } } @@ -173,7 +173,7 @@ class UserPageTheme extends Themelet { "; - if($user->is_admin()) { + if($user->can("change_user_info")) { $i_user_id = int_escape($duser->id); $h_is_admin = $duser->is_admin() ? " checked" : ""; $html .= " diff --git a/ext/view/theme.php b/ext/view/theme.php index 59f6b730..666ac8bf 100644 --- a/ext/view/theme.php +++ b/ext/view/theme.php @@ -90,7 +90,7 @@ class ViewImageTheme extends Themelet { $html = ""; $html .= "

Uploaded by $h_owner $h_date"; - if($user->is_admin()) { + if($user->can("view_ip")) { $html .= " ($h_ip)"; } if(!is_null($image->source)) { diff --git a/lib/shimmie.js b/lib/shimmie.js index 31e7e7e3..611d49ee 100644 --- a/lib/shimmie.js +++ b/lib/shimmie.js @@ -45,25 +45,8 @@ $(document).ready(function() { $("#commentBox").DefaultValue("Comment"); $("#tagBox").DefaultValue("tagme"); - - // if we're going to show with JS, hide with JS first - pass_confirm = byId("pass_confirm"); - if(pass_confirm) { - pass_confirm.style.display = "none"; - } }); -function showUp(elem) { - e = document.getElementById(elem) - if(!e) return; - e.style.display = ""; -// alert(e.type+": "+e.value); - if(e.value.match(/^http|^ftp/)) { - e.type = "text"; - alert("Box is web upload"); - } -} - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * LibShish-JS * @@ -83,6 +66,7 @@ function byId(id) { } +// used once in ext/setup/main function getHTTPObject() { if (window.XMLHttpRequest){ return new XMLHttpRequest(); @@ -92,15 +76,6 @@ function getHTTPObject() { } } -function ajaxRequest(url, callback) { - var http = getHTTPObject(); - http.open("GET", url, true); - http.onreadystatechange = function() { - if(http.readyState == 4) callback(http.responseText); - } - http.send(null); -} - /* get, set, and delete cookies */ function getCookie( name ) {