I've probably neglected to enable a setting somewhere but I'm struggling to get Domain Access working with Organic Groups.

I'm running a new install of Drupal 5.7 with Domain Access 5.x-1.0, Organic Groups 5.x-5.4 and have applied the multiple_node_access.patch. I am looking to run multiple sites using Domain Access and provide a private area for certain groups via Organic Groups. Server is running PHP 5.2.5 and MySQL 5.0.45.

Using the default OR permission logic an anonymous user can access any group, private or not
Changing to the AND permission logic an anonymous user can no longer access any content on the site.

If I disable the Domain Access module the Organic Groups permissions work as expected.

Comments

agentrickard’s picture

Do you have Domain Strict turned on? If so, turn it off.

What domains are the groups themselves assigned to?

The first condition you describe sounds like the expected behavior. With -or- logic, if either OG or DA grants access, you get access. So if the group is visible on the current domain, DA will grant access -- that's what the patch is for, to add an extra layer of checking.

The second condition sounds like misuse of Domain Strict. Please see its README file.

agentrickard’s picture

Remember that -- by design -- Domain Access gives to same permissions to all users, anonymous or otherwise.

tober’s picture

Domain Strict and Domain User are both turned off.

To verify the behaviour I have just tried a new installation:

* created a blank database
* created a directory called 'beta'
* copied a fresh version of 5.7 into this directory
* ran the install to connect/set up the Drupal database
* created the first user, set the password and timezone
* set the file system settings path
* manually ran the chron job
* copied Domain Access 5.x-1.0 module to beta/sites/all/modules
* copied Views 5.x-1.6 module to beta/sites/all/modules
* copied OG 5.x-5.4 module to beta/sites/all/modules
* enabled Domain Access module (all other Domain Access modules off)
* configured Primary domain name and Site name in Domain Access
* enabled Views and Views RSS
* enabled Organic Groups
* created Content Type called 'Group' (not promoted, comments disabled)
* configured Organic Group Homepage to type 'Group'
* copied patched 'node.module' file to beta/modules/node
* enabled 'AND' logic in Domain Access
* created content of type 'Page' sent to 'All affiliates' (/node/1)
* tried to access /node/1 as anonymous user and get 'Access Denied'
* enabled access control in Organic Groups
* tried to access /node/1 as anonymous user and get 'Access Denied'

From what I can figure out if I create a group, assign content to the group and then mark the content as Public an anonymous user can see the content. This seems to be different from the expected behaviour stated in OG where 'Posts without any groups are always Public.' - unless I've totally misunderstood how DA and OG work together.

I think my workaround for the moment is to create a 'Public' group and assign all anonymous content to this group and explicitly mark it as Public...

agentrickard’s picture

Did you give anonymous users the standard 'access content' permission?

The easiest way to debug this -- and the only way to debug remotely -- is to download and install the Devel module. Turn on its query tracking and node_access reporting features. Then report the results.

I am assuming that you have not configured any additional domains, since you do not report any.

What does your {node_access} table look like right now?

tober’s picture

Anonymous had 'access content' permissions by default (ie it was already ticked in Administer->User Management->Access Control->node module->access content).

I'll download the Devel module and report back

No additional domains configured on the new installation

I've been playing around a little bit so node/6 is a Page sent to all affiliates, not a member of any group
node/7 is a test group sent to all affiliates
node/8 is a test Page assigned to the test group, not Public

For anonymous user I get access denied on node/6 and node/8. Can see the group (node/7) but not the private group post (node/8).

Here is the {node_access} table

nid gid realm grant_view grant_update grant_delete
6 0 domain_site 1 0 0
0 0 domain_all 1 0 0
7 0 domain_site 1 0 0
7 0 domain_id 1 0 0
7 7 og_subscriber 1 1 1
7 0 og_public 1 0 0
8 0 domain_site 1 0 0
8 0 domain_id 1 0 0
8 7 og_subscriber 1 1 1
6 0 domain_id 1 0 0

tober’s picture

Devel results:

node/6 (standard Page)

node_access entries for nodes shown on this page
node realm gid view update delete explained
0 domain_all 0 1 0 0
Home Page! domain_id 0 1 0 0
Home Page! domain_site 0 1 0 0

node/7 (Group)

node_access entries for nodes shown on this page
node realm gid view update delete explained
0 domain_all 0 1 0 0
testgroup domain_site 0 1 0 0
testgroup domain_id 0 1 0 0
testgroup og_subscriber 7 1 1 1 Subscribers of testgroup may view this node.
testgroup og_public 0 1 0 0 All users may view this node.
testpost domain_site 0 1 0 0
testpost domain_id 0 1 0 0
testpost og_subscriber 7 1 1 1 Subscribers of testgroup may view this node.

node/8 (Group Page, not Public)

node_access entries for nodes shown on this page
node realm gid view update delete explained
0 domain_all 0 1 0 0
testpost domain_site 0 1 0 0
testpost domain_id 0 1 0 0
testpost og_subscriber 7 1 1 1 Subscribers of testgroup may view this node.

Am I correct in thinking there should be an og_public permission either explicitly stated or implied on node/6? node/7 and node/8 are behaving how I would expect.

agentrickard’s picture

I think OG is still expecting the 'all' grant to be present, but it isn't, which would require the og_public grant to be there for all nodes.

What do the queries look like -- using the query tracker. Look for 'pager_query' entries, which should be similar to:

SELECT DISTINCT(n.nid), n.sticky, n.created FROM node n INNER JOIN node_access na ON na.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.realm = 'all' AND na.gid = 0) OR (na.realm = 'domain_site' AND na.gid = 0) OR (na.realm = 'domain_id' AND na.gid = 0)) ) AND ( n.promote = 1 AND n.status = 1 ) ORDER BY n.sticky DESC, n.created DESC LIMIT 0, 10

For individual node pages, look for node_access queries:

SELECT COUNT(*) FROM node_access WHERE (nid = 0 OR nid = 31) AND ((realm = 'all' AND gid = 0) OR (realm = 'domain_site' AND gid = 0) OR (realm = 'domain_id' AND gid = 3)) AND grant_view >= 1
tober’s picture

These are the queries I could find:

for node/6 (standard Page)
node_access

SELECT COUNT(*) FROM node_access WHERE (nid = 0 OR nid = 6) AND ((realm = 'all' AND gid = 0) OR (realm = 'og_public' AND gid = 0)) AND nid IN (SELECT nid FROM node_access WHERE ((realm = 'domain_site' AND gid = 0) OR (realm = 'domain_id' AND gid = 0))) AND grant_view >= 1

for node/7 (Group)
pager_query

SELECT count( DISTINCT(node.nid)) FROM node node LEFT JOIN og_ancestry og_ancestry ON node.nid = og_ancestry.nid INNER JOIN node_access na ON na.nid = node.nid WHERE (na.grant_view >= 1 AND ((na.realm = 'all' AND na.gid = 0) OR (na.realm = 'og_public' AND na.gid = 0)) AND na.nid IN (SELECT na.nid FROM node_access na WHERE ((na.realm = 'domain_site' AND na.gid = 0) OR (na.realm = 'domain_id' AND na.gid = 0))) ) AND ( (node.status = '1') AND (og_ancestry.group_nid = 7) ) 

pager_query

SELECT DISTINCT(node.nid), node.sticky AS node_sticky, node.created AS node_created_created FROM node node LEFT JOIN og_ancestry og_ancestry ON node.nid = og_ancestry.nid INNER JOIN node_access na ON na.nid = node.nid WHERE (na.grant_view >= 1 AND ((na.realm = 'all' AND na.gid = 0) OR (na.realm = 'og_public' AND na.gid = 0)) AND na.nid IN (SELECT na.nid FROM node_access na WHERE ((na.realm = 'domain_site' AND na.gid = 0) OR (na.realm = 'domain_id' AND na.gid = 0))) ) AND ( (node.status = '1') AND (og_ancestry.group_nid = 7) ) ORDER BY node_sticky DESC, node_created_created DESC LIMIT 0, 50

node/8 (Group Page, not Public)
node_access

SELECT COUNT(*) FROM node_access WHERE (nid = 0 OR nid = 8) AND ((realm = 'all' AND gid = 0) OR (realm = 'og_public' AND gid = 0)) AND nid IN (SELECT nid FROM node_access WHERE ((realm = 'domain_site' AND gid = 0) OR (realm = 'domain_id' AND gid = 0))) AND grant_view >= 1
agentrickard’s picture

OK, so your initial assessment is correct. Nodes not assigned to a group need to be marked as "Public."

With the AND logic active, the og_public grant must be true.

Isn't there a setting that controls that behavior for OG?

tober’s picture

I don't think there is such a setting (or at least not one that I have been able to find).

This is the 'Group' setting on each node page

 Audience:
testgroup
Show this post in this group.
Public
Show this post to everyone, or only to subscribers of the groups checked above. Posts without any groups are always Public.

The only way I've been able to get the og_public grant on the node is to assign the node to a group and then explicitly mark it as Public. The way I interpret the dialog is if I don't assign the node to a group it should be Public by default.

I've also just gone through and dumped the node_access at various stages

no DA or OG

nid 	gid 	realm 	grant_view 	grant_update 	grant_delete
0 	0 	all 	1 	0 	0

OG with Access Control

nid 	gid 	realm 	grant_view 	grant_update 	grant_delete
6 	0 	all 	1 	0 	0
7 	7 	og_subscriber 	1 	1 	1
7 	0 	og_public 	1 	0 	0
8 	7 	og_subscriber 	1 	1 	1

OG with Access Control & DA

nid 	gid 	realm 	grant_view 	grant_update 	grant_delete
6 	0 	domain_site 	1 	0 	0
6 	0 	domain_id 	1 	0 	0
7 	0 	domain_site 	1 	0 	0
7 	0 	domain_id 	1 	0 	0
7 	7 	og_subscriber 	1 	1 	1
7 	0 	og_public 	1 	0 	0
8 	0 	domain_site 	1 	0 	0
8 	0 	domain_id 	1 	0 	0
8 	7 	og_subscriber 	1 	1 	1
0 	0 	domain_all 	1 	0 	0
agentrickard’s picture

StatusFileSize
new38.96 KB

Right -- I see the conflict. This notes are based on looking at the code, not user-testing.

Without a defined node access record element, Drupal writes the 'all' row for nid 6. The 'og_public' record should be passed here but is not.

With a node access record given by DA, the 'all' grant is never written, and og_public must be explictly stated.

The reason for this behavior is in how the records get saved by Drupal core.

There should be a "public" checkbox on all node posts -- as there is on g.d.o. in the screenshot -- and it is checked by default.

There is a 'Visibility of posts' setting on the og admin pages that affect the behavior of this checkbox, AFAIK.

agentrickard’s picture

StatusFileSize
new23.5 KB

The key is in the Visibility settings of OG. With OG access control enabled, the following settings have the following effects:

[] Visible only within the targeted groups
og_public is never written for posts.

[] Visible within the targeted groups and on other pages
og_public is always written for posts.

[] Visibility chosen by author/editor using a checkbox on the posting form. Checkbox defaults to Public.
og_public defaults to on, but can be disabled.  * Applies only if posting to a group, otherwise, defaults to off.

[] Visibility chosen by author/editor using a checkbox on the posting form. Checkbox defaults to Private.
og_public defaults to off, but can be enabled. * Applies only if posting to a group, otherwise, defaults to off.

This is a core feature of OG.

There is also an "omitted content types" option which removes og access control rules from certain node types. If this is disabled for a specific node type, the og_public grant will not be written.

The end result is, OG/DA integration is more complicated than I feared. For nodes that do not belong to groups, the AND grant setting will only work in cases where OG settings are applied to all node types, and where 'og_public' is always written.

tober’s picture

My testing with the Visibility settings in OG when combined with DA AND logic seems to show that the following permissions are written (for resaved and new content) regardless of the setting - ie the og_public grant never gets written for a node

nid 	gid 	realm 	grant_view 	grant_update 	grant_delete
6 	0 	domain_site 	1 	0 	0
6 	0 	domain_id 	1 	0 	0

For 'Visible only within the targeted groups' the 'Public' checkbox is greyed out and defaults to unchecked
For 'Visible within the targeted groups and on other pages' the 'Public' checkbox is greyed out and defaults to checked
For 'Visibility chosen by author/editor using a checkbox on the posting form. Checkbox defaults to Public.' the 'Public' checkbox is greyed out and defaults to checked
For 'Visibility chosen by author/editor using a checkbox on the posting form. Checkbox defaults to Private.' the 'Public' checkbox is greyed out and defaults to unchecked

Once you select a group the 'Public' checkbox ungreys itself

If you explicitly select a group the og_subscriber grant gets written for the node
If you then select the 'Public' checkbox the og_public grant gets written (this is the only case I can find where the og_public grant gets written)

I can also confirm that if you put a node type in the omitted content type the og_public grant does not get written (and the anonymous user gets denied access to the node)

agentrickard’s picture

Right. This is the designed behavior of OG, and there isn't much to be done.

However, using hook_domainrecords(), you could write a small function that would force this to be saved in any/all cases.

agentrickard’s picture

Status: Active » Closed (works as designed)
gcassie’s picture

I'm having this same issue. I added this function to my site's custom code module and it seems to be working to allow anonymous users view rights like you'd expect. I don't have a heap of content or users yet, so it may fall apart in the long run, but perhaps it is a start. Hope it helps.

function mycustomcodemodule_node_access_records($node) {
  // we need to explicitly label public nodes it seems. OG doesn't label nodes 
  // of types it doesn't apply to, or the "implicitly public" nodes created by
  // leaving all the audience checkboxes blank.

  if (og_is_omitted_type($node->type) || (is_array($node->og_groups) && count($node->og_groups) === 0)) {
    $grants[] = array (
      'realm' => 'og_public',
      'gid' => 0,
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0 );
    return $grants;
  }
  else {
    return;
  }
}
agentrickard’s picture

Yes, this solution seems to be necessary if you use the patch and set DA behavior to AND.

Nice fix.

gcassie’s picture

My little bit of code seems to be ignored when permissions are rebuilt from admin/content/node-settings . I tried changing the module weight so it runs after og, but that didn't help. Is there something else I need to hook into so it gets called during this process? I didn't notice other hooks for node access.

agentrickard’s picture

I am not sure. See http://api.drupal.org/api/function/node_access_rebuild/5

Also check to see if OG sets a 'priority' flag on its grants.

gcassie’s picture

No luck so far. I'm thinking about creating a cron hook that looks for entries that need an explicit OG public entry and inserts them. Not the best solution...

somebodysysop’s picture

Through sheer dumb luck, I think I may have found the solution:

    if (og_is_omitted_type($node->type) || (is_array($node->og_groups) && count($node->og_groups) === 0) || (!is_array($node->og_groups) && !og_is_group_type($node->type))) {
      $grants[] = array (
        'realm' => 'og_public',
        'gid' => 0,
        'grant_view' => 1,
        'grant_update' => 0,
        'grant_delete' => 0 );
      return $grants;
    } else {
      return;
    }

When you rebuild permissions, the non-group nodes no longer have the $node->og_groups variable, so you need to look for nodes that do NOT have that array AND which aren't groups themselves.

Now, when I run "rebuild permissions", my additional og_public grants persist. Try it and see if it works for you.

And, thanks for the original code! I've been trying to get TAC and OG to coexist peacefully for over a year, and it looks like this might be the last piece of the puzzle!

agentrickard’s picture

Version: 5.x-1.0 » 5.x-1.2
Category: support » feature
Status: Closed (works as designed) » Needs review

Upgrading. I think we need to release this code.

gcassie’s picture

Yes, that works, it even adds anon permissions to nodes which previously had them destroyed by updating post settings before this change!

solutiondrop’s picture

I can also confirm that this works when permissions are rebuilt. Thanks SomebodySysop.

amccune’s picture

Category: feature » support

I have been having the same drupal access problem when domain access and organic groups are used together.

Can anyone advise me where and how to call this code. ie what steps need to be taken? if I need to rebuild node access permissions afterwardshow do I do this?

I am fairly new to Drupal

Many thanks

Adam

somebodysysop’s picture

This code goes into the hook_node_access_records() function of a custom module:

    if (og_is_omitted_type($node->type) || (is_array($node->og_groups) && count($node->og_groups) === 0) || (!is_array($node->og_groups) && !og_is_group_type($node->type))) {
      $grants[] = array (
        'realm' => 'og_public',
        'gid' => 0,
        'grant_view' => 1,
        'grant_update' => 0,
        'grant_delete' => 0 );
      return $grants;
    } else {
      return;
    }

That is, you have to create a module and put this code in it and enable the module on your site. Or, you can use an existing module that contains this code. The OG User Roles module creates this code when TAC/OG Integration is turned on, but that is probably a lot more configuration hassle than you want or need. It also uses a version of the DA multinode_access patch.

You should ask who else created modules using this code, and perhaps you can use one of those.

somebodysysop’s picture

As a logical exercise, I decided to try and figure out, and document, how to integrate OG and DA using the Multinode Access UI I've created in OG User Roles, effectively integrating OG, DA and OGR.

So, for the brave amongst you, the steps you'd have to take to make this work using OGR:

  • Install OG, DA, OGR and Taxonomy Access Control.
  • Do NOT install the multinode_access patch which comes with DA.
  • DO install the Multinode Access Logic patch: node.module.multinode.patch, which comes with the OGR distribution. This was developed here: http://drupal.org/node/196922.
  • In OGR, you'd have to turn on the "TAC/OG Integration". I understand you're not using TAC, but it's required for this setting in OGR.
  • Configure DA/OG Integration using the Multinode Access UI. Currently, I don't have any instructions for configuring DA/OG access. However, instructions for configuring TAC/OG integration are here: http://groups.drupal.org/node/4026. Instructions for configuring TAC/OG/ACL/CA/OGR are here: http://groups.drupal.org/node/5392. You should read these to familiarize yourself with using the Multinode Access UI.

Now, here's the tricky part. I actually don't know how you need to configure DA/OG integration using the Multinode Access UI. I haven't tested any configuration with DA. However, I do have an idea as to, logically, what should be done.

According to: http://drupal.org/node/191375#comment-627326, it appears that the DA module creates the following two grants: domain_site and domain_id.

So, the node_access logic we'd be looking for is:

IF (all OR og) AND (domain_site OR domain_id)

Looking at my instructions for TAC/OG Integration http://groups.drupal.org/node/4026 we don't need to integrate TAC. You need to go to the Multinode Access UI. Once you've applied the OGR node.module.multinode.patch, you get to the Multinode Access UI by either:

Admin->Content Management->Multinode user interface
or
Admin->Organic groups->Organic groups user roles->Configure multinode UI

Using this interface, you should configure the node access as follows:

   domain_site
   =========
   Place check in checkbox next to "domain_site" Realm name.
   Enter "das" in Group column.
   Select "AND" as Logic.
   Select "0" as Weight.
   Select "0" for Check.

   domain_id
   ========
   Place check in checkbox next to "domain_id" Realm name.
   Enter "dai" in Group column.
   Select "OR" as Logic.
   Select "1" as Weight.
   Select "0" for Check.

   ogr_access
   ==========
   Place check in checkbox next to "ogr_access" Realm name.
   Enter "ogr" in Group column.
   Select "OR" as Logic.
   Select "2" as Weight.
   Select "0" for Check.

Don't forget to click on the "Save changes" button.

Again, I can't say for sure if this is correct. You'll have to try it and see. I you try it and it works/doesn't work, please let me know.

Thanks!

gcassie’s picture

I think there may be a problem using this with private groups. Right now admins/members can't reliably see their own subscribed private groups. I've printed out some of the SQL that gets run in the patched node_access, and it looks like they only include one of the subscribed groups?

Here are the rules that are in node_access_grants_sql:

Array(
    [all] => Array
        (
            [0] => 0
        )

    [domain_site] => Array
        (
            [0] => 0
            [group] => domain
        )

    [domain_id] => Array
        (
            [0] => 2
            [group] => domain
        )

    [og_public] => Array
        (
            [0] => 0
        )

    [og_subscriber] => Array
        (
            [0] => 1111
            [1] => 829
            [2] => 1
            [3] => 1068
            [4] => 890
            [5] => 1112
        )
)

You can see there are multiple subscriptions for this user.

Here is the SQL that is being run:

SELECT COUNT(*) FROM {node_access} WHERE (nid = 0 OR nid = %d) AND ((realm = 'all' AND gid = 0) OR (realm = 'og_public' AND gid = 0) OR (realm = 'og_subscriber' AND gid = 1112)) AND nid IN (SELECT nid FROM {node_access} WHERE ((realm = 'domain_site' AND gid = 0) OR (realm = 'domain_id' AND gid = 2))) AND grant_view >= 1

It comes out with only that one subscription record no matter which node I run node_access against.

Any thoughts? Is there a patch I need to add to og to get a [group] entry into its rules that I missed somewhere along the line? Anyone else notice this problem?

somebodysysop’s picture

This sounds suspicously like the issue we ran into here: http://drupal.org/node/243731#comment-810317

Only the last grant (what I referred to as "roleID") was being returned from the "term_access" realm.

If this is the same problem:

Fixed that here: http://drupal.org/node/243731#comment-810521

Updated patch submitted here: http://drupal.org/node/243731#comment-810681

gcassie’s picture

I've applied the updated patch and it seems to be working. I will test some more over the weekend. Thanks very much for pointing that out to me.

agentrickard’s picture

Version: 5.x-1.2 » 5.x-1.4

The version of the patch in 5.x.1.4 and 6.x should be up-to-date.

The code from #26 still needs to be implemented on a per-site basis.

agentrickard’s picture

Category: support » feature
StatusFileSize
new737 bytes

Attached is a Domain OG module which should solve this issue. Needs testers.

tober’s picture

I've just implemented the patch from post #32 and it seems to be working - thanks everyone!

A few notes:

Line 19 of domain_og.module needs to be changed from
if (module_exists('og') {
to
if (module_exists('og')) {

note the missing closing bracket

You might also need to rebuild the node permissions to get everything set correctly:

Administer->Post settings->Rebuild permissions

I'll be sure to report back if I find anything unexpected.

agentrickard’s picture

StatusFileSize
new2.05 KB

Fixed, per above.

agentrickard’s picture

Also investigate: function og_form_add_og_audience(&$form, &$form_state)

gcassie’s picture

I've been running OG 5.x-5.4, and would like to upgrade to 5.x-7.3 for several reasons. I know that OG's node_access rules have been broken out into a distinct module since 5.4. Is anyone using the patches discussed in this thread with OG 5.x-7.3 with success? Do they need any modifications? Thanks much for your advice.

agentrickard’s picture

I have not, but the system OG uses should be the same. Splitting og_access into a separate module was a Good Thing (tm).

gcassie’s picture

Yes, I agree. I will try it soon and post back here with the results, for good or ill.

totocol’s picture

Can I use the fix on #34 on D6?. Or does the latest version (6.x-1.2) already fixes this?

Thanks a lot

agentrickard’s picture

No. The fix in #34 may need some modification to run on D6.

bribiz’s picture

Do you remember what in the fix on #34 needed to be modified? I modified the .info file so it would install on D6. Seems to have worked at least initially. Did node access change under D6 and your initial assessment is that the fix in #34 may require significant changes beyond the .info file?

agentrickard’s picture

Aside from needing a .info file, it should work fine in D6, I just haven't tested it.

inforeto’s picture

I installed and tested domain_og.module on drupal 5.14 and worked fine except for one problem.
The site has two domains, adding and editing nodes on the primary domain work as expected and thus the database entry for realm og_public gets added.
However, adding and editing nodes trough the secondary domain does not add the entry and removes the entry on existing nodes.
This is for nodes assigned to either domain and users assigned to edit either domain or both.
Perhaps i am missing some permission for users but that's the current results.
Have anyone know what could be wrong or missing?

agentrickard’s picture

Anyone care to take over this module and release it?

scedwar’s picture

subscribe

agentrickard’s picture

Status: Needs review » Postponed
agentrickard’s picture

Status: Postponed » Closed (works as designed)
HJulien’s picture

I'm not clear if the Domain OG module was created as the result of this thread. Is the Domain OG module required to use Domain Access and OG together?

I want to allow one group type on my main site to have subdomains with ubercart stores, I'm not sure what modules (Domain Access and Domain OG) I need to build this functionality. Or maybe I just need the patch mentioned in the README file? I am using Drupal 6.

colorado’s picture

I had to change the .info file in #34 to this in order to prevent the error message (in admin/build/modules) saying "This version is incompatible with the 6.26 version of Drupal core."

; $Id:$
name = "Domain OG"
description = "Organic Groups integration helper module"
version = "6.x-1.0"
core = "6.x"
package = "Domain Access"
project = "domain_og"
dependencies[] = domain