Add "Create" as an option for TAC

markDrupal - May 15, 2009 - 22:37
Project:Taxonomy Access Control Lite
Version:6.x-1.3
Component:User interface
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs review
Description

Am I mistaken, any user can add a node with a taxonomy term that I have forbid them to view? This module should strip out terms from the "node create new ..." forms and "update node forms" so only terms that they have access to "Create" appear. This could also have a check when the node is validated to ensure that only terms the users is allowed to use have been selected.

#1

Dave Cohen - May 16, 2009 - 01:45
Status:active» won't fix

tac_lite will hide terms from a user if they have no permission to view the terms. In that case, the terms will never appear on the node create/edit form, or anywhere else on the site.

Drupal's node_access features dont cover create permissions. (user privileges do.) It's not clear to me that tac_lite can offer a feature for this that is safe for sites to use. In particular, I don't want one user to tag a node with certain terms, then have another user un-intentionally remove those terms when editing a node. This can happen if the second user cannot see the same terms. This can happen today - I may make changes to avoid that - I won't make changes that make it more likely.

For your case you can write a custom module that uses hook_form_alter to do what you want. If someone writes a good module that does this in conjunction with tac_lite, I'd consider adding tac_lite/contrib and placing it there.

#2

markDrupal - May 18, 2009 - 19:05

So it almost does exactly what I want, only change would be to restrict showing the user the term unless they have permission to edit those terms.

Any chance you could point me to the spot where I could patch your module to allow only users with the "edit" permission to use it? If you don't think it is possible, I'll try writing a custom module.

Here is my problem:

My site has a shared documents section where different departments can upload documents to their section, and edit others documents as long as they are in their department. So someone from the HR department can edit/delete any document in the HR section. Only problem is that anyone in any department, say IT department, can add a document to the HR section by using the taxonomy term "HR"

I don't want to hide all the HR documents from the IT guys, I just want to restrict access to add an HR document to only HR people.

#3

markDrupal - May 18, 2009 - 22:16
Status:won't fix» needs review

UPDATE---THIS VERSION IS OUTDATED---
I made a module that does this... attaching, guess I cant attach module files, so I'll just post the code here. Only known issue with this is if the user dosen't have access to update any term, and the term is required. But I guess in that case the user dosen't have access to post, maybe we should put in an access_denyed() instead of the node/add node/edit page in those situations.

START
tac_create.info

; $Id:$
name = Taxonomy Access Control Lite Create
description = Restrict Taxonomy selection on node add/edit forms to only terms the user can update
dependencies[] = tac_lite
core = 6.x

START
tac_create.module

<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

/**
* Implementation of hook_form_alter()
*/
function tac_create_form_alter(&$form, $form_state, $form_id) {
  if(
strpos($form_id, 'node_form') !== FALSE){
    global
$user;

    if (
user_access('administer tac_lite') || variable_get("tac_lite_config_create_restriction", 1) == 1) {
     
// no need to restrict based on update permission in these cases
     
return;
    }

   
// the vocabularies containing protected info.
   
$vids = variable_get('tac_lite_categories', array(0));

   
// the terms this user is allowed to edit
   
$tids = array();
    for (
$i = 1; $i <= variable_get('tac_lite_schemes', 1); $i++) {
     
$config = _tac_lite_config($i);
      if (
in_array('grant_update', $config['perms'])) {
       
$tids = array_merge($tids, _tac_lite_user_tids($user, $i));
      }
    }

    foreach((array)
$form['taxonomy'] as $vid => $data){
      if (!
is_numeric($vid) || !in_array($vid, $vids)){
        continue;
      }
      foreach(
$data['#options'] as $num => $term){
        if (!
is_numeric($num)){
          continue;
        }
        if(!
in_array(key($term->option), $tids)){
          unset(
$form['taxonomy'][$vid]['#options'][$num]);
        }
        if(
count($form['taxonomy'][$vid]['#options']) == 1){
          unset(
$form['taxonomy'][$vid]);
        }
      }
    }
  }
  elseif (
$form_id == 'tac_lite_admin_settings'){
   
$form["tac_lite_config_create_restriction"] = array(
     
'#type' => 'radios',
     
'#title' => t('General Usage based on'),
     
'#description' => t('Which permission should be used to limit the display of taxonomy terms when creating or editing a node? I.E. only users with this permission can create new nodes using that term.'),
     
'#options' => array(1 => 'View', 2 => 'Update'),
     
'#required' => TRUE,
     
'#default_value' => variable_get("tac_lite_config_create_restriction", 1),
     
'#weight' => -1,
    );
  }
}
?>

AttachmentSize
tac_create.info 186 bytes

#4

markDrupal - May 18, 2009 - 22:37

Ends up that didn't cut it for me.
I had to change it in order to allow for both wiki style, everyone-can-edit ,and normal blog style, only-creator-can-edit, permissions on creating new nodes while allowing restrictions to taxonomy terms that can be used in the node add/edit forms. I also added in the access denied when a user tries to create a node for which they have no update/create permissions for the required vocabulary

You can add in the 'Create" permission the same as any other permission after you enable this module

<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

/**
* Implementation of hook_form_alter()
*/
function tac_create_form_alter(&$form, $form_state, $form_id) {
  if(
strpos($form_id, 'node_form') !== FALSE){
    global
$user;

    if (
user_access('administer tac_lite')) {
     
// no need to restrict based on update permission in this cases
     
return;
    }

   
// the vocabularies containing protected info.
   
$vids = variable_get('tac_lite_categories', array(0));

   
// the terms this user is allowed to edit
   
$tids = array();
    for (
$i = 1; $i <= variable_get('tac_lite_schemes', 1); $i++) {
     
$config = _tac_lite_config($i);
      if (
in_array('grant_create', $config['perms']) || in_array('grant_update', $config['perms'])) {
       
$tids = array_merge($tids, _tac_lite_user_tids($user, $i));
      }
    }

    foreach((array)
$form['taxonomy'] as $vid => $data){
      if (!
is_numeric($vid) || !in_array($vid, $vids)){
       
//If not a vid, or not controled under TAC_lite
       
continue;
      }
      foreach(
$data['#options'] as $num => $term){
        if (!
is_numeric($num)){
          continue;
        }
        if(!
in_array(key($term->option), $tids)){
          unset(
$form['taxonomy'][$vid]['#options'][$num]);
        }
        if(
count($form['taxonomy'][$vid]['#options']) == 1){
          if(
$form['taxonomy'][$vid]['#required'] == TRUE){
          
drupal_set_message(t('You have no permissions to add content to the required %name vocabulary. Please contact the site administrator if you believe you should have permission to add content.', array('%name' => $form['taxonomy'][$vid]['#title'])));
          
drupal_access_denied();
           exit();
          }
          unset(
$form['taxonomy'][$vid]);
        }
      }
    }
  }
  elseif (
$form_id == 'tac_lite_admin_scheme_form'){
   
$scheme = $form['#parameters'][2];
    if (
$scheme === 1){
     
$config = variable_get('tac_lite_config_scheme_' . $scheme,
        array(
'name' => t('read and create'),
         
'perms' => array('grant_view', 'grant_create')));
    }
    else{
     
$config = variable_get('tac_lite_config_scheme_' . $scheme,
         array(
'name' => NULL, 'perms' => array()));
    }
   
$form["tac_lite_config_scheme_$scheme"]['perms']['#options']['grant_create'] = t("create");
   
$form["tac_lite_config_scheme_$scheme"]['perms']['#default_value'] = $config['perms'];
   
$form["tac_lite_config_scheme_$scheme"]['perms']['#description'] .= t(' The "create" permission does not override add * node permissions. It only adds restrictions on the useable taxonomy terms when creating or editing a node. "update" permission always implies "create" permission. Without "view" permission, "create", "update", and "delete" permissions are meaningless');
  }
}
?>

#5

markDrupal - May 28, 2009 - 23:33

Anyone want to test this out?
It is working good for me

#6

jaron - June 1, 2009 - 21:53

Would that apply to comments on a node as well? I'm having an issue where I'm using tac-lite with a forum to create private forums. The problem is that I'd like the forums and comments to be un-editable, meaning once they are posted, they are permanent. The create function on a node would handle the forum topic, but would the limitation also apply to comments on that topic? If so, I'd love to try it!

I should also mention I'm very new to Drupal, so any implementation advice would be helpful...not sure exactly what to do with all that code.
Thanks.

#7

markDrupal - June 1, 2009 - 23:12

In short, no, currently this makes no attempt to restrict comment postings.

But I believe it is possible to patch this module to add that functionality. Your best bet is to add a hook_comment or hook_nodeapi to this module and remove the comment box when users are lacking the 'create' permission :

http://api.drupal.org/api/function/hook_comment/6
http://api.drupal.org/api/function/hook_nodeapi/6

for nodeapi, you'd probably have to edit the $node variable during the "prepare" operation.
for commentapi, it looks like you could only remove the edit/delete links during the "view" operation. To remove the comment box entirely, my guess is to do it in the nodeapi 'prepare' op.

good luck. I can offer more help if you need it.
Mark

#8

markDrupal - June 1, 2009 - 23:14

In addition, you may be able to disallow editing comments if you change the permissions in the administration interface. But if you need more complex permissions based on Taxonomy, try patching this module

#9

jaron - June 2, 2009 - 16:17

Added it and it's working great. Much appreciated. I'll post if I encounter any issues. Thanks!

#10

Dave Cohen - June 2, 2009 - 19:19

I'm still pondering whether this really belongs in the module. I do see how it useful. But I also see that it

  • Adds overhead to every node form rendered by Drupal
  • Introduces potentially tricky issues

The tricky issues being... say I create a node and have full privileges for every term. You can edit the node, but cant create every term that I've tagged the node with. When you submit your changes, you also remove the terms I've tagged the node with.

Maybe this should be in its own module, say tac_lite_create.module, which people can enable at their own risk. Reasonable?

#11

jaron - June 2, 2009 - 19:36

That's actually how I added it in. I didn't change the tac_lite module. I'm also using very delineated use of taxonomy so the multiple terms issue wouldn't be a problem for me.
By the way, tac_lite is great. Thanks.

#12

markDrupal - June 2, 2009 - 19:44

I created it as it's own module that can be enabled if needed.

currently the name is tac_create, so create a subdirectory(within tac_lite) called tac_create and throw in the .info file and .module file

#13

markDrupal - June 2, 2009 - 20:16

@Dave
The other point you make about if a node has terms "ABC" and "XYZ" and I can edit(edit permission implies create) "ABC" but cannot edit or create "XYZ" it is true that the term "XYZ" will be removed from the node when the user resaves it.

question is
Since the user has no permissions to edit "XYZ" should this be allowed to happen? Shouldn't the user be required to have all the permissions to edit the node?

If your answer is no, you can fix it by changing

<?php
       
if(!in_array(key($term->option), $tids)){
          unset(
$form['taxonomy'][$vid]['#options'][$num]);
        }
?>

to

<?php
       
if(!in_array(key($term->option), $tids)){
          if(!
in_array(key($term->option), $form['taxonomy'][$vid]['#default_value'])){
            unset(
$form['taxonomy'][$vid]['#options'][$num]);
          }
        }
?>

Here is the new module/info file changing the name to tac_lite_create.module, tac_lite_create.info and the fix above

<?php
/**
* Implementation of hook_form_alter()
*/
function tac_lite_create_form_alter(&$form, $form_state, $form_id) {
  if(
strpos($form_id, 'node_form') !== FALSE){
    global
$user;

    if (
user_access('administer tac_lite')) {
     
// no need to restrict based on update permission in this cases
     
return;
    }

   
// the vocabularies containing protected info.
   
$vids = variable_get('tac_lite_categories', array(0));

   
// the terms this user is allowed to edit
   
$tids = array();
    for (
$i = 1; $i <= variable_get('tac_lite_schemes', 1); $i++) {
     
$config = _tac_lite_config($i);
      if (
in_array('grant_create', $config['perms']) || in_array('grant_update', $config['perms'])) {
       
$tids = array_merge($tids, _tac_lite_user_tids($user, $i));
      }
    }

    foreach((array)
$form['taxonomy'] as $vid => $data){
      if (!
is_numeric($vid) || !in_array($vid, $vids)){
       
//If not a vid, or not controled under TAC_lite
       
continue;
      }
      foreach(
$data['#options'] as $num => $term){
        if (!
is_numeric($num)){
          continue;
        }
        if(!
in_array(key($term->option), $tids)){
         
//if the taxonmy is selected, allow the user to use it
         
if(!in_array(key($term->option), $form['taxonomy'][$vid]['#default_value'])){
            unset(
$form['taxonomy'][$vid]['#options'][$num]);
          }
        }
        if(
count($form['taxonomy'][$vid]['#options']) == 1){
          if(
$form['taxonomy'][$vid]['#required'] == TRUE){
          
drupal_set_message(t('You have no permissions to add content to the required %name vocabulary. Please contact the site administrator if you believe you should have permission to add content.', array('%name' => $form['taxonomy'][$vid]['#title'])));
          
drupal_access_denied();
           exit();
          }
          unset(
$form['taxonomy'][$vid]);
        }
      }
    }
  }
  elseif (
$form_id == 'tac_lite_admin_scheme_form'){
   
$scheme = $form['#parameters'][2];
    if (
$scheme === 1){
     
$config = variable_get('tac_lite_config_scheme_' . $scheme,
        array(
'name' => t('read and create'),
         
'perms' => array('grant_view', 'grant_create')));
    }
    else{
     
$config = variable_get('tac_lite_config_scheme_' . $scheme,
         array(
'name' => NULL, 'perms' => array()));
    }
   
$form["tac_lite_config_scheme_$scheme"]['perms']['#options']['grant_create'] = t("create");
   
$form["tac_lite_config_scheme_$scheme"]['perms']['#default_value'] = $config['perms'];
   
$form["tac_lite_config_scheme_$scheme"]['perms']['#description'] .= t(' The "create" permission does not override add * node permissions. It only adds restrictions on the useable taxonomy terms when creating or editing a node. "update" permission always implies "create" permission.');
  }
}
?>

name = Taxonomy Access Control Lite Create
description = Restrict Taxonomy selection on node add/edit forms to only terms the user can create
dependencies[] = tac_lite
core = 6.x

#14

Dave Cohen - June 3, 2009 - 18:42

I'm OK with the files the way you've pasted them into code above. But for future reference you should learn how to create a patch. Patches are easier for maintainers to deal with.

As for the permission question, I don't know what most people would want or what is better. In Drupal, access control permissions are generally ORed together (rather than ANDed), so having one edit permission will let you edit a node, even if the node is tagged with terms you don't have permission to edit. On the other hand, if you have permission to edit a node but no privilege to use the node's input format you will be denied edit permission. So in a sense drupal has a precedent for both approaches. I'm inclined to the think the second user should be allowed to edit the node, and the hidden terms should either be lost, or preserved by the module without the user ever seeing them.

#15

streever - June 8, 2009 - 19:29

I've installed this, but my user (who has create selected) is unable to see that term.

Could there be a conflicting permission? Permissions are typically designed with AND, not OR, correct? So adding permission in one place should be enough?

Sorry, to clarify--when they click "Create Content", no terms show up for the vocabulary. At one point I had Tax Acc Control full, with the same error. Could that be in conflict with this? I DID re-build permissions to use Tax Lite.

#16

markDrupal - June 8, 2009 - 21:42

I don't think you should ever see an empty taxonomy box. If there are no terms available, it should error out with an access denied.

the create permission will not need to have the permissions rebuilt, they operate differently.

My guess is your user dosen't have the 'view' permission for that taxonomy term.
try to ensure the user can 'view' those taxonomy terms.

So if the user is missing the 'view' permission, the create permission cannot be used.

#17

streever - July 16, 2009 - 14:49

You are correct Mark: thank you so much! (Sorry for my late reply)

#18

norio - July 28, 2009 - 16:58

Thank you Mark & Dave! This new module + tac lite was exactly what I needed for a new site I'm putting together where a handful of authors are responsible for content in specific categories.

Thank you!

#19

2ndmile - September 8, 2009 - 02:21

subscribe

#20

johnpitcairn - September 13, 2009 - 22:52

Subscribing. Unsure whether we'll be using TAC lite to control view and edit/delete privileges (possibly just view), but if we do go with it for edit/delete control we'll need create control as well. Definitely not using TAC (full) for this because of the roles requirement, we'd need a ton of roles. Roles on their own may suffice for edit/delete/create however.

#21

guix - November 25, 2009 - 13:58

sub

#22

Oleksa - December 9, 2009 - 12:47

Very important feature for TAC lite.
But it looks that tac_lite_create does not work with forum. When user without create permissions for some term of forum, go to this term and above there is "create new forum topic" and user post topic to this (not allowed for him) term of forum.

UPD: module version tac_create from #4 works OK with forum terms

 
 

Drupal is a registered trademark of Dries Buytaert.