使用map_meta_cap阻止访问某些帖子,页面,附件和类别术语

时间:2019-06-03 01:43:03

标签: php wordpress authorization

我试图阻止某些用户在管理界面(“后端”)和实际网站(“前端”)上访问某些帖子,页面,类别和附件。

我已经使用template_redirect动作解决了前端,检查是否允许wp_get_current_user()查看global $post,如果不是,则触发404。

我还使用pre_get_posts过滤器解决了大多数帖子列表。甚至管理员内部的列表(不幸的是,并非所有列表)。

但是,在管理员内部,用户仍然可以简单地通过输入诸如/wp-admin/post.php?post=SOME_ID&action=edit之类的正确URL来编辑他实际上不应该访问的任何帖子,附件,类别或页面。

我尝试使用map_meta_cap过滤器修复此问题,虽然它似乎适用于帖子和页面(查看正常的编辑屏幕时为附件),但我无法使其用于附件“弹出式窗口”(当您单击列表中的附件并获得带有此类URL的弹出式窗口:/wp-admin/upload.php?item=SOME_ID)或类别(/wp-admin/term.php?taxonomy=category&tag_ID=SOME_ID&post_type=post)。

首先,我什至不确定要为附件和类别过滤的功能,但是我一直在尝试使用upload_filesmanage_categories,但无法知道哪个帖子/术语正在编辑:

add_filter('map_meta_cap', function ($caps, $cap, $user_id, $args) {
    # NOTE: $args[0] contains the post->ID
    if (in_array($cap, ['edit_post', 'delete_post', 'edit_page', 'delete_page']) and !can_current_user_access_post($args[0])) {
        return ['do_not_allow'];
    }
    elseif (in_array($cap, ['upload_files'])) {
        # NOTE: $args is false, not sure how to check if user can access current attachment
    }
    elseif (in_array($cap, ['manage_categories'])) {
        # NOTE: $args is false, not sure how to check if user can access current term
    }

    return $caps;
}, 10, 4);

我也很好奇为什么不能简单地将read_postread_page添加到要检查的大写以防止读取访问? (这将允许我删除我的template_redirect代码)。

此外,如果我可以使此map_meta_cap代码在任何地方都可以正常工作(即使对于read也可以),则可以删除pre_get_posts过滤器,这会很好。

我以前从未使用过map_meta_cap,坦率地说,我对它的工作原理有些困惑。

编辑:我现在也使用edit_term功能解决了类别编辑屏幕。

1 个答案:

答案 0 :(得分:0)

好吧,事实证明read_postread_page实际上并没有阻止任何人阅读帖子或页面。不知道那到底在做什么。因此,仍然需要我的template_redirect来阻止前端访问。

第二,使用pre_get_posts过滤器隐藏附件实际上也可以解决附件弹出问题,因为如果附件列表中未打印附件,则弹出窗口不起作用(抛出JS错误)尝试访问弹出窗口时在控制台上)-我猜是因为弹出代码打印在同一列表中。

即使这可能是一个错误,并且可能并不完全安全,但它适用于我的用例。不过,对于附件弹出窗口,我也希望使用map_meta_cap解决方案。