Can you please tell me if Organic Groups and Domain Access play nicely together? Will one or other the other step on each others toes?

I just need some clarification with D6 vs D7 modules. I'm mainly interested in the D7 versions.

-Thank you for your time

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

agentrickard’s picture

I don't know. They might, but that can be mitigated by writing a bridge module that integrates the two properly.

gmclelland’s picture

Thank you for your response.

BrightBold’s picture

@gmclelland -
I tested them both together on a D7 site earlier this fall, and they did not seem to play nicely; it appeared that the grants were ORing so that DA was effectively winning out over OG and everyone could access all the nodes regardless of OG permissions. I thought D7 was supposed to have some improvements that made multiple node access modules work together better but it was not working in my case.

If you have a different experience or discover potential solutions will you post those here and I will do the same? From my research, it sounds like this won't be possible until someone writes a helper module using hook_node_access_records_alter() or hook_node_grants_alter(), but on the other hand I seem to be finding references to people using both modules together (although without any details). So I may give it another shot since both OG and my knowledge of it have matured since my previous test, but my guess is we have to wait on the bridge module, which is beyond my skills.

BrightBold’s picture

Have you tried Domain Access Advanced? This purportedly changes the way DA node access is implemented so you can use it with another node access module. However, based on the issue queue it doesn't appear to work flawlessly, and the D7 version is still only an attachment in an issue (http://drupal.org/node/1117262#comment-4692228) — although one person seems to be using it successfully. I may try the D7 version and see how that works.

gmclelland’s picture

@BrightBold - Thank you for your comments.

I was originally wanting to use DA to manage creating domains and then using OG for creating self-managing(organizing) sections within those domains.

From my research, it sounds like this won't be possible until someone writes a helper module

-I'm thinking the same. Maybe http://drupal.org/project/domain_adv is the answer? Haven't tried, but I did see the D7 issue you were talking about.

Post back if you find out anything else.

agentrickard’s picture

There is better support here, but no OR magic.

You can now use hook_node_access_records_alter() to negotiate between the two modules and discard the set of rules that don't fit -- or merge them into a new realm entirely.

I would expect someone to write a generic solution for this integration.

See http://api.drupal.org/api/drupal/modules--node--node.module/group/node_a... and especially

* http://api.drupal.org/api/drupal/modules--node--node.api.php/function/ho...
* http://api.drupal.org/api/drupal/modules--node--node.api.php/function/ho...

You may be able to write a small module that alters the user's OG grants based on the domain of the current OG context. That is probably the easiest solution.

Let me know if you have any code to review.

BrightBold’s picture

@agentrickard — the support here is indeed always fabulous! Greatly appreciated.

agentrickard’s picture

I've been anticipating this one for a while. The first step is to map the rules you want to enforce. From there, the code should be easy.

I think hook_node_grants_alter() should do what you want. Just remove the grant(s) that should be subordinate to the current contextual rule.

BrightBold’s picture

@gmclelland - Is taking a stab at this within your abilities? I'm not much of a module developer — I've been trying to learn more in that area, but mostly around theme-related stuff; dealing with node access feels like a real stretch for me. So I'm probably not the right person to try this, although if I end up with some free time in January and haven't found a solution, I might be game for taking on something this far outside my comfort zone!

gmclelland’s picture

@BrightBold - sorry I'm not familiar enough with Node Access or OG. Another thing to keep in mind is that OG for D7 provides a field level access control module as well.

BrightBold’s picture

@gmclelland - Ooh I hadn't thought about that. Do you think that would act as yet a third access control module, or would it behave as a subset of the OG grants? (I'm wondering if you think this will make the bridge harder to develop.) I don't have that sub-module turned on right now on the site where I want OG and DA to be friends, but I might need it in the future. I'm guessing I can live without it, though, especially if it makes it less likely I can use DA.

BrightBold’s picture

Wouldn't Module Grants be the right place for this bridge functionality? It allows multiple node access modules to work together in D6, so it seems like the right contrib space for this functionality in D7. Unfortunately there hasn't been any movement towards a D7 port.

I did take a look at the links you posted and if anyone else is looking at trying to code this they should also see http://api.drupal.org/api/examples/node_access_example--node_access_exam....

agentrickard’s picture

In D7, we have core hooks that make Module Grants unnecessary (or much simpler). I would think a specific bridge would be better.

joakim.dahlberg’s picture

I had the same problem, and really wanted to be able to use DA and OG simultaneously. Using Drupal 7.7, OG 7.x-1.3, DA 7.x-2.16. After tons of googling, I finally found and tried out the patch suggested here: http://drupal.org/node/1149582. Used the fix to prioritize OG above DA and what do you know - it worked!

So, short story: Worked for me. OG private content is now private, DA still works. However, being an experienced php programmer but also a newbie at coding Drupal, I really can't tell how reliable this is... Though the discussion in previous comments did let me believe this module priority thing is really the D7 magic people have been asking for. Is it? It seems so simple!

Could anyone with Drupal coding experience fill me in on this, is the priority fix the holy grail for making DA play nicely with the other kids in the access playground or not?

agentrickard’s picture

Using "priority" is a hack from the bad old days (Drupal < 5) and should not be used, IMO. Use hook_node_access_records_alter() instead.

AFAIK, setting priority > 0 means that all other grants are not saved. So I don't know what "DA still works" would mean in this context. Are you still getting domain records stored in {node_access}?

See http://api.drupal.org/api/drupal/modules--node--node.module/function/nod...

See also #686858: Document the correct replacement for 'priority' from hook_node_access_records()

joakim.dahlberg’s picture

Ok, I didn't know that it was considered bad practice to use that - it did seem like a swift way to get expected behavior... Maybe I shouldn't be surprised that an easy fix turns out to be an ugly hack.

With "DA still works" I meant that prioritizing OG ahead of DA didn't break any of the domain-specific functionality, while it did fix my problems with private groups not being restricted when they should be. I'll check if the domain records are stored when I get back to my test server and try to report back.

kugta’s picture

I solved the problem like this:

function MY_MODULE_node_access($node, $op, $account) {
  $is_private = (isset($node->group_content_access[LANGUAGE_NONE][0]['value']) && $node->group_content_access[LANGUAGE_NONE][0]['value'] == 2);
  if(isset($node->group_audience) && $is_private) {
    $group_access = FALSE;
    $user_groups  = og_get_entity_groups('user', $account);

    foreach($node->group_audience[LANGUAGE_NONE] as $node_group) {
      if(in_array($node_group['gid'], $user_groups)) {
        $group_access = TRUE;
        continue;
      }
    }

    if(!$group_access) {
      return NODE_ACCESS_DENY;
    }
  } else {
    return NODE_ACCESS_IGNORE;
  }
}

I think this is not the best solution, but it seems to work for me now. I couldn't figure out how I should implement this using hook_node_access_records_alter() and hook_node_access_grants_alter(). Any suggestions are welcome because this solution unfortunately doesn't affect node listings out of the box, see:
http://api.drupal.org/api/drupal/modules--node--node.module/group/node_access/7 and
http://api.drupal.org/api/drupal/modules--node--node.api.php/function/hook_node_access/7

agentrickard’s picture

Right hook_node_access() only affects single node View / Edit / Delete. The node access table handles lists.

Ideally, I think, the two modules would merge to create a different access "realm" that merged the rules of both modules.

e.g.

* Node is assigned to domain 1 and Group 5.
* Don't store domain_id = 1 and og = 5 as access rules.
* Store domain_og = 51 (or some similar)
* For node grants, calculate the user's rights in the same way.

This is what the alter hooks are for. The problem is that the logic for generating the new realm id is tricky, and the pseudo-code above isn't correct.

Another possible way around this is to store all the records normally and use hook_node_grants_alter() to match the context of the request to the proper realms.

kugta’s picture

@agentrickard Thank you for your help.
I think I could solve it the proper way this time. Indeed the tricky thing is to define a pattern for the realm id. There is probably no 100% bullet-proof solution, but I think mine will fit 99,99% of the cases. I use '0990' to separate the domain id from the group id, so it is safe enough to use with 10989 domains. Here is my code:

define('DOMAIN_OG_SEPARATOR', '0990');

function MY_MODULE_node_access_records_alter(&$grants, $node) {
     
    $domain_set = FALSE;
    $og_set     = FALSE;
    $domain_ids = array();
    $og_grants  = array();
    
    foreach ($grants as $grant) {
        if($grant['realm'] == 'domain_id') {
            $domain_set   = TRUE;
            $domain_ids[] = $grant['gid'];
        } else if($grant['realm'] == 'group_access_authenticated') {
            $og_set      = TRUE;
            $og_grants[] = $grant;
        }
    }
    
    if($domain_set && $og_set) {
        foreach($og_grants as $og_grant) {
            foreach($domain_ids as $domain_id) {
                $domain_og_grant = array(
                    'realm'        => 'domain_og',
                    'gid'          => $domain_id . DOMAIN_OG_SEPARATOR . $og_grant['gid'],
                    'grant_view'   => $og_grant['grant_view'],
                    'grant_update' => $og_grant['grant_update'],
                    'grant_delete' => $og_grant['grant_delete'],
                    'priority'     => 0,
                    '#module'      => 'MY_MODULE',
                );
                $grants[] = $domain_og_grant;
            }
        }
    }
}

function MY_MODULE_node_grants_alter(&$grants, $account, $op) {
    
    if(isset($grants['domain_id']) && isset($grants['group_access_authenticated'])) {
        $user_domains = $grants['domain_id'];
        $user_groups  = $grants['group_access_authenticated'];
        $domain_og_grants    = array();
        foreach($user_groups as $og) {
            foreach($user_domains as $domain_id) {
                $domain_og_grants['domain_og'][] = $domain_id . DOMAIN_OG_SEPARATOR . $og;
            }
        }
        
        $grants = array_merge($domain_og_grants, $grants);
        
        //print_r($grants);
        unset($grants['domain_id']);
        unset($grants['group_access_authenticated']);
    }
}

Any suggestions are welcome! Thanks again for your explanation.

joakim.dahlberg’s picture

I checked and it turns out the domain records are being set as they should with the priority hack. I suppose I'll just go with this - apparenty hacky - solution for now until a more stable solution appears. Good work with the hooks though, I might try it out later on!

BrightBold’s picture

@kugta - Thanks for all your work on this! I'm hoping to test out your code in the next few weeks; I'll let you know how it works for me.

BrightBold’s picture

Curious what @agentrickard thinks of the most recently posted solution — is it closer to being the preferred way to solve this problem, or still hacky? I am hoping to try this out this weekend (unless time gets away from me, which may happen!)

agentrickard’s picture

It's close the the preferred means, though the '0990' separator trick is the hacky part. But since gid has to be numeric, I'm not sure what the other options are there.

Someone with a CS background should be able to tell us how to concatenate two numbers into a unique third number...

kihap’s picture

I'd like to test out the code from #19, but being a newbie I don't know where to insert it. Could someone give me some tips on what I need to do in order test the code on the site?

This issue (and hopefully the fix) relate directly to my use case where I am using Domain to provide front doors to people's/affiliate's mini-sites. These mini-sites are built on organic groups that are part of an overall site / sharing community. I need to give each mini-site its own top level domain.

On a related note, has anyone looked at how the og_domain module worked for D6? It seems to be what we're looking for.

Is there any chance that this functionality is going to be included in OG 7.x-2.x?

Thanks!

BrightBold’s picture

@LeapYear —
Basicall you want to create a custom module and put the code above in the .module file. There are instructions for creating a Drupal module here: http://drupal.org/node/1074360 — I think you'll only need the first two pages, Getting Started which describes what folders and files to create, and Telling Drupal about Your Module which explains what to write in your .info file. If you follow those instructions and change all instances of MY_MODULE in the code above to whatever you've named your module. Let us know if you need help.

BrightBold’s picture

Or — wait, I just remembered I already did this! (Although apparently I got called away by other projects before I could test it.) Here you go.

kihap’s picture

@BrightBold - Excellent. Thank you!

BrightBold’s picture

@kihap - will you let us know how it works for you? I intended to test it and report back but that part of the project where I was using it got put on the back-burner and I haven't gotten back to it yet. I'd love to know how it works for you so I know what to expect!

markwk’s picture

Hi guys, I'm stepping in a bit late on this discussion but interested in the results/feedback. I'm looking to combine OG 7.x-2.x along with various subdomains to create a community by community SINGLE site but with OG-specific subdomains. I see alot of different solutions above. Can anyone recommend the best / most viable starting point?

kugta’s picture

@markwk - The solution posted in #26 by BrightBold is basically the same solution I proposed in #19. She put it nicely in a separate module, so you can install it in a clean way. Thanks for that btw :)

I suggest to go with #26. The solution is working for me ever since I've posted it, and didn't have any issues with it.

agentrickard’s picture

Would be awesome if someone would release and maintain that module. It's an interesting example of the new functionality for combining node access modules in D7.

BrightBold’s picture

Yes, let's be clear that @kugta wrote the code! So s/he gets all the credit. But I do know how to package code up into a module, so I offer that as my small contribution.

markwk’s picture

Thanks everyone. Much appreciated. I'll take a look at this for my starting point.

kugta’s picture

@agentrickard - I've created a sandbox project based on #26 and I am ready to maintain it in the future as a full project. Could you give it a quick look, please? I am not sure that I did everything as it supposed to be done. This is my first project, I think it is simple enough to start with, but any advice is welcome.

Here is the project: http://drupal.org/sandbox/kugta/1621090

agentrickard’s picture

@kugta

Do you need to apply for full Git access? If so, post the issue here so we can follow-up.

There are some coding standards issues --possibly the indentation of lines and the formatting of conditionals, but otherwise it looks good. Clearly documented code, too.

torrance123’s picture

I wrote the original d7 domain_adv patch available in this thread: http://drupal.org/node/1117262#comment-4692228 However, there are issues with that type of implementation and I think the method used by kugta is better.

I've created a fairly substantial patch to kugta's module available here: http://drupal.org/node/1643784 which fixes a number of bugs I was coming across and fixes some formatting issues.

I'm really hoping to see people come together around *a* solution of some sort for this issue, as this has been an ongoing issue for us.

torrance123’s picture

Please see https://github.com/torrance/domain_og_bridge for an updated version of Kugta's module.

agentrickard’s picture

Is there a reason that isn't on d.o.?

torrance123’s picture

Is there a reason that isn't on d.o.?

Not really. I have a github account already so that's easier. I'm maintaining it at this point for our own use and sharing the code to help others, but I'm not prepared to take on the role of maintaining a module at this point.

Yuri’s picture

I installed the #37 module, but I don't see any changes.
After installation, rebuild of permissions are asked and done. Cleared cache, update.php,
but group visibility: private still results to be visible and accessible to anonymous users (although group permissions disallow that)
This module I applied to an existing installation of OG and DA.

Anyone with similar issues on this #37 module?

Yuri’s picture

Can someone please confirm to me that he/she has tested this with the latest devs of DA and OG, since the code and modules mentioned in this tread do not have the required effect in my site. Since this thread appears to be the closest solution ever for the DA/OG permissions issue, I really would like to check out why it is not working for me.
I have installed, tested, uninstalled reinstalled etc. but still private groups are visible and accessible to any anonymous user, as well as private group content. Please give me a hand to figure this out.
Thanks you

torrance123’s picture

Hi Yuri,

I guess the first thing to confirm is that the private groups and the content posted to private groups is indeed returning a 403/access denied when domain is disabled. For group content, you need to make sure that the content type has the 'content visibility' field included, or else it won't receive the same permissions as the group to which it is posted.

If you've double checked that OG groups and content are indeed private when Domain module is disabled, then (re)enable Domain module and Domain_OG_Bridge module. You'll need to rebuild permissions.

Now, note the node id of the node or nodes that should be private. Then take a look in the database (using phpmyadmin or your favourite tool) and open the table 'node_access'. Find the row(s) where the column 'nid' matches the node id you noted before. You should see something like:

101 : 2 : domain_og_0 : 1 : 0 : 0
101 : 2 : domain_og_all : 1 : 0 : 0

Which means node 101 on my system is visible on domain 0 (the primary domain) and also to all affiliates, so long the current user is a member of group ID 2.

If you see records like these, it means the module has at least kicked in. If, however, you rows that look like

4 : 0 : domain_id : 1 : 1 : 1
4 : 2 : group_access_authenticated : 1 : 0 : 0

etc. then this means there are still independent records for each of domain and organic groups, and that domain is overwriting the permissions granted by organic groups.

Depending on what you're seeing, I'll have some inkling what's going on. There's every possibility there's something wrong with my module, but we've had it running on 2 production systems for a wee while now and it's been serving us well.

Yuri’s picture

Hello torrance123, thank you for your explanation.

Because it still does not work on my site, I did a clean install for testing.

Installed Drupal 7.15

Installed the latest dev versions of Organic Groups 7.x-2.x-dev and its dependecies.

Created a content type 'Group'
Added the group Group visibility field to the content type Group

Created a node of type Group (node/1),
Set the group visibility to Private.
Viewing the group as anonymous user: user gets access denied (Privacy working).

Installed the latest Domain Access 7.x-3.x-dev
Viewing the group as anonymous user: user can view the group (Privacy not working).

Downloaded the domain_og_bridge module from https://github.com/torrance/domain_og_bridge
Which is the zipfile named torrance-domain_og_bridge-0fd3c9f.zip
Installed the module
Rebuilded permissions
Viewing the group as anonymous user: user can view the group (Privacy not working).
Did update.php, clear cache, but that has not effect on this issue.

Phpmyadmin, table node_access:

nid   gid   realm         grant_view grant_update grant_delete
0     0     domain_all      1          0          0
1     0     domain_site     1          0          0 
1     1     doamin_id       1          1          1
1     1     og_access:node  1          0          0

I will send you a personal message with the login details of the test site and phpmyadmin, so you can verify if things are different from your setup.

torrance123’s picture

Installed the latest dev versions of Organic Groups 7.x-2.x-dev and its dependecies.

It looks as though the node access realm has change in organic groups 2.x to og_access:node. Can you uninstall og 2 and install the latest stable 1.x version, to confirm?

If that is indeed the case, I'll see about accommodating that change in realm id with version 2.

Yuri’s picture

Yep, I confirm that the current domain_og_bridge module works fine with OG 7.x-1.4 (which is the latest 7.x-1.x version) on a clean install. Node_access table now show correctly as you pointed out. The Devel blocks are very helpful in this by the way. Well done, and sorry I didn't check that OG version.

And yes, thanks for your time to make this work with the version 2. Amazing stuff that you all already accomplished with this bridge module.

kihap’s picture

torrance123, thanks so much for coding this! It would be such a great help if you could get it to work with OG 7.x-2.x since it seems that all the focus of development for OG is on that version.

Yuri’s picture

I am currently using a workaround to create a separate domain that disallows access to users that are not assigned to the domain. This uses the 'Domain Strict' sub module of DA. That domain contains the group that should be denied access to non-members.
This is actually not a workaround at all, and makes it overly complicated to work with.

@torrance123 or @other posters in this thread, is anyone willing to look into 7.x-2.x compatibility soon?
Thank you so much.

torrance123’s picture

Yuri, Kihap, please test the latest commit of https://github.com/torrance/domain_og_bridge

Also ensure you update the db and then rebuild permissions after upgrading. I think I have it working now for both OG 1.x and 2.x, although I haven't looked much into why the realm name changed for OG and what else might have changed in its behaviour.

Yuri’s picture

Yes torrance123, your latest commit indeed gives an access denied for private groups, and makes them invisible for non-groupmembers. Congatulations!
I did not test it very thoroughly but I got the bridge on a clean install and a production site already, so any issues will come to ear soon enough. Seems to work fine though, thank you!

niccolox’s picture

has anyone tried this bridge with the Drupal Commons 3 Beta 1 ? http://drupal.org/project/commons

ibakayoko’s picture

torrance123

I have made some (small) modifications to your code to do the bridge between Domain and Workflow.

Thank you for your code.

https://github.com/ibakayoko/domain_wf_bridge

greg.1.anderson’s picture

Perhaps domain_og_bridge could be made a project on drupal.org?

niccolox’s picture

Yes greg. This is a breakthrough moment

A full project ought mark the milestone

Open Social’s picture

Anybody still working on this? We need this setup for a big project which combines DA, OG and i18n.

Our setup:
- Latest version of the module [https://github.com/torrance/domain_og_bridge]
- Domain Access 3.7
- OG 7.x-2.0-rc2
- og_access enabled.

Our findings:
1. + Does the job for OG private nodes. It is private when needed.
2. - When a Group is posted as a Public group on domain 1 (not send to all affiliates) it will also be available on domain 2.
3. - When a page content type (not a group page, or a group content type) is posted on domain 1 (not send to all affiliates) it will also be available on domain 2.

So, my assumption is we still need to work on point 2 and 3.

I think it is time for a central place (on d.org) where we can work on these issues or submit new issues when necessary.

agentrickard’s picture

@goalgorilla

I believe you want https://github.com/torrance/domain_og_bridge

babbage’s picture

OK, well I needed this functionality myself, and like agentrickard I was of the view that it'd be better to have this hosted on drupal.org for those of us who prefer to have our module repositories here. Given torrance123's explicit statement in #39 that he didn't want to take on maintaining a module at this time, I've gone ahead and created a module here using the code from his github repository. The module here maintains the previous commit history, and I've made both torrence123 and kugta maintainers of the project (no pressure to do anything torrence123!) should they wish to push further commits here in the future. Let me know if either of you want this revoked.

This is a very simple code base. I wasn't 100% convinced that we needed a new, separate module for this I've initially created Domain OG module as a sandbox project, though I have permissions already to upgrade it to a full module if we decide it should be. (A sandbox means you still need to check it out via git if you want to use it at this stage, just now from d.o.)

It is hard to anticipate a situation where this code shouldn't automatically kick in when both the Domain Access and Organic Groups modules are in operation. So the key question is—should this really be a separate module, or should this code just be built into Domain Access, or into Organic Groups, so that it just operates automatically when both are installed and enabled?

markwk’s picture

@ibakayoko: a drupal.org module like this already exists for a domain access + workflow bridge: http://drupal.org/project/domain_wf_bridge :)

agentrickard’s picture

@babbage

Separate module. Too much burden to place on either module maintainer to keep up with the other. It is, in fact, harder to anticipate a situation where this code is needed.

babbage’s picture

@agentrickard: Fair enough point that neither module maintainer should have to keep up with the other.

I'm surprised by the later point, however, so perhaps I've misunderstood. Unless I've simply mis-configured something, isn't it the case that such a module would be required on any site that wanted to have private Organic Groups content which had Domain Access module installed? On a site on which I was testing this, Domain Access was opening up access to otherwise private Organic Groups content, even though the content was assigned to only one domain. I assumed this was a side effect of Drupal's grant-only/no-restrict permissions structure and the way Domain Access module worked, but perhaps I was simply configuring something incorrectly?

Edit: OK. I've seen your comments here: #1773922: Domain Access + Content Access + ACL. Clearly this is an issue that you've dealt with before, and my assumptions coming into this are different to those that underlie the Domain Access module.

agentrickard’s picture

:-)

abacusmedia’s picture

Version: 7.x-3.x-dev » 6.x-2.8
Assigned: Unassigned » abacusmedia

Hi all,
I was wondering if anyone has found a solution that works with Drupal 6.28?

Essentially I want to block access to specific pages for users unless they become registered users. I know some php, but not to the level of some of you guys.

I thought this would have been quite simple but I've been on this for days and nothing I've tried seems to work.

Thanks in advance for any assistance.

agentrickard’s picture

In the 6.x branch, you might be able to duplicate the work using hook_domainrecords() and hook_domaingrants(). The alter hooks we use in Drupal 7 are not available in Drupal 6.

See also https://drupal.org/project/domain_adv for Drupal 6.

greg.1.anderson’s picture

I added a link to the sandbox project Domain Og Bridge to the Domain Access Related contributed modules; hope it's okay to put sandbox modules there. I also created #1970962: Update Domain Access documentation page when Domain OG Bridge Module becomes a full project as a reminder to update the documentation when the sandbox project becomes a full module.

agentrickard’s picture

It's fine. Thanks.

hanksterr7’s picture

Issue summary: View changes

@markwk, @ibakayoko

I tried Domain Workflow Bridge module. Found that it caused workflow grants to override DA grants, so nodes with workflows would show in all domains. Wasn't what I wanted. Domain OG bridge (main focus of this thread) seems to work well for my needs (I want DA and OG to control node visibility, regardless of associated workflow state). Not sure if Domain Access Bridge module would add anything beyond what Domain OG does.

Drupa1ish’s picture

Never tried #26 or #55, but https://www.drupal.org/project/domain_access_bridge is a more general use case, works flawless with DA and OG and well maintained