I've been struggling with trying to manage proper access control for our Views with permissions and PHP in our blocks. I think what we really need is a Views access plugin. Basically, we need to sub-class views_plugin_access.

Comments

ergonlogic’s picture

I've implemented a Views access plugin for hosting_packages, and along the way, I've started moving all Views-related code into a views/ directory. I figure to do the same for the rest of our modules that expose anything to Views. I've also pushed some clean-up of Views exposed forms to Eldir, and removed the PHP we were injecting for block visibility in Hostmaster. This is all in 'dev/views-access' branches.

Currently the access plugin is about as basic as can be:

/**
 * Access plugin that provides access control for package views.
 */
class views_plugin_access_hosting_package extends views_plugin_access {

  function summary_title() {
    return t('Hosting package');
  }

  function get_access_callback() {
    return array('hosting_package_views_access', array($this->display->display_plugin));
  }

  function access($account) {
    return hosting_package_views_access($this->display->display_plugin, $account);
  }

}

We might want to add some options here, at some point, but for now, I've hard-coded the access rules in our callback:

/**
 * Views access callback.
 *
 * @param $type
 *   The display plugin.
 * @param $account
 *   The current user.
 */
function hosting_package_views_access($type, $account = NULL) {
  switch ($type) {
    case 'page':
      $path = explode('/', drupal_get_normal_path($_GET['q']));
      $nid = $path['1'];
      if (is_numeric($nid)) {
        $node = node_load($nid);
        if (!is_null($account)) {
          return user_access('view package', $account) && node_access('view', $node, $account);
        }
        return ($node->type == 'site' && $node->site_status != -2) || ($node->type == 'platform' && $node->platform_status != -2);
      }
      break;
    case 'block':
      if ($node = menu_get_object()) {
        return $node->type == 'package' && $node->package_type != 'profile';
      }
      break;
    default:
      return FALSE;
  }

  return FALSE;
}

I've update the default views that ship with hosting_package to use this access plugin. It appears to work, but could use more testing. Next is hosting_site.

ergonlogic’s picture

Status: Active » Needs review

hosting_site has had the same treatment. For some reason the 'access()' method never seems to be called for page displays, so I've stuck with permission-based access there.

While there's still the matter of moving the rest of our modules' views stuff into views/ directories, I don't think there's any need for more access plugins at this point.

ergonlogic’s picture

ergonlogic’s picture

ergonlogic’s picture

In removing the PHP we were injecting into our blocks, but since access control isn't enforced for UID1, you sometimes get views where they shouldn't be. I'll put it back, I guess. We can control this directly in Views-7.x-3.x.

anarcat’s picture

Status: Needs review » Needs work
      $path = explode('/', drupal_get_normal_path($_GET['q']));

can't we pass the node id down in the access callback instead of doing this hackish technique?

        return ($node->type == 'site' && $node->site_status != -2) || ($node->type == 'platform' && $node->platform_status != -2);

Do not use numeric identifiers but use constants instead.

I am kind of confused as to why this plugin is necessary - shouldn't views respect existing node_access rules? I understand if we needed to hack our way around platform's access control limitations (i.e. #725952: implement node-level access permissions for platforms) but for sites, shouldn't views just respect existing permissions?

ergonlogic’s picture

can't we pass the node id down in the access callback instead of doing this hackish technique?

No, we can't pass arguments to block Views in D6. We'll be able to clean this up in Aegir 3, so this deserves a @todo.

I am kind of confused as to why this plugin is necessary

This is to control access to the View at all, not individual results.

anarcat’s picture

Status: Needs work » Needs review

Oh I see, so I don't think I see any blockers here then.

ergonlogic’s picture

Status: Needs review » Fixed

Merged into 6.x-2.x on hosting, hostmaster and eldir.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.