Commit 3c7f39f7 authored by japerry's avatar japerry

Improve access checking in IPE

parent d2fc20ba
......@@ -302,6 +302,11 @@ function panels_permission() {
'title' => t("Change layouts with the Panels In-Place Editor"),
'description' => t("Allows a user to change layouts with the IPE."),
),
'bypass access in place editing' => array(
'title' => t("Bypass access checks when using Panels In-Place Editor"),
'description' => t("Allows using IPE even if user does not have additional permissions granted by other modules."),
'restrict access' => TRUE,
),
'administer advanced pane settings' => array(
'title' => t("Configure advanced settings on Panel panes"),
'description' => t(""),
......
<?php
/**
* @file
* Hooks provided by Panels In-Place Editor.
*/
/**
* Allow modules to control access to the Panels IPE.
*
* @param panels_display $display
* The panels display about to be rendered.
*
* @return TRUE|FALSE|NULL
* Returns TRUE to allow access, FALSE to deny, or NULL if the module
* implementing this hook doesn't care about access for the given display.
*/
function hook_panels_ipe_access($panels_display) {
// We only care about displays with the 'panelizer' context.
if (!isset($display->context['panelizer'])) {
return NULL;
}
if ($display->context['panelizer']->type[0] == 'entity:node') {
// Allow or deny IPE access based on node type.
return $display->context['panelizer']->data->type == 'awesome_page';
}
// Otherwise, deny access to everything!
return FALSE;
}
......@@ -7,12 +7,44 @@ class panels_renderer_ipe extends panels_renderer_editor {
// The IPE operates in normal render mode, not admin mode.
var $admin = FALSE;
// Whether or not the user has access.
var $access = NULL;
function invoke_panels_ipe_access() {
if (user_access('bypass access in place editing')) {
return TRUE;
}
// Modules can return TRUE, FALSE or NULL, for allowed, disallowed,
// or don't care - respectively. On the first FALSE, we deny access,
// otherwise allow.
foreach (module_invoke_all('panels_ipe_access', $this->display) as $result) {
if ($result === FALSE) {
return FALSE;
}
}
return TRUE;
}
function access() {
if (is_null($this->access)) {
$this->access = $this->invoke_panels_ipe_access();
}
return $this->access;
}
function render() {
$output = parent::render();
return "<div id='panels-ipe-display-{$this->clean_key}' class='panels-ipe-display-container'>$output</div>";
if ($this->access()) {
return "<div id='panels-ipe-display-{$this->clean_key}' class='panels-ipe-display-container'>$output</div>";
}
return $output;
}
function add_meta() {
if (!$this->access()) {
return parent::add_meta();
}
ctools_include('display-edit', 'panels');
ctools_include('content');
......@@ -96,6 +128,9 @@ class panels_renderer_ipe extends panels_renderer_editor {
if (empty($output)) {
return;
}
if (!$this->access()) {
return $output;
}
// If there are region locks, add them.
if (!empty($pane->locks['type']) && $pane->locks['type'] == 'regions') {
......@@ -138,6 +173,10 @@ class panels_renderer_ipe extends panels_renderer_editor {
}
function prepare_panes($panes) {
if (!$this->access()) {
return parent::prepare_panes($panes);
}
// Set to admin mode just for this to ensure all panes are represented.
$this->admin = TRUE;
$panes = parent::prepare_panes($panes);
......@@ -145,6 +184,10 @@ class panels_renderer_ipe extends panels_renderer_editor {
}
function render_pane_content(&$pane) {
if (!$this->access()) {
return parent::render_pane_content($pane);
}
if (!empty($pane->shown) && panels_pane_access($pane, $this->display)) {
$content = parent::render_pane_content($pane);
}
......@@ -175,6 +218,10 @@ class panels_renderer_ipe extends panels_renderer_editor {
* @param $panes
*/
function render_region($region_id, $panes) {
if (!$this->access()) {
return parent::render_region($region_id, $panes);
}
// Generate this region's 'empty' placeholder pane from the IPE plugin.
$empty_ph = theme('panels_ipe_placeholder_pane', array('region_id' => $region_id, 'region_title' => $this->plugins['layout']['regions'][$region_id]));
......
......@@ -396,6 +396,19 @@ function panels_node_panels_dashboard_blocks(&$vars) {
);
}
/**
* Implements hook_panels_ipe_access().
*/
function panels_node_panels_ipe_access($display) {
// We only care about Panels displays from panels_node.
if (isset($display->context['panel-node'])) {
// Only allow access to use the IPE if the user has 'update' access to
// the underlying node.
$node = $display->context['panel-node']->data;
return node_access('update', $node);
}
}
// ---------------------------------------------------------------------------
// Callbacks for panel caching.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment