The new features and structure of 3.x are wonderful, however they seem to be missing a key permission, for my usecase anyway.

When a webform is attached to a content type if a user has permission to edit that content type then they also get permissions to edit the attached webform. E.g. 'page' content type with an attached webform. If a user has 'edit any/own page content' then they also get the ability to edit the attached webform.

It'd be nice to give someone the ability to edit a page, but not the webform that is attached to that page.

At the very lease I think it would be useful if a 'edit webforms' permission was added to allow control over which user can edit attached webforms.

Comments

ludo.r’s picture

Subscribing...

I usually dont give access to webform configuration because it is too complex for my clients (even if it seems a bit simpler with v3).

It would be very useful to have such a permission.

quicksketch’s picture

Hm, interesting. Webforms have always been a part of the node form up until the 3.x version. Now that they are on a completely separate tab, it would make sense to provide that as a separate permission.

fenstrat’s picture

Status: Active » Needs review
StatusFileSize
new4.59 KB

Here's a first pass at this. It simply add's back the 'edit webforms' permission and assigns it to any node/%/webform menu item. Perhaps the permission would be better named 'edit webform components'? Then raises the issue what about 'edit any/all webform components'?

As it stands this works for the use case where you want to allow access to node/%/edit but not node/%/webform

If this track is taken then it's of note that webform_update_6305() migrated any existing 'edit webforms' permissions to 'edit any webform content' and 'delete any webform content' so there's no getting those old permissions back.

quicksketch’s picture

Status: Needs review » Needs work

Hmm, I think this might be a bit of a step backwards, since this means that you can no longer use Webform with node access control systems like Organic Groups. I'm not sure if it's possible, but the ideal thing would be to make it so that we still use the node_access() function but add a new permission at the node level for "edit webform".

djalloway’s picture

I'm not sure the proper way to go about doing this either.
But, what if you wrapped the node_access() call within a custom webform_node_access() one?
This would allow the scenario you have described.
As it would return the permissions from whatever Node Access system you are using, then also handle our Webform access permissions.

In concept.

function webform_menu() {
    $items['node/%webform_menu/webform'] = array(
        'title' => 'Webform',
        'access callback' => 'webform_node_access',
        'access arguments' => array('update', 1),
    );
}

function webform_node_access($op, $node, $account = NULL) {
    switch ($op) {
        case "update":
            if (node_access('update', $node) && user_access('edit webforms')) {
                return TRUE;
            }
            break;
    }

    return FALSE;
}
quicksketch’s picture

Though the entire request was to make it so that users could have access to edit the webform but not the node itself. The suggested change would only accomplish the reverse, where the node could be edited but the webform could not.

djalloway’s picture

Swing and a miss.
You're right, I miss-understood the request entirely.

fenstrat’s picture

Status: Needs work » Needs review
StatusFileSize
new5.43 KB

@quicksketch from #4: Is this what you had in mind?

quicksketch’s picture

Status: Needs review » Needs work

Thanks fenstrat, but unfortunately this approach has the same problems I mentioned in #4, which is that Webform would no longer be able to be used with access control systems like Organic Groups. If a user is a "group administrator", they should be able to edit Webform forms but only within their group. If we start using a custom access callback instead of the node_access() function, then access control modules will no longer work with webform and it'd make it so that any user that has "edit webform webforms" (the name is a problem of its own) permissions would be able to edit webforms across the whole site instead of just in their groups.

djalloway’s picture

Ok, new day, new coffee, clear head... let me try to help again.

What are the possibilities of integrating Webform into the Node Access system?
Maybe define our own Realms and Grants to work along side other systems?

Is this beyond the scope of Webform?

quicksketch’s picture

I'm not sure this is a feasible problem to solve. What we really want here is a new $op outside of the normal set supported by node.module. Unfortunately the node_access() function is hard-coded to a small set of operations:

function node_access($op, $node, $account = NULL) {
  global $user;

  if (!$node || !in_array($op, array('view', 'update', 'delete', 'create'), TRUE)) {
    // If there was no node to check against, or the $op was not one of the
    // supported ones, we return access denied.

Creating a new access control realm would only make it so that we could control the "edit" operation, it wouldn't make it possible to control the access to just the "webform" tab.

So after all of this analysis, I think the "solution" is to just use hook_menu_alter() if you don't want the edit tab and turn it off for certain roles.

function mymodule_menu_alter($items) {
  $items['node/%node/edit']['access_callback'] = 'mymodule_access_check';
}

function mymodule_access_check($op, $node, $account = NULL) {
  if (empty($account)) {
    $account = $GLOBALS['user'];
  }
  $access = node_access($op, $node, $account);
  $rid = 1; // The role a user must have to edit webform nodes.
  if ($access && $node->type == 'webform' && $op == 'update' && !in_array($rid, $account->roles)) {
    return FALSE;
  }
  return $access;
}

I don't think this can be added as an option in Webform. Additionally, I'm not sure we want to make it an option in Webform anyway.

fenstrat’s picture

Hmm, can now see the challenges of integrating with access control systems.

Do appreciate that use case, however I think there'll be a lot of support request with the simple use case of "how do I remove the Webform tab from my $node->type node"? After all giving a user access to edit a page (or other node type) is really quite different to giving them access to edit any attached webform.

As a simple example to do that you need to do something like this:

function mymodule_menu_alter(&$items) {
  // Change the permission needed to edit attached webforms.
  $items['node/%webform_menu/webform']['access callback'] = 'user_access';
  $items['node/%webform_menu/webform']['access arguments'] = array('administer nodes');
}

Keep in mind that it's not complete in that it only changes access to the top level attached webform 'tab' and not other menu item callbacks under that path.

Can see why this could be a won't fix. But I do think this simple use case will start to crop up more often.

bartezz’s picture

For those who don't know how to implement fenstrat's code;
http://drupal.org/node/1025724#comment-4037140

Cheers

quicksketch’s picture

Status: Needs work » Closed (won't fix)

Thanks guys. Moving to won't fix per the technical difficulties involved. While another module could implement this (or more easily a custom module implementing either of the solutions above), I don't think this is feasible to include in Webform directly because the node access system simply isn't made to handle it. See #4 and #9 for explanations why.

Anonymous’s picture

Thanks fenstrat, the workaround in #12 worked perfectly for me (removed the webform tab, and if they try to navigate straight to the webform URL they get "You are not authorized to access this page.")

gynekolog’s picture

danchadwick’s picture

Issue summary: View changes
Status: Closed (won't fix) » Closed (duplicate)
fenstrat’s picture