CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • ACL Hook Automatically Gives Edit Permission
Pages: [1]

Author Topic: ACL Hook Automatically Gives Edit Permission  (Read 1380 times)

bpmccain

  • I post frequently
  • ***
  • Posts: 255
  • Karma: 5
  • CiviCRM version: 4.1
  • CMS version: Drupal 7.12
  • MySQL version: 5.2
  • PHP version: 5.2
ACL Hook Automatically Gives Edit Permission
August 16, 2011, 09:29:19 am
This is a follow on from this
http://forum.civicrm.org/index.php/topic,21126.0.htm

but I thought I would start a new topic since this is a slightly different issue (potential bug?)

I have successfully implemented the aclWhereClause hook the restrict a user to a certain subset of contacts (based on a custom field in both the user and contacts). The user has the following drupal privileges:
Profile View
Access All Custom Data
Access CiviContribute
Access CiviMail
Access CiviMember
Access CiviReport
Access CiviCRM
Access Contact Dashboard

When the user logs in, they can search for contacts, but the only results are the ones that are displayed are those that the user has permission to access. The only problem is that the user has the ability to EDIT all of these contacts which I want to restrict.

So I made two ACLs using the UI.
1) "Users with Edit Permission" (Role) can "Edit" (Operation) can edit "All Groups" (Data).
2) "Users with View Permission" (Role) can "View" (Operation) can edit "All Groups" (Data).

I put my user in the 'Users with View Permission' and logged in again. This time, when the search results are displayed, there is only a View label on the right hand side of each contact, instead of View | Edit which I had before - so it looks like it is working. However, if I click on any contacts name, I am presented with their contact summary and an EDIT button at the top allowing me to edit.

As a test, I created another user, gave them the same drupal permissions, and put them in the same 'Users with View Permission' group. I didn't assign them a custom field limiting them to a subset of contacts, so the aclWhereClause hook doesn't do anything with this user. I can now view all the contacts in the database, but the edit button doesn't appear anywhere.

So it seems that the aclWhereClause hook overrides my UI ACL to restrict the user to View Only - and I have no idea how to solve this. I know the aclWhereClause has a $type that dictates what permission level the user must have, but I have no idea where it checks the type against a logged in users permission level.

This is an absolutely essential part of my implementation. We could have several hundred users, and I need to be able to restrict them to being able to view only the contacts in one of a over a hundred groups. Using the UI ACL interface to do this will be too cumbersome.

Any thoughts?

If it is a bug, I am sure I could get some funding to help with the solution.

Brian


Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: ACL Hook Automatically Gives Edit Permission
August 16, 2011, 09:37:49 am

what happens when u click on the edit button? does it take u to the edit page?

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

bpmccain

  • I post frequently
  • ***
  • Posts: 255
  • Karma: 5
  • CiviCRM version: 4.1
  • CMS version: Drupal 7.12
  • MySQL version: 5.2
  • PHP version: 5.2
Re: ACL Hook Automatically Gives Edit Permission
August 16, 2011, 10:18:42 am
Yes it does. And I am able to make changes and save them to the db.

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: ACL Hook Automatically Gives Edit Permission
August 16, 2011, 02:22:30 pm

can you cut-n-paste your hook code on the forum. Please simplify it to as small a function as needed

thanx

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

bpmccain

  • I post frequently
  • ***
  • Posts: 255
  • Karma: 5
  • CiviCRM version: 4.1
  • CMS version: Drupal 7.12
  • MySQL version: 5.2
  • PHP version: 5.2
Re: ACL Hook Automatically Gives Edit Permission
August 16, 2011, 05:48:51 pm
Thanks Lobo - I think I have simplified it as much as I can without taking anything away from the operation of the hook. Love to hear what you think.

Code: [Select]
<?php

// Restrict the list of contacts that logged in users are able to view
function nbla_hooks_civicrm_aclWhereClause( $type, &$tables, &$whereTables, &$contactID, &$where ) {

// Table tracking custom permissions
$permissionTable = "civicrm_value_permissions";

// Table tracking custom constituent info
$groupTable = "civicrm_value_regions";

// List of different geographic permission types
$permissionFieldsType = array( 'provincial_riding' => 'Integer',
                     
'commission' => 'Integer');
$permissionFields = array( 'provincial_riding',
                     
'commission');

// List of different geographic trackers  
$groupFields = array( 'official_provincial_riding',
                     
'commissions');

// Find the values association with the different permission types
$keys = implode( ', ', array_keys( $permissionFieldsType ) );
  
$sql = "SELECT $keys FROM {$permissionTable} WHERE  entity_id = $contactID";

        
$dao = CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );

        if ( ! 
$dao->fetch( ) ) {
            return;
        }

// Join the necessary tables to execute query
        
$tables[$groupTable] = $whereTables[$groupTable] = "LEFT JOIN {$groupTable} groupTable ON contact_a.id = groupTable.entity_id";

// Create search clauses based on permissions
        
$clauses = array( );
        foreach( 
$permissionFieldsType as $field => $fieldType ) {
            
$i = 0;
    if ( ! empty( $dao->$field ) ) {
                if ( 
strpos( CRM_Core_DAO::VALUE_SEPARATOR, $dao->$field ) !== false ) {
                    
$value = substr( $dao->$field, 1, -1 );
                    
$values = explode( CRM_Core_DAO::VALUE_SEPARATOR, $value );
                    foreach ( 
$values as $v ) {
        $clauses[] = "groupTable.{$groupFields[$i]} = $v";
                    }
                } 
                else {
            
    $clauses[] = "groupTable.{$groupFields[$i]} = '{$dao->$field}'";
                }
            }
    $i++;
        }

// Turn clause into where statement
if ( ! empty( $clauses ) ) {
            if ( ! empty( 
$where ) ) {
                
$where .= ' AND '.implode( ' OR ', $clauses ).'';
    
    }
    else {
        $where .= ' '.implode( ' OR ', $clauses ).'';
    }
}
}

bpmccain

  • I post frequently
  • ***
  • Posts: 255
  • Karma: 5
  • CiviCRM version: 4.1
  • CMS version: Drupal 7.12
  • MySQL version: 5.2
  • PHP version: 5.2
Re: ACL Hook Automatically Gives Edit Permission
August 18, 2011, 10:46:07 am
Sometimes, after days and days of trying to debug complex problems, a solution pops into your head so simple that you wonder how you never thought of it.

This was one of those times.

Enclose everything inside of the hook in (drum roll please):
Code: [Select]
if ($type == 2){
}

This will then only run when the hook is called with type = 2, which is View. When it is called with type = 1, checking for permission for edit, it will not find any contacts as the where statement is not amended.

I can change the IF statement to run based on a custom field using the API, so I can now completely control VIEW / EDIT permissions from within the UI using the aclWhereClause hook.

I think this should go in the documentation, and I'll do a blog post about it, as I think it is a fairly useful example that isn't documented anywhere.

Thanks for all the help along the way. Problem SOLVED!
« Last Edit: August 18, 2011, 01:16:42 pm by bpmccain »

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: ACL Hook Automatically Gives Edit Permission
August 18, 2011, 01:51:48 pm

thanx for posting, i was just starting to reproduce and figure this one out.

yes, if you could blog about the process and update the wiki docs that would be great and highly appreciated

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • ACL Hook Automatically Gives Edit Permission

This forum was archived on 2017-11-26.