Hello,

When using og.module on a site when NOT ALL of the content belongs to at least one group (i.e. where some content doesn't belong to any group), that part of the content is not accessible to anyone (but the admin), regardless of other permission setting.

The problem is that when rebuilding the permissions with og.module enabled, only the nodes that belong to at least one og are listed in the table {node_access}. Access to all other nodes, those not listed in {node_access}, is denied.

Comments

beginner’s picture

When I manually INSERT some rows for those nodes, everything behaves as I would have expected.
The question is, why those rows are not created in the first place...

beginner’s picture

in node_access_write_grants, the nodes are not INSERTed because og.module denies every grant. The $grant array is defined in og_node_access_records as follows:

    [0] => Array
        (
            [priority] => 10
            [realm] => og_public
            [gid] => 0
            [grant_view] => 0
            [grant_update] => 0
            [grant_delete] => 0
        )
moshe weitzman’s picture

did you mark those node types as omitted in og? you are using HEAD or 5? do you have any other node_access modules running?

beginner’s picture

I found the culprit in function og_node_access_records:

  // propose a deny for non public nodes whose type matters to og and aren't in a group
  if (!count($grants)) {
    $grants[] = array('priority' => 10, 'realm' => 'og_public', 'gid' => 0, 'grant_view' => 0, 'grant_update' => 0, 'grant_delete' => 0);
  }

Apparently, the behavior is 'by design'! :(
I like the 'proposal' hidden away in the code. (well, not quite!).

This behavior is unacceptable for a site where the same node type may or may not be part of an og.
The solution is to delete this piece of code...

Am I missing something?

beginner’s picture

Using HEAD, and it's the only node_access module running.
All node types can be added to a group on my test platform. I understand what this implies, now. But this behavior will surprise more than one...

moshe weitzman’s picture

can you explain what is surprising about this, and what you propose to make behavior more intuitive. please consider the available prefs on admon/og/og

beginner’s picture

Priority: Critical » Normal
Status: Active » Closed (works as designed)

Yes, I was looking at the settings at admin/og/og when you posted.
What I hadn't expected was:
1) the public checkbox (unchecked) would affect even those nodes that are not part of an og. What I had expected was: "IF this node is part of an og, is is public or not?"
2) that the settings in admin/og/og would be applied retro-actively to all nodes created before og.module was enabled the first time. What freaked me is that using the wrong setting, all my nodes disappeared from the front page!

I am suspecting that this user was also startled by this behavior: http://drupal.org/node/106347

I am setting this issue as "by design" for now. I am not too sure if things could be done better. Maybe it's just me who should learn how the tools I am using actually work :) (well, now I know!)

I apologize for the noise and thanks for the support :).

moshe weitzman’s picture

Title: non-og content not accessible » don't deny access to nodes that are without a group
Status: Closed (works as designed) » Active

1) is arguably a bug in the new 5.0 port.

2) i will add some text about this.

reopening this issue. thanks beginner.

beginner’s picture

Priority: Normal » Critical
StatusFileSize
new772 bytes

Actually, there IS a bug.

This bug doesn't affect:
a- the sites like groups.d.o who only use og for their content.
b- the sites that have a specific node type only for groups.
but affects mixed sites (i.e. sites where forum posts or blog entries may or may not belong to a group, and/or who had plenty such nodes before og.module was enabled).

The bug is: any node created before og.module was enabled (or whenever it is disabled) do not have an entry in {og_ancestry}, i.e. they are hard-coded to private by default even though they do not belong to any group.

beginner’s picture

btw (1) and (2) mentioned in #7 and #8 are related.
(2) is actually wrong: the help text of the visibility of posts setting reads: Note that changing this setting has no effect on existing posts. Re-save those posts to acquire this new setting..

So only (1) needs to be fixed with the patch above.

beginner’s picture

Status: Active » Needs review
mgerra’s picture

Wondering if there is a patch or someone with a solution for 4.7.6. I currently have og 1.110.2.148 installed and am having same problem.

That is, if neither public nor private group is selected then no group gets set (I'd like it to default to public) and no record is added to node_access table for that nid.

moshe weitzman’s picture

I am starting to agree that this is not expected behavior. i'm inclined to remove that deny grant completely. am a bit worried though that some sites rely on this hiding for whatever reason.

mgerra’s picture

I found a possible culprit in og_submit_group (og.module v.1.110.2.148). Please bear in mind I'm no php expert and even less
so regarding og. That said, here's a place to look:

if(empty($node->og_groups)) {
$node->og_public =1
}

empty() does not return true when all og_groups checkboxes in the node edit form are left unchecked. So, og_public = 1 never
gets set when there are groups on the node form.

That is, empty() does not perceive the og_groups array to be empty because the array keys are set with nids for each group,
with only the array values being empty.

I hope this helps. I have not posted my own patched solution, because it's not very elegant, but it does work for me. Rather than using
empty(), I check each array element individually, and set og_public if I find all array element values to be 0.

Mike.

newms’s picture

I want to second (or third) this issue. I upgraded my site from 4.7.x to 5.1 last week and anonymous and registered users could not access my site. They would get the "Access denied" page. For the life of me I couldn't figure out what was wrong until I stumbled accross this issue. To resolve the problem, I had to re-submit each organic group on my site. Fortunately there were only 2! Good luck on finding a solution to this. OG is a very important module IMO.

moshe weitzman’s picture

I am going to try to fix a couple more bugs and then make a release of og5. then this can get committed to HEAD and tip of DRUPAL-5. no timeframe though.

moshe weitzman’s picture

Well, I might take this in the upcoming release. In addition to the latest patch, we need some wording on the Public checkbox like "Posts that are not in any group are Public regardless of this checkbox."

torne’s picture

In addition to wording indicating that untargetted posts are public, wouldn't it be nice to have a teeny JS fragment that actually ticked and greyed out the public box if no group was selected, just to make it clearer what's happening?

moshe weitzman’s picture

yes, that javascript would be nice.

Egon Bianchet’s picture

Hi all, I was following http://drupal.org/node/83005, which is marginally related to this one..

I don't think that the proposed solution is a good, wouldn't it be better to fill the node_ancestry table for unassigned nodes when enabling og?

Having a 'Public' checkbox with a notice like "Posts that are not in any group are Public regardless of this checkbox." is rather confusing ... I'd expect nodes without the public checkbox to be private.

Egon Bianchet’s picture

If filling the node_ancestry table isn't feasible, mabye reversing the logic and using a "Private" checkbox would be less confusing:

  • nodes are by default untouched by og
  • when you check a group in the audience fieldset the node is assigned to that group but it's public
  • to make it restricted to that group only you have to check "private"
  • if you check only private and no groups the node is accessible only from its author
moshe weitzman’s picture

hiding nodes to only their author is not part of og's mission. i'm inclined to stick with the track we are discussing (Public is assumed if node not in any groups)

moshe weitzman’s picture

I should have said more. The point of the ancestry table to track ancestry. Thats why I don't want records for nodes that are not in any groups. I want og to not even care about such nodes.

jhm’s picture

Moshe said

hiding nodes to only their author is not part of og's mission. i'm inclined to stick with the track we are discussing (Public is assumed if node not in any groups)

and

I should have said more. The point of the ancestry table to track ancestry. Thats why I don't want records for nodes that are not in any groups. I want og to not even care about such nodes.

and I for one totally agree with that, its just that the system does not honor this logic and denies access to a node not belonging to any group when Public is not selected. I tested this 1.0 1.x-dev and HEAD.

moshe weitzman’s picture

@jhm - this patch hasn't been committed (look at the issue status). thats why you are seeing this behavior. please be patient. i am just thinking about what would be needed for an update path. also hoping someone will write the javascript to disable public checkbox on node form when no groups are selected. otherwise, the patch in #9 looks good.

moshe weitzman’s picture

Status: Needs review » Fixed

I committed this, along with some javascript for the node form. Please do test this, and report back success or failure. I hope to roll a new release of og soon.

tonythemediaguy’s picture

I think this is related.

When using Leech, organic groups doesn't seem to get passed on to the node items that Leech creates. It just marks everything as public. Nothing gets added to the node_ancestry table when Leech updates it's items. As a workaround, I added this to the Leech module:

$sql = "INSERT INTO {og_ancestry} (nid, group_nid, is_public) 
                  VALUES (%d, %d, 1)";
          db_query($sql, $n->nid, $gid);

It's not a good way to accomplish this, but it at least puts the items into the correct groups. Hopefully the new OG will fix this issue.

moshe weitzman’s picture

i don't know anything about leech but i guess it created nodes and doesn't call nodeapi('submit') before saving. anyway, thats not relevant here.

bwynants’s picture

og_node_access_records uses

  if ($node->og_public) {
    $grants[] = array('realm' => 'og_public', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0);
  }

expecting $node->og_public to be set correct. if $node->og_public is not set correct no 'grant_view' is inserted

where does $node->og_public get set? in og_nodeapi ->'load'

   if (!og_is_group_type($node->type)) {
        $node->og_public = db_result(db_query_range("SELECT is_public FROM {og_ancestry} WHERE nid = %d", $node->nid, 0, 1));
      }
      else {
        og_load_group($node);
      }

so when there is no 'og_ancestry' entry for a node (no groups selected, only public) upon next load $node->og_public is not set....

When the code then calls og_node_access_records the node_access table is no longer correct.

propose to rewrite og_node_access_records

function og_node_access_records($node) {
  // don't write records if og access control is disabled or the node type is omitted or node is a group
  // if you want group nodes to be protected too, perhaps write a complementary node_access module. lets discuss.
  if (og_is_omitted_type($node->type) || !variable_get('og_enabled', FALSE) || og_is_group_type($node->type)) {
    return;
  }
  
  if (is_array($node->og_groups) && count($node->og_groups)) {
    foreach ($node->og_groups as $gid) {
      // we write a broad grant here but og_node_grants() only issues it selectively.
      $grants[] = array('realm' => 'og_subscriber', 'gid' => $gid, 'grant_view' => 1, 'grant_update' => 1, 'grant_delete' => 1);
    }
    // $node->og_public was set correct on 'load' use it since there are groups used
    $insertPublicView = $node->og_public;
  }
  else {
    // $node->og_public was not set correct on 'load', no groups, assume public...
    $insertPublicView = TRUE;
  }

  if ($insertPublicView) {
    $grants[] = array('realm' => 'og_public', 'gid' => 0, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0);
  }
  
  // propose a deny for non public nodes whose type matters to og and aren't in a group
  if (!count($grants)) {
    $grants[] = array('priority' => 10, 'realm' => 'og_public', 'gid' => 0, 'grant_view' => 0, 'grant_update' => 0, 'grant_delete' => 0);
  }

  return $grants;
}

an alternative is make sure such nodes are catched in the initial check....


More info also in http://drupal.org/node/121566

bwynants’s picture

mmmm guess that if http://drupal.org/node/107289#comment-175014 is applied it should be ok too.....

moshe weitzman’s picture

@bwynants - i think you have missed the fact that this was committed yesterday. the code you quote has changed. please test and let me know how it goes.

bwynants’s picture

I looked ad the checkins from yesterday just a few minutes ago and they do seem OK. I'll test them this evening and report back.

bwynants’s picture

StatusFileSize
new1.38 KB

Works. I cleared all entries in og_ancestry where gid was zero, did the update.php and all is still well. Even after an edit... However the initial state of the check box is not disabled.... it only gets disabled after a click a on, click off from some group. I'm not yet familiar with this java code so can't fix it.

I also would prefer the checkbox to be ON if no goup is selected (which is a correct visual representation).

patch attached does not insert anything extra in the database :-)

moshe weitzman’s picture

@bynants - the current code assumes that if a node is not in a group, then og doesn't care about it. i simply don't want to set $node->og_public at all. Thus, we don't have to change any code in og_node_access_records() either since $node->og_public will not evaluate to TRUE for these nodes. Thus, I see no benefit from your patch.

As for the javascript - the initial state of the checkbox comes from some complicated rules and i do not want to change that even when there are no selected groups. i want the user to be able to select a group and then checkbox becomes enabled, maintaining its carefully calculated default setting.

bwynants’s picture

@moshe: I do understand your point of view as a programmer. However try to explain to a user if a post is visible or not. The user will not see 'public' selected and it's first reaction is that it will not be visible. Until he reads the small text. Checking it is 'for the user' a more direct approach. The overhead on the code is none existing!

PS: did 2 more sites with the newest code and all still fine :-)

moshe weitzman’s picture

i'm also trying to optimize user experience. this is not about optimizing code ... i wil soon roll a new release of og. thanks for the feedback.

bwynants’s picture

solving the initial state (disabled) for the checkbox is easy. add a $('.og-audience').click();
to the Drupal.ogAttach function. It gets executed when the page opens and it puts the checkbox in a correct state

moshe weitzman’s picture

if someone wants to submit a .js patch i will review it

bwynants’s picture

Status: Fixed » Needs review
StatusFileSize
new431 bytes

Correct initial state enabled/disabled state of checkbox

bwynants’s picture

StatusFileSize
new431 bytes

Correct initial state enabled/disabled state of checkbox

moshe weitzman’s picture

Status: Needs review » Fixed

committed ... i was confused and didn't realize you were fixing the disabled/enabled state, and not the checked/unchecked state ... thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)
drupalzack’s picture

Since this applies to 4.7 too (see #12 comment), will this be backported to 4.7 as well? Thanks

leoklein’s picture

Status: Closed (fixed) » Active

I'm not sure why this doesn't work on my setup -- but if you're an 'administrator', the 'public' box is grayed out. This is not the case with any other role (with sufficient permissions).

When I disable javascript in my browser, lo and behold, I'm able as an 'administrator' to check/uncheck the 'public' box.

So what I'm wondering, is what is the os.js file reading that it disables the 'public' checkbox just because the user is an administrator?

moshe weitzman’s picture

Status: Active » Fixed

please discuss that js issue elsewhere.

Anonymous’s picture

Status: Fixed » Closed (fixed)
emilyf’s picture

Version: master » 4.7.x-1.x-dev
Status: Closed (fixed) » Active

I am also on 4.7.6 and have the same question as #12 and #43. Can this patch be backported to 4.7? It seems it would be extremely beneficial to many of us.

moshe weitzman’s picture

Status: Active » Closed (fixed)

perhaps it could, if someone volunteered to maintain the 4.7 branch. i think this would be a big change for a stable branch though. IOW, very unlikely.