summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Perry2016-08-16 22:11:47 (GMT)
committerJakob Perry2016-08-17 15:08:14 (GMT)
commit3c7f39f77984141fcef77221e88cbbf90bc287fe (patch)
tree1f3491ab7b88d77cb8edbb2e9b80dfa952ab637a
parentd2fc20baf79de8ffa44e707172e70ca3c55555b4 (diff)
Improve access checking in IPE
-rw-r--r--panels.module5
-rw-r--r--panels_ipe/panels_ipe.api.php31
-rw-r--r--panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php49
-rw-r--r--panels_node/panels_node.module13
4 files changed, 97 insertions, 1 deletions
diff --git a/panels.module b/panels.module
index 3f243eb..0193153 100644
--- a/panels.module
+++ b/panels.module
@@ -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(""),
diff --git a/panels_ipe/panels_ipe.api.php b/panels_ipe/panels_ipe.api.php
new file mode 100644
index 0000000..15a9904
--- /dev/null
+++ b/panels_ipe/panels_ipe.api.php
@@ -0,0 +1,31 @@
+<?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;
+}
diff --git a/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php b/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php
index 9a7a7de..abaf6da 100644
--- a/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php
+++ b/panels_ipe/plugins/display_renderers/panels_renderer_ipe.class.php
@@ -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]));
diff --git a/panels_node/panels_node.module b/panels_node/panels_node.module
index 0d01587..bcdb670 100644
--- a/panels_node/panels_node.module
+++ b/panels_node/panels_node.module
@@ -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.