Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRM-19494 Refactoring of permission code #9229

Closed
wants to merge 15 commits into from

Conversation

bjendres
Copy link
Contributor

@bjendres bjendres commented Oct 12, 2016

Contains:

  • refactoring of CRM_Contact_BAO_Contact_Permission
  • tests
  • bugfixes for existing code
  • fix for CRM-12645

With the fix for CRM-12645 this should replace #9193.


@seamuslee001
Copy link
Contributor

@systopia can you please fix the style errors found here https://test.civicrm.org/job/CiviCRM-Core-PR/12167/checkstyleResult/new/

@bjendres
Copy link
Contributor Author

@systopia can you please fix the style errors found here https://test.civicrm.org/job/CiviCRM-Core-PR/12167/checkstyleResult/new/

@seamuslee001 done. thanks.

Copy link
Contributor

@eileenmcnaughton eileenmcnaughton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked at this code as far as Relationship - am going to try to mainline coffee & face that function

// empty contact lists would cause trouble in the SQL. And be pointless.
return $result_set;
}
$contact_id_list = implode(',', $contact_ids);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivial point - but this might be better after the 'early return' for 'edit all contacts' etc


// get logged in user
$session = CRM_Core_Session::singleton();
$contactID = (int) $session->get('userID');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferred function here is $contactID = CRM_Core_Session::getLoggedInUser()

it saves a whole line!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do (found out it's ::getLoggedInContactID(), just in case anybody wonders)

$tables = array();
$whereTables = array();
// get logged in user
$session = CRM_Core_Session::singleton();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto about the preferred function - saves 3 lines here as the function name should be clear enough to justify dropping the comment line :-)

$contactID = (int) $session->get('userID');

// first: check if contact is trying to view own contact
if ($type == CRM_Core_Permission::VIEW && CRM_Core_Permission::check('view my contact')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DIdn't we decide this should be

$type == CRM_Core_Permission::VIEW && (CRM_Core_Permission::check('view my contact') || CRM_Core_Permission::check('edit my contact'))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to not do that for 'view/edit my contact', there might be scenarios where people should be able to e.g. set a flag to their contact without seeing all data....

@@ -60,13 +158,16 @@ public static function allow($id, $type = CRM_Core_Permission::VIEW) {
return TRUE;
}

//check permission based on relationship, CRM-2963
// check permission based on relationship, CRM-2963
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we are being fussy it's supposed to be a capital letter & a full stop at the end....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I think I don't comply with that in any comment. Ignore it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well I can't standover you & deny you coffee now so we will have to :-)

@@ -99,7 +202,8 @@ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force
}

if (!$force) {
if (!empty($_processed[$userID])) {
// skip if already calculated
if (!empty($_processed[$type][$userID])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to do a select from the table to check there are entries for the user id - I'm worried the cache could be truncated from out of under someone

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, but that might have a big impact on performance. Maybe we should investigate how often it's called...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't change now, since this is also the existing approach. But I added a FIXME comment

@@ -125,6 +229,7 @@ public static function cache($userID, $type = CRM_Core_Permission::VIEW, $force

$from = CRM_Contact_BAO_Query::fromClause($whereTables);

// FIXME: don't use 'ON DUPLICATE KEY UPDATE'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I should push a fix for this up & get it in the same release

// get the currently logged in user
$config = CRM_Core_Config::singleton();
$session = CRM_Core_Session::singleton();
$contactID = (int) $session->get('userID');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto about using getLoggedInUser

}

// get the currently logged in user
$config = CRM_Core_Config::singleton();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are only using this for one purpose you can also do
$useSecondDegreeUserPermissions = CRM_Core_Config::singleton()->secondDegRelPermissions

Copy link
Contributor

@eileenmcnaughton eileenmcnaughton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK - I just have the test class still to read

}

$queries[] = "
SELECT DISTINCT(second_degree_relationship.contact_id_{$second_direction['to']}) AS contact_id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong but I don't think you need distinct here because the UNION will distinct it all

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed SELECT DISTINCT and used UNION DISTINCT, although that was the default for UNION anyway

while ($result->fetch()) {
$result_set[(int) $result->contact_id] = TRUE;
}
$keys = array_keys($result_set);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line seems redundant

$query = "(" . implode(")\nUNION (", $queries) . ")";
$result = CRM_Core_DAO::executeQuery($query);
while ($result->fetch()) {
$result_set[(int) $result->contact_id] = TRUE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be tempted to skip this loop & do

$query = "SELECT GROUP_CONCAT contact_id FROM ( $query ) as q";
return explode(',', CRM_Core_DAO::singleValueQuery($query));

My guess is more work on mysql & less on php is better

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be dangerous for large sets of contacts...

$keys = array_keys($result_set);
return array_keys($result_set);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why didn't jenkins bite you on the double line

@@ -33,6 +33,96 @@
class CRM_Contact_BAO_Contact_Permission {

/**
* Check which of the given contact IDs the logged in user
* has permissions for the operation type according
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to what ... the suspense

// create test contacts
$contacts = $this->createScenarioPlain();

// test WITH all permissions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need to state that NULL has that effect

$this->assertEquals($result, $contacts, "Contacts should be viewable when 'view all contacts'");

// test WITH explicit permission
CRM_Core_Config::singleton()->userPermissionClass->permissions = array('view all contacts');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a check for edit all contacts can view all contacts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea.

 - style
 - extra test
 - documentation
 - FIXME remarks
@eileenmcnaughton
Copy link
Contributor

@systopia We should close this or #9246 -I've given you permission to push to my github repo if you want to use #9246

I believe that one is working now - but it would be good if you would recheck. I think I'd like to merge it shortly AFTER 4.7.13 is forked

@monishdeb
Copy link
Member

Closing this in favor of #9246

@monishdeb monishdeb closed this Oct 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants