Hi,

the access rules for Domain Access are not working in panels.

Szenario 1:
- Main Access restricted to certain domains.
- Result: Access denied on all domains.

Szenario 2:
- Main access open to all domains
- Panel 1 access restricted to a certain domain.
- Panel 2 access restricted to a different domain
- Panel 3 ....
- Result: Panel 1 visible on all domains

This behaviour can be reproduced on different new drupal installations.

Tested with:
- Panels 7.x-3.0-alpha3
- Domain Access 7.x-3.0-rc4
- Domain Ctools 7.x-1.2

AND

- Panels 7.x-3.0-alpha3
- Domain Access 7.x-3.0-rc2 (which was actual release while Domain Ctools 1.2 was released)
- Domain Ctools 7.x-1.2

Works as expected only with:
- Panels 7.x-3.0-alpha3
- Domain Access 7.x-2.15
- Domain CTools 1.1

Hope this helps.

Kind regards
Jan

Comments

jan.s’s picture

Title: Access Rules in Panels not working » Found the error

domain.inc line 102:

if ($key == $_domain['machine_name']) {

must be

if ($value == $_domain['machine_name']) {

Can anybody confirm please.

agentrickard’s picture

Title: Found the error » Access Rules in Panels not working
Status: Active » Needs review

Please keep a meaningful title.

agentrickard’s picture

Status: Needs review » Postponed (maintainer needs more info)

When did you configure this code? That is, is this an exported Panel rule set?

The error has to do with trying to use machine_name key settings (7.x.3) vs. numeric keys (7.x.2).

Can you please post the export of this access rule. (Or the entire panel.)

jan.s’s picture

I first postetd it has to be

if ($value == $_domain['machine_name']) {

but it must be:

if ($value === $_domain['machine_name']) {

(Don't know exactly why, but the first code gives me a (0 == "domain_1") is true. I'm confused, but with type checking (===) it works fine.)

I will write more in a few minutes.

jan.s’s picture

Thank you for your quick reply and changing the title back (thought it was the title for the comment).

Let me explain without the panels export (it is ok), that might be more helpful:

Look at function domain_ctools_domain_access_check($conf, $context, $plugin) in domain.inc.

function domain_ctools_domain_access_check($conf, $context, $plugin) {
  $_domain = domain_get_domain();
  if ($conf['domain_site']) {
    return TRUE;
  }
  // Check each domain, converting -1 to 0.
  foreach ($conf['domains'] as $key => $value) {
    $id = ($key == -1) ? 0 : $key;
    if (domain_ctools_api_version() < 3) {
      if (abs($value) > 0 && $id == $_domain['domain_id']) {
        return TRUE;
      }
    }
    // Normal 7.x.3 support.
    if ($key == $_domain['machine_name']) {
      return TRUE;
    }
    // Legacy 7.x.2 checking.
    if ($key == -1 || ($id > 0 && intval($key) == $key)) {
      if (abs($value) > 0 && $id == $_domain['domain_id']) {
        return TRUE;
      }
    }
  }
  return FALSE;
}

If you var_dump the $conf variable you get something like this, if the second domain is selected:

array(2) {
  ["domain_site"]=>
  int(0)
  ["domains"]=>
  array(3) {
    ["domain_1"]=>
    int(0)
    ["domain_2"]=>
    string(22) "domain_2"
    ["domain_3"]=>
    int(0)
  }
}

While looping through the conf['domains'] you get the $key and $values, but for 7.x.3 support you can see the code:

if ($key == $_domain['machine_name']) {
      return TRUE;
    }

Lets assume you load this page from "domain 1" but the first panel is configured to appear on "domain 2".
So this function is called for the first panel. Now the loop runs and will get a TRUE when the loop reaches the first domain, because the $key is definitly the domain machine name (see the array dump above). -> Panel 1 is displayed, but thats not correct.
You must check for the $value to be the domain machine name (and not 0). In this example "domain_1" is not existent in any $value, so the panel is not displayed.
If you load this page on "domain 2", the loop checks for the $value "domain_2" and it gets a true in the second loop. -> Panel will be displayed.

If you want to get my panel export anyway let me know.

agentrickard’s picture

Status: Postponed (maintainer needs more info) » Active

What I am saying is that with 7.x.3, I expect $key to be a string, not an integer. But the === is likely necessary.

jan.s’s picture

Yes, with 7.x.3 $key is a string.

Nevertheless in the 7.x.3 loop the $value must be compared to the domain machine name, not the $key. The problem itself is caused by that, not by the format of the $key index.

jan.s’s picture

Don't know the $conf array of 7.x.2, maybe it is neccessary to check still for $key to be string, so that the right code for 7.x.3 is used.

So I think it should be

// Normal 7.x.3 support.
    if ($key === $_domain['machine_name']) { // check for 7.x.3
        if ($value === $_domain['machine_name']) { // check for domain to be used
          return TRUE;
        }
        return false; // return false when 7.x.3 but not right domain, so that 7.x.2 code below ist not executed
    }
agentrickard’s picture

I think you are correct about the ===, I'm just looking for information so I can duplicate the problem. An export of the access rule would be very helpful in that regard.

jan.s’s picture

StatusFileSize
new5.61 KB

The panel export is attached, I renamed the domains to "domain1_de", "domain2_de" and "domain3_de".

Here an excerpt of the rule for the first panel (for domain1).

$handler->conf = array(
  'access' => array(
    'plugins' => array(
      0 => array(
        'name' => 'domain',
        'settings' => array(
          'domain_site' => 0,
          'domains' => array(
            'domain1_de' => 'domain1_de',
            'domain2_de' => 0,
            'domain3_de' => 0,
          ),
        ),
        'not' => FALSE,
      ),
    ),
    'logic' => 'and',
  ),
);
agentrickard’s picture

Thanks. I think your original patch is likely correct.

jan.s’s picture

I think #8 would be a better solution to respect Domain Access 7.x.2. But I didn't test it.

agentrickard’s picture

Status: Active » Needs review
StatusFileSize
new1.78 KB

I refactored the code to be a little more clear. array_filter() can rip out the 0 records, and we explicitly check the expected version of the key,

agentrickard’s picture

StatusFileSize
new1.92 KB

That last patch isn't quite right, because it doesn't account for cases where access rules were exported in 7.x.2 and applied in 7.x.3.

jan.s’s picture

Seems to work.

Testet with:

- Domain Ctools 7.x-1.2
- Domain Access 7.x-2.15

AND

- Domain Ctools 7.x-1.2
- Domain Access 7.x-3.0-rc4

agentrickard’s picture

StatusFileSize
new1.92 KB

Minor re-roll for better comments. Committed and new release rolled.

agentrickard’s picture

Status: Needs review » Fixed
jan.s’s picture

Status: Fixed » Closed (fixed)

New release tested. Seems to work.

Thank you!

jan.s’s picture

Issue summary: View changes

edit