Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amitaibu’s picture

Status: Needs review » Closed (works as designed)

> At the moment, og is restricting node access permissions to only those who are members.

That's not correct, see:

// We don't have a context, so we need to get all the permissions
// of all the groups. We don't intersect with the user's group, as
// groups might allow anonymous members access.
foreach ($gids as $gid) {

hook_node_access() deals only with OG's permissions. The "core" permissions are already handled via node module.

mradcliffe’s picture

Status: Closed (works as designed) » Needs review
FileSize
6.41 KB
3.33 KB
8.43 KB

> That's not correct, see:

Yes, it is correct. Og is specifically telling to deny access if og_user_access($gid, etc... does not pass. See screenshots after explanation below:

  1. Enable og, og_ui, og_access, devel, devel_node_access
  2. Create group node type
  3. Create node of group type
  4. "editor" user and "editor" role setup with permission to edit any group node type
  5. "member" authenticated user setup
  6. Add "member" to node group, but not "editor"
  7. Rebuild content permissions just in case
  8. Look at devel node access, editor is blocked from being able to modify node by og module, not core
  9. "editor" cannot access node/%/edit because of og

Edit: it would have been better if i posted more information earlier, sorry.

mradcliffe’s picture

I'm going to write a test case to check things.

mradcliffe’s picture

FileSize
2.26 KB

Okay, here's a test case that shows the issue. I did not make it a patch but a separate test file so you need to add it to og.info.

amitaibu’s picture

Status: Needs review » Needs work

Ok, now I understand :)

I think this isn't a bug, but a feature, as one might want OG to take full control (actually up until now, there was no issue like yours, so I assume most people want it this way).

So I think our appraoch should be in og_node_access:

Instead of $return = NODE_ACCESS_DENY; we should have a variable:

$return = variable_get('og_node_access_strict', TRUE) ? NODE_ACCESS_DENY : NODE_ACCESS_IGNORE;

And in OG-UI add this setting. Of course a simpleTest will make sure it will be committed ;)

mradcliffe’s picture

Cool. That sounds good to me. I'll try to get a patch to you, with tests, early next week. :-)

mradcliffe’s picture

Status: Needs work » Needs review
FileSize
8 KB

Okay, I added the variable in og_ui's admin settings, added to the array of variable to remove in og_uninstall(), and modified og_node_access().

Also wrote some tests. I did not add to testOgAccess method, but added my own OgNodeAccess class in og.test (two test methods). I did not include tests for a group member editing content because it depends on og_access, and I am not sure if that should be in og_access or not. If you want, I can add to the test or refactor and put it all in testOgAccess.

amitaibu’s picture

Status: Needs review » Needs work

Thanks!

+++ b/og.moduleundefined
@@ -425,12 +425,11 @@ function og_og_default_roles() {
+  $return = variable_get('og_node_access_strict', TRUE) ? NODE_ACCESS_DENY : NODE_ACCESS_IGNORE;

Lets add comment why we have this variable -- i.e. OG full control VS allowing others to also decide.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+  ¶

Minor: Remove white space.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    // Create some users

Missing dot in the end (other comments as-well).

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->group_manager = $this->drupalCreateUser(array('access content'));

Isn't $this->drupalCreateUser() enough?

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $settings = array('type' => 'page', OG_GROUP_FIELD . '[und][0][value]' => 1, 'uid' => $this->group_manager->uid);

Please break this long line.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+  function testStrictAccess() {

Add PHPdocs.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    // Rebuild content access perms., and set group perms.
+    $this->drupalLogin($this->admin_user);
+    $this->drupalPost('admin/reports/status/rebuild', array(), t('Rebuild permissions'));
+    $this->drupalGet('node/' . $this->group_node->nid);
+    $this->drupalLogout();

We don't need this, as we don't deal with node access records.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->assertRaw('Access denied', t('A non-member with core node access permissions was denied access to edit group node.'));

Use $this->assertResponse()

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+
+    $this->drupalLogout();
+
+    // Login as a group manager and try to change group node..
+    $this->drupalLogin($this->group_manager);

I don't think you need to logout, before login -- doesn't it happen by itself? not sure.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->drupalLogout();

No need to logout, in the end of the test :)

+++ b/og_ui/og_ui.admin.incundefined
@@ -19,6 +19,13 @@ function og_ui_user_admin_settings($form_state) {
+    '#title' => t('Strict group node access permissions'),

Maybe better: Strict node access permissions

+++ b/og_ui/og_ui.admin.incundefined
@@ -19,6 +19,13 @@ function og_ui_user_admin_settings($form_state) {
+    '#description' => t('When enabled group node access permissions will supercede core node access permissions such as update and delete.'),

Maybe: When enabled OG takes full control over node access and if no access found based on OG access is denied. If disabled access will not be explicitly denied.

amitaibu’s picture

Thanks!

+++ b/og.moduleundefined
@@ -425,12 +425,11 @@ function og_og_default_roles() {
+  $return = variable_get('og_node_access_strict', TRUE) ? NODE_ACCESS_DENY : NODE_ACCESS_IGNORE;

Lets add comment why we have this variable -- i.e. OG full control VS allowing others to also decide.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+  ¶

Minor: Remove white space.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    // Create some users

Missing dot in the end (other comments as-well).

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->group_manager = $this->drupalCreateUser(array('access content'));

Isn't $this->drupalCreateUser() enough?

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $settings = array('type' => 'page', OG_GROUP_FIELD . '[und][0][value]' => 1, 'uid' => $this->group_manager->uid);

Please break this long line.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+  function testStrictAccess() {

Add PHPdocs.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    // Rebuild content access perms., and set group perms.
+    $this->drupalLogin($this->admin_user);
+    $this->drupalPost('admin/reports/status/rebuild', array(), t('Rebuild permissions'));
+    $this->drupalGet('node/' . $this->group_node->nid);
+    $this->drupalLogout();

We don't need this, as we don't deal with node access records.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->assertRaw('Access denied', t('A non-member with core node access permissions was denied access to edit group node.'));

Use $this->assertResponse()

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+
+    $this->drupalLogout();
+
+    // Login as a group manager and try to change group node..
+    $this->drupalLogin($this->group_manager);

I don't think you need to logout, before login -- doesn't it happen by itself? not sure.

+++ b/og.testundefined
@@ -326,6 +326,106 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->drupalLogout();

No need to logout, in the end of the test :)

+++ b/og_ui/og_ui.admin.incundefined
@@ -19,6 +19,13 @@ function og_ui_user_admin_settings($form_state) {
+    '#title' => t('Strict group node access permissions'),

Maybe better: Strict node access permissions

+++ b/og_ui/og_ui.admin.incundefined
@@ -19,6 +19,13 @@ function og_ui_user_admin_settings($form_state) {
+    '#description' => t('When enabled group node access permissions will supercede core node access permissions such as update and delete.'),

Maybe: When enabled OG takes full control over node access and if no access found based on OG access is denied. If disabled access will not be explicitly denied.

mradcliffe’s picture

Whoops, I also forgot to run through other og tests, which caught another big bug. I have attached two patches to address that and the issues above, but this should not be considered ready. I found a case where the solution doesn't fit correctly. :(

In my use case, a user would not have access to the group audience field via field_permissions. However this is not default behavior. If a user does have access to it, but is not in the group and can edit group content, then we run into this issue where they do not see any groups in the group field. There is a warning on node save, but it maintains the group.

I could see the following situations although I think that the second and third one fall under the same case (maybe not):

  1. Non-member with edit any permission edits group content
  2. Non-member with bypass node access permission edits group content
  3. Non-member with administer group permission edits group content

Is default behavior for a non-member to be able to see potential groups? If that is true, then I just need to allow that in a patch.

Another question: I have some commits to my local development branch. Should I create a new branch and just grab the overall code and commit that, then format a new patch. Or do you want to see all of this history, Amitaibu? Thanks.

amitaibu’s picture

> Should I create a new branch and just grab the overall code and commit that, then format a new patch

Yes please:

git diff 7.x-1.x my-branch > patch-fie.patch

mradcliffe’s picture

Status: Needs work » Needs review
FileSize
9.92 KB

Okay, new patch.

After thinking about it, I don't think Og should make any assumptions on whether a user with edit should be able to see all groups or not. I added an extra conditional wrapper in the validate function, but that's it. Tests pass.

amitaibu’s picture

Status: Needs review » Needs work
+++ b/og.field.incundefined
@@ -402,19 +402,21 @@ function og_field_attach_form($entity_type, $entity, &$form, $form_state, $langc
+    // Rebuild the form state values if OG_AUDIENCE_FIELD exists.

Why is this needed? This validation callback is called from OG-audience widget, so for sure the field is there. + it's not related to the issue ;)

+++ b/og.moduleundefined
@@ -431,18 +431,21 @@ function og_node_access($node, $op, $account) {
+        // og_node_access_strict will take full control of node access when true
+        // while it will pass through access to other modules when false.

Maybe better: Determine if OG should explicitly deny access.

+++ b/og.testundefined
@@ -326,6 +326,116 @@ class OgGroupApi extends DrupalWebTestCase {
+    $this->assertTrue(variable_get('og_node_access_strict'), t('Organic groups node access strict variable set to true.'));

No need for this assert.

+++ b/og.testundefined
@@ -326,6 +326,116 @@ class OgGroupApi extends DrupalWebTestCase {
+    // Login as a group manager and try to change group node.
+    $this->drupalLogin($this->group_manager);

Why do we need this part?

I have just committed this , which will allow to make og_node_access() shorter, something along this lines (untested):

/**
 * Implement hook_node_access()
 */
function og_node_access($node, $op, $account) {
  // If not a group type or the operation is node creation which still has no
  // groups so we can't check it yet, we ignore the access.
  $return = NODE_ACCESS_IGNORE;

  $type = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
  if (in_array($op, array('update', 'delete'))) {
    $access = og_user_access_entity('administer group', 'node', $node, $account);

    if (is_null($access)) {
      // The node isn't in an OG context, so no need to keep testing.
      return NODE_ACCESS_IGNORE;
    }
    else {
      $access = $access ||
        // Any content.
        og_user_access_entity("$op any $type content", 'node', $node, $account) ||
        // Own content.
        og_user_access_entity("$op own $type content", 'node', $node, $account);
    }

    if ($access) {
      return NODE_ACCESS_ALLOW;
    }

    // No access, check if OG should explicitly deny.
    return variable_get('og_node_access_strict', TRUE);
  }

  return NODE_ACCESS_IGNORE;
}
mradcliffe’s picture

+++ b/og.field.incundefined
@@ -402,19 +402,21 @@ function og_field_attach_form($entity_type, $entity, &$form, $form_state, $langc
+ // Rebuild the form state values if OG_AUDIENCE_FIELD exists.

Why is this needed? This validation callback is called from OG-audience widget, so for sure the field is there. + it's not related to the issue ;)

If I have permission to edit the node, but I am not in a group, I received a warning about it being undefined after I clicked save. No data loss.

I will rework the patch based on the og_node_access changes.

mradcliffe’s picture

Status: Needs work » Needs review
FileSize
10.92 KB

Okay, I have re-rolled the patch to try to integrate og_node_access changes.

I did find a failing test with og_field_access, but that seems to be a general issue with "update body field" without "update type content" permission in og_permissions.

Should a user who can update a field be able to update the node as well? I don't use og_field_access myself so I am not sure about the correct behavior.

Edit: I switched to git diff for some reason this time.

amitaibu’s picture

Status: Needs review » Needs work

> Should a user who can update a field be able to update the node as well?

No. But it seems that the failing test is "catching" a bug (as it passes without the test). Note that it fails in giving access to node-edit.

amitaibu’s picture

Oh, I see where it fails. We have the "update group" permissions defined in OG, but we don't explicitly check for it in the hook_node_access().

amitaibu’s picture

^^ It's good that we have tests ;)

amitaibu’s picture

Status: Needs work » Needs review
FileSize
11.15 KB

Attach the patch the solves #17. Still reviewing...

amitaibu’s picture

Category: bug » feature
Status: Needs review » Fixed

Cleaned a bit more, and committed. Thank you mradcliffe!

Status: Fixed » Closed (fixed)

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