function scoper_admin_terms_js() { if (!empty($_REQUEST['action']) && 'edit' == $_REQUEST['action']) { return; } if (!empty($_REQUEST['taxonomy'])) { // using this with edit-link-categories if ($tx_obj = get_taxonomy($_REQUEST['taxonomy'])) { $cap_name = $tx_obj->cap->manage_terms; } } if (empty($cap_name)) { $cap_name = 'manage_categories'; } if (cr_user_can($cap_name, BLOG_SCOPE_RS)) { return; } ?> <script type="text/javascript"> /* <![CDATA[ */ jQuery(document).ready( function($) { $('#parent option[value="-1"]').remove(); }); /* ]]> */ </script> <?php }
function _validate_assigner_roles($scope, $src_or_tx_name, $item_id, $roles) { if (!$item_id && !is_user_administrator_rs()) { return false; } $user_has_role = array(); if (TERM_SCOPE_RS == $scope) { foreach (array_keys($roles) as $role_handle) { $role_attributes = $this->scoper->role_defs->get_role_attributes($role_handle); $args = array('src_name' => $role_attributes->src_name, 'object_type' => $role_attributes->object_type); $user_has_role[$role_handle] = $this->user_has_role_in_term($role_handle, $src_or_tx_name, $item_id, $args); } } else { if ($require_blogwide_editor = scoper_get_option('role_admin_blogwide_editor_only')) { global $current_user; $is_user_administrator = is_user_administrator_rs(); $is_content_administrator = is_content_administrator_rs(); } foreach (array_keys($roles) as $role_handle) { // a user must have a blog-wide edit cap to modify editing role assignments (even if they have Editor role assigned for some current object) if ($require_blogwide_editor) { if (!$is_user_administrator && 'admin' == $require_blogwide_editor) { $user_has_role[$role_handle] = false; continue; } if (!$is_content_administrator && 'admin_content' == $require_blogwide_editor) { $user_has_role[$role_handle] = false; continue; } $src_name = $this->scoper->role_defs->member_property($role_handle, 'src_name'); $object_type = $this->scoper->role_defs->member_property($role_handle, 'object_type'); static $can_edit_blogwide; if (!isset($can_edit_blogwide)) { $can_edit_blogwide = array(); } if (!isset($can_edit_blogwide[$src_name][$object_type])) { $can_edit_blogwide[$src_name][$object_type] = $this->scoper->user_can_edit_blogwide($src_name, $object_type, array('require_others_cap' => true)); } if (!$can_edit_blogwide[$src_name][$object_type]) { $user_has_role[$role_handle] = false; continue; } } if (!empty($this->scoper->role_defs->role_caps[$role_handle])) { $user_has_role[$role_handle] = cr_user_can(array_keys($this->scoper->role_defs->role_caps[$role_handle]), $item_id); } } } return $user_has_role; }
function flt_admin_bar_menu(&$bar) { if (is_content_administrator_rs()) { return; } $type = 'new-content'; foreach (get_post_types(array('public' => true), 'object') as $_post_type => $type_obj) { $var = 'new-' . $_post_type; if (isset($bar->menu->{$type}['children']->{$var})) { if (!cr_user_can($type_obj->cap->edit_posts, 0, 0, array('skip_id_generation' => true, 'skip_any_object_check' => true))) { unset($bar->menu->{$type}['children']->{$var}); } } } }
function ui_hide_add_menu() { $tx_obj = get_taxonomy('nav_menu'); if (!empty($GLOBALS['current_user']->allcaps['edit_theme_options'])) { $use_term_roles = scoper_get_otype_option('use_term_roles', 'post'); if (empty($use_term_roles['nav_menu'])) { return; } } if (cr_user_can($tx_obj->cap->manage_terms, BLOG_SCOPE_RS)) { return; } ?> <script type="text/javascript"> /* <![CDATA[ */ jQuery(document).ready( function($) { $('.menu-add-new').hide(); }); /* ]]> */ </script> <?php }
function user_can_admin_object_rs($src_name, $object_type, $object_id = false, $any_obj_role_check = false, $user = '') { if (is_content_administrator_rs()) { return true; } global $scoper; // TODO: is this necessary? $is_new_object = !$object_id && false !== $object_id || 'post' == $src_name && !empty($GLOBALS['post']) && 'auto-draft' == $GLOBALS['post']->post_status; if ($is_new_object) { $status_name = 'post' == $src_name ? 'draft' : ''; } else { $status_name = sanitize_key($scoper->data_sources->detect('status', $src_name, $object_id)); } // TODO: is multi-value array ever passed? if (is_array($object_type)) { if (count($object_type) == 1) { $object_type = reset($object_type); } else { // only WP roles should ever have multiple sources / otypes $object_type = $scoper->data_sources->get_from_db('type', $src_name, $object_id); } } $base_caps_only = $is_new_object; // Possible TODO: re-implement OP_ADMIN distinction with admin-specific capabilities //$admin_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_ADMIN_RS, $status_name, $base_caps_only); $admin_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_EDIT_RS, $status_name, $base_caps_only); $delete_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_DELETE_RS, $status_name, $base_caps_only); $reqd_caps = array_merge(array_keys($admin_caps), array_keys($delete_caps)); if (!$reqd_caps) { return true; } // apparantly this src/otype has no admin caps, so no restriction to apply // Note on 'require_full_object_role' argument: // Normally we want to disregard "others" cap requirements if a role is assigned directly for an object // This is an exception - we need to retain a "delete_others" cap requirement in case it is the // distinguishing cap of an object administrator $return = cr_user_can($reqd_caps, $object_id, 0, array('require_full_object_role' => true, 'skip_revision_allowance' => true)); if (!$return && !$object_id && $any_obj_role_check) { // No object ID was specified, and current user does not have the cap blog-wide. Credit user for capability on any individual object. // Possible TODO: re-implement OP_ADMIN distinction with admin-specific capabilities //$admin_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_ADMIN_RS, STATUS_ANY_RS); $admin_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_EDIT_RS, STATUS_ANY_RS); $delete_caps = $scoper->cap_defs->get_matching($src_name, $object_type, OP_DELETE_RS, STATUS_ANY_RS); if ($reqd_caps = array_merge(array_keys($admin_caps), array_keys($delete_caps))) { if (!defined('DISABLE_QUERYFILTERS_RS')) { global $cap_interceptor; if ($cap_interceptor->user_can_for_any_object($reqd_caps)) { $return = true; } } } } return $return; }
function flt_get_editable_authors($unfiltered_results) { global $wpdb, $scoper, $post; if (!($post_type = cr_find_post_type())) { return $unfiltered_results; } if (!($post_type_obj = get_post_type_object($post_type))) { return $unfiltered_results; } $have_cap = cr_user_can($post_type_obj->cap->edit_others_posts, $post->ID, 0, array('require_full_object_role' => true)); if ($have_cap) { return $scoper->users_who_can($post_type_obj->cap->edit_posts, COLS_ALL_RS); } else { if ($post->ID) { if ($current_author = $scoper->data_sources->get_from_db('owner', 'post', $post->ID)) { $force_user_id = $current_author; } } else { global $current_user; $force_user_id = $current_user->ID; } if ($force_user_id) { $display_name = $wpdb->get_var("SELECT display_name FROM {$wpdb->users} WHERE ID = '{$force_user_id}'"); $users = array((object) array('ID' => $force_user_id, 'display_name' => $display_name)); return $users; } } //log_mem_usage_rs( 'flt_get_editable_authors()' ); return $unfiltered_results; }
function flt_wp_dropdown_users($wp_output) { // just filter Post Author dropdown if (!strpos($wp_output, "name='post_author_override'")) { return $wp_output; } // this is meant to filter the post author selection if (!is_admin()) { return $wp_output; } // if (even after our blogcap tinkering) the author list is already locked due to insufficient blog-wide caps, don't mess if (!($pos = strpos($wp_output, '<option'))) { return $wp_output; } if (!strpos($wp_output, '<option', $pos + 1)) { return $wp_output; } global $wpdb, $scoper; $last_query = $wpdb->last_query; if (!($object_type = cr_find_post_type())) { return $wp_output; } if (!($post_type_obj = get_post_type_object($object_type))) { return $wp_output; } global $current_user; $is_ngg_edit = strpos($_SERVER['REQUEST_URI'], 'nggallery-manage-gallery'); if (!$is_ngg_edit) { $src_name = 'post'; $object_id = scoper_get_object_id('post', $object_type); // only modify the default authors list if current user has Editor role for the current post/page $have_cap = cr_user_can($post_type_obj->cap->edit_others_posts, $object_id, 0, array('require_full_object_role' => true)); } else { $src_name = 'ngg_gallery'; $object_id = $_REQUEST['gid']; $have_cap = !empty($current_user->allcaps[$post_type_obj->cap->edit_others_posts]); // $post_type_obj defaults to 'post' type on NGG Manage Gallery page } //if ( ! $have_cap ) // return $wp_output; $orderpos = strpos($last_query, 'ORDER BY'); $orderby = $orderpos ? substr($last_query, $orderpos) : ''; if (!strpos($orderby, 'display_name')) { // sanity check in case the last_query buffer gets messed up $orderby = ''; } $id_in = $id_not_in = $show_option_all = $show_option_none = ''; $pos = strpos($last_query, 'AND ID IN('); if ($pos) { $pos_close = strpos($last_query, ')', $pos); if ($pos_close) { $id_in = substr($last_query, $pos, $pos_close - $pos + 1); } } $pos = strpos($last_query, 'AND ID NOT IN('); if ($pos) { $pos_close = strpos($last_query, ')', $pos); if ($pos_close) { $id_not_in = substr($last_query, $pos, $pos_close - $pos + 1); } } $search = "<option value='0'>"; $pos = strpos($wp_output, $search . __awp('Any')); if ($pos) { $pos_close = strpos($wp_output, '</option>', $pos); if ($pos_close) { $show_option_all = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = "<option value='-1'>"; $pos = strpos($wp_output, $search . __awp('None')); if ($pos) { $pos_close = strpos($wp_output, '</option>', $pos); if ($pos_close) { $show_option_none = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = "<select name='"; $pos = strpos($wp_output, $search); if (false !== $pos) { $pos_close = strpos($wp_output, "'", $pos + strlen($search)); if ($pos_close) { $name = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = " id='"; $multi = !strpos($wp_output, $search); // beginning with WP 2.7, some users dropdowns lack id attribute $search = " class='"; $pos = strpos($wp_output, $search); if ($pos) { $pos_close = strpos($wp_output, "'", $pos + strlen($search)); if ($pos_close) { $class = substr($wp_output, $pos + strlen($search), $pos_close - $pos - strlen($search)); } } $search = " selected='selected'"; $pos = strpos($wp_output, $search); if ($pos) { $search = "<option value='"; $str_left = substr($wp_output, 0, $pos); $pos = strrpos($str_left, $search); //back up to previous option tag $pos_close = strpos($wp_output, "'", $pos + strlen($search)); if ($pos_close) { $selected = substr($wp_output, $pos + strlen($search), $pos_close - ($pos + strlen($search))); } } if (empty($selected)) { $selected = $current_user->ID; } // precaution prevents default-selection of non-current user // Role Scoper filter application $where = "{$id_in} {$id_not_in}"; $args = array(); $args['where'] = $where; $args['orderby'] = $orderby; if ($object_id > 0) { if ($current_author = $scoper->data_sources->get_from_db('owner', $src_name, $object_id)) { $force_user_id = $current_author; } } else { $force_user_id = $current_user->ID; } if ($have_cap) { if ($force_user_id) { $args['preserve_or_clause'] = " uro.user_id = '{$force_user_id}'"; } $users = $scoper->users_who_can($post_type_obj->cap->edit_posts, COLS_ID_DISPLAYNAME_RS, 'post', $object_id, $args); } else { $display_name = $wpdb->get_var("SELECT display_name FROM {$wpdb->users} WHERE ID = '{$force_user_id}'"); $users = array((object) array('ID' => $force_user_id, 'display_name' => $display_name)); } if (empty($users)) { // sanity check: users_who_can should always return Administrators if ($admin_roles = awp_administrator_roles()) { $users = scoper_get_results("SELECT DISTINCT ID, display_name FROM {$wpdb->users} INNER JOIN {$wpdb->user2role2object_rs} AS uro ON uro.user_id = {$wpdb->users}.ID AND uro.scope = 'blog' AND uro.role_type = 'wp' AND uro.role_name IN ('" . implode("','", $admin_roles) . "')"); } else { return $wp_output; } // the user data must be messed up } $show = 'display_name'; // no way to back this out // ----------- begin wp_dropdown_users code copy (from WP 2.7) ------------- $id = $multi ? "" : "id='{$name}'"; $output = "<select name='{$name}' {$id} class='{$class}'>\n"; if ($show_option_all) { $output .= "\t<option value='0'>{$show_option_all}</option>\n"; } if ($show_option_none) { $output .= "\t<option value='-1'>{$show_option_none}</option>\n"; } foreach ((array) $users as $user) { $user->ID = (int) $user->ID; $_selected = $user->ID == $selected ? " selected='selected'" : ''; $display = !empty($user->{$show}) ? $user->{$show} : '(' . $user->user_login . ')'; $output .= "\t<option value='{$user->ID}'{$_selected}>" . esc_html($display) . "</option>\n"; } $output .= "</select>"; // ----------- end wp_dropdown_users code copy (from WP 2.7) ------------- return $output; }
function awp_user_can($reqd_caps, $object_id = 0, $user_id = 0, $meta_flags = array()) { return cr_user_can($reqd_caps, $object_id, $user_id, $meta_flags); }
function act_check_ajax_referer($referer_name) { if ('add-tag' == $referer_name) { if ($tx_obj = get_taxonomy($_POST['taxonomy'])) { $cap_name = $tx_obj->cap->manage_terms; } if (empty($cap_name)) { $cap_name = 'manage_categories'; } // Concern here is for addition of top level terms. Subcat addition attempts will already be filtered by has_cap filter. if ((empty($_POST['parent']) || $_POST['parent'] < 0) && !cr_user_can($cap_name, BLOG_SCOPE_RS)) { die('-1'); } } elseif ('add-link-category' == $referer_name) { if (!cr_user_can('manage_categories', BLOG_SCOPE_RS)) { die('-1'); } } }
function filter_add_new_content_links() { global $scoper, $submenu; if (is_content_administrator_rs()) { return; } // But user might have a qualifying Default Post Role assigned //$_default_restricted_roles = $scoper->get_default_restrictions( 'object' ); //$default_restricted_roles = ( isset( $_default_restricted_roles['post'] ) ) ? $_default_restricted_roles['post'] : array(); // workaround for WP's universal inclusion of "Add New" $src = $this->scoper->data_sources->get('post'); foreach (array_keys($src->object_types) as $_post_type) { if ($wp_type = get_post_type_object($_post_type)) { $edit_key = 'post' == $_post_type ? 'edit.php' : "edit.php?post_type={$_post_type}"; $add_key = 'post' == $_post_type ? 'post-new.php' : "post-new.php?post_type={$_post_type}"; if (isset($submenu[$edit_key])) { foreach ($submenu[$edit_key] as $key => $arr) { if (isset($arr['2']) && $add_key == $arr['2']) { //$qualifying_roles = $scoper->role_defs->qualify_roles( $wp_type->cap->edit_posts ); if (!defined('SCOPER_LEGACY_MENU_FILTERING') && !cr_user_can($wp_type->cap->edit_posts, 0, 0, array('skip_id_generation' => true, 'skip_any_object_check' => true))) { unset($submenu[$edit_key][$key]); } } } } } } if (isset($submenu['link-manager.php'][10])) { $this->scoper->ignore_object_roles = true; if (!current_user_can('manage_links')) { unset($submenu['link-manager.php'][10]); } $this->scoper->ignore_object_roles = false; } }
function get_all_groups($filtering = UNFILTERED_RS, $cols = COLS_ALL_RS, $args = array()) { $defaults = array('include_norole_groups' => false, 'reqd_caps' => 'manage_groups', 'where' => ''); $args = array_merge($defaults, (array) $args); extract($args); if ($filtering && is_user_administrator_rs()) { $filtering = 0; } if ($filtering) { $cache_flag = 'usergroups'; global $current_rs_user; $cache = $current_rs_user->cache_get($cache_flag); } else { $cache_flag = 'all_usergroups'; $cache_id = 'all'; $cache = wpp_cache_get($cache_id, $cache_flag); } $ckey = md5($cols . $reqd_caps); if (!isset($cache[$ckey])) { global $wpdb; if ($filtering && !is_user_administrator_rs() && !cr_user_can($reqd_caps, 0, 0, array('skip_any_object_check' => true, 'skip_any_term_check' => true, 'skip_id_generation' => true))) { $duration_clause = scoper_get_duration_clause(); global $scoper; $role_handles = $scoper->role_defs->qualify_roles($reqd_caps); $role_names = array(); foreach (array_keys($role_handles) as $role_handle) { $role = scoper_explode_role_handle($role_handle); $role_names[] = $role->role_name; } $role_clause = "AND uro.role_name IN ('" . implode("','", $role_names) . "')"; $join = "INNER JOIN {$wpdb->user2role2object_rs} AS uro" . " ON uro.obj_or_term_id = {$wpdb->groups_rs}.{$wpdb->groups_id_col}" . " AND uro.src_or_tx_name = 'group' AND uro.scope = 'object' {$role_clause} {$duration_clause}"; $_where = "WHERE uro.user_id = {$current_rs_user->ID}"; } else { $join = ''; $_where = 'WHERE 1=1 '; } // append supplemental where clause, if any was passed in $_where .= $where; if (COL_ID_RS == $cols) { $query = "SELECT DISTINCT {$wpdb->groups_id_col} FROM {$wpdb->groups_rs} {$join} {$_where}"; } else { $query = "SELECT DISTINCT {$wpdb->groups_id_col} AS ID, {$wpdb->groups_name_col} AS display_name, {$wpdb->groups_descript_col} as descript, {$wpdb->groups_meta_id_col} as meta_id" . " FROM {$wpdb->groups_rs} {$join} {$_where} ORDER BY {$wpdb->groups_name_col}"; } if (COL_ID_RS == $cols) { $cache[$ckey] = scoper_get_col($query); } else { $cache[$ckey] = scoper_get_results($query); } } if ($filtering) { $current_rs_user->cache_set($cache, $cache_flag); } else { wpp_cache_set($cache_id, $cache, $cache_flag); } if (COLS_ALL_RS == $cols) { // strip out anon metagroup if we're not using it (have to do this after cache storage / retrieval) if (!defined('SCOPER_ANON_METAGROUP')) { foreach (array_keys($cache[$ckey]) as $key) { if ('wp_anon' == $cache[$ckey][$key]->meta_id) { unset($cache[$ckey][$key]); break; } } } // strip out groups that don't use roles, unless arg asked for them if (!$include_norole_groups) { foreach (array_keys($cache[$ckey]) as $key) { if (strpos($cache[$ckey][$key]->meta_id, '_nr_')) { unset($cache[$ckey][$key]); } } } } if (!$cache[$ckey]) { $cache[$ckey] = array(); } return $cache[$ckey]; }
function _user_can_read_file($file, &$return_attachment_id, &$matched_published_post, $uploads = '') { // don't filter the direct file URL request if filtering is disabled, or if the request is from wp-admin if (defined('DISABLE_QUERYFILTERS_RS') || is_content_administrator_rs() || !scoper_get_option('file_filtering') || !empty($_SERVER['HTTP_REFERER']) && false !== strpos($_SERVER['HTTP_REFERER'], '/wp-admin') && false !== strpos($_SERVER['HTTP_REFERER'], get_option('siteurl') . '/wp-admin')) { // note: image links from wp-admin should now never get here due to http_referer RewriteRule, but leave above check just in case - inexpensive since we're checking for wp-admin before calling get_option //rs_errlog("skipping filtering for $file"); return true; } if (!is_array($uploads) || empty($uploads['basedir'])) { require_once dirname(__FILE__) . '/uploads_rs.php'; $uploads = scoper_get_upload_info(); } //rs_errlog('_user_can_read_file'); $file_path = $uploads['basedir'] . "/{$file}"; //rs_errlog("$file_path exists."); global $wpdb, $wp_query; $file_url = $uploads['baseurl'] . "/{$file}"; // auto-resized copies have -NNNxNNN suffix, but the base filename is stored as attachment. Strip the suffix out for db query. $orig_file_url = preg_replace("/-[0-9]{2,4}x[0-9]{2,4}./", '.', $file_url); // manually resized copies have -?????????????? suffix, but the base filename is stored as attachment. Strip the suffix out for db query. $orig_file_url = preg_replace("/-[0-9,a-z]{14}./", '.', $orig_file_url); $qry = "SELECT * FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent > 0 AND guid = '{$orig_file_url}'"; $results = scoper_get_results($qry); $matched_published_post = array(); $return_attachment_id = 0; if (empty($results)) { $args = array('skip_any_object_check' => true, 'skip_any_term_check' => true); return cr_user_can('edit_others_posts', 0, 0, $args) || cr_user_can('edit_others_pages', 0, 0, $args); } else { // set global flag (checked by flt_user_has_cap, which filters current_user_Can) global $scoper_checking_attachment_access; $scoper_checking_attachment_access = true; foreach ($results as $attachment) { //rs_errlog( "found attachment: " . serialize($attachment) ); if (is_content_administrator_rs()) { $return_attachment_id = $attachment->ID; break; } if ($attachment->post_parent) { if ($parent_post = scoper_get_row("SELECT post_type, post_status FROM {$wpdb->posts} WHERE ID = '{$attachment->post_parent}' LIMIT 1")) { $object_type = $parent_post->post_type; $containing_post_status = $parent_post->post_status; // Only return content that is attached to published (potentially including private) posts/pages // If some other statuses for published posts are introduced in later WP versions, // the failure mode here will be to overly suppress attachments if ('publish' == $containing_post_status || 'private' == $containing_post_status) { if (current_user_can("read_{$object_type}", $attachment->post_parent)) { $return_attachment_id = $attachment->ID; break; } else { global $current_user; $matched_published_post[$object_type] = $attachment->post_name; } } } } } // clear global flag $scoper_checking_attachment_access = false; } if ($return_attachment_id) { return true; } }