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

Add "priority" column to ACLs and support ACL rule precedence #26592

Merged
merged 2 commits into from
Jun 22, 2023

Conversation

seamuslee001
Copy link
Contributor

@seamuslee001 seamuslee001 commented Jun 21, 2023

Overview

This extends the work done by #26041 by adding in the concept of a priority to ACL rules. This allows for allow or deny rules to take precedence by the priority they are given.

Before

Deny rules always override allow rules without any real flexibility

After

Flexibility

ping @colemanw

@civibot
Copy link

civibot bot commented Jun 21, 2023

(Standard links)

FROM civicrm_acl_cache c, civicrm_acl a
WHERE c.acl_id = a.id
AND a.is_active = 1
AND a.object_table = %1
AND a.id IN ( $aclKeys )
AND a.deny = 1
GROUP BY a.operation,a.object_id
GROUP BY a.operation,a.object_id, a.weight
Copy link
Member

Choose a reason for hiding this comment

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

Why are you grouping by weight? I would think you would want to order by weight instead.

@@ -530,22 +530,37 @@ private static function loadDenyIDs(int $contactID, string $tableName, int $type
$aclKeys = array_keys($acls);
$aclKeys = implode(',', $aclKeys);
$query = "
SELECT a.operation, a.object_id
SELECT a.operation, a.object_id, a.weight
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little concerned about this query causing a crash in an upgrade situation when the column hasn't been added yet. DAO::getSupportedFields() is your friend.

@colemanw colemanw changed the title Add weight column to ACLs and support weighted ACL rules Add "priority" column to ACLs and support ACL rule precedence Jun 22, 2023
@@ -164,6 +165,7 @@ public function buildQuickForm() {
0 => ts('Allow'),
1 => ts('Deny'),
]);
$this->add('text', 'priority', ts('Priority'));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
$this->add('text', 'priority', ts('Priority'));
$this->add('number', 'priority', ts('Priority'));

@@ -31,6 +31,7 @@
<th>{ts}Description{/ts}</th>
<th>{ts}Enabled?{/ts}</th>
<th>{ts}Mode{/ts}</th>
<th>{ts}Weight{/ts}</th>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<th>{ts}Weight{/ts}</th>
<th>{ts}Priority{/ts}</th>

@@ -28,6 +28,7 @@ class CRM_Upgrade_Incremental_php_FiveSixtyFour extends CRM_Upgrade_Incremental_
* The version number matching this function name
*/
public function upgrade_5_64_alpha1($rev): void {
$this->addTask('Add weight column onto ACL table', 'addColumn', 'civicrm_acl', 'priority', 'int NOT NULL DEFAULT 0');
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
$this->addTask('Add weight column onto ACL table', 'addColumn', 'civicrm_acl', 'priority', 'int NOT NULL DEFAULT 0');
$this->addTask('Add priority column onto ACL table', 'addColumn', 'civicrm_acl', 'priority', 'int NOT NULL DEFAULT 0');

Add in upgrade step

Rename field to be priority and add in upgrade guards as per Coleman

Updates as per discussion with coleman
$orderBy = 'a.object_id';
$hasPriorty = FALSE;
if (array_key_exists('priority', CRM_ACL_BAO_ACL::getSupportedFields())) {
$select .= ',a.priority';
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this needs to be selected.

if (array_key_exists('priority', CRM_ACL_BAO_ACL::getSupportedFields())) {
$select .= ',a.priority';
$orderBy .= ',a.priority';
$hasPriority = TRUE;
Copy link
Member

Choose a reason for hiding this comment

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

Unused variable?

@colemanw
Copy link
Member

Ok great, this has passed review and tests are passing.

@colemanw colemanw merged commit 7eb8afe into civicrm:master Jun 22, 2023
@seamuslee001 seamuslee001 deleted the acl_rule_weight branch July 8, 2023 00:44
@TobiasVoigt
Copy link

Hi there,

today I tested the newest implementation of the weighting functionality in CiviCRM 5.65.0 and found that I wasn't able to set up my initial usecase due to what seems to be a bug.

My usecase included three ACLs:

ACL rule 1: Allow access to all custom field groups for all authenticated users → Priority 1
ACL rule 2: Disallow access to the privileged set of custom fields for all authenticated users → Priority 2
ACL rule 3: Allow access to the privileged set of custom fields for a privileged role → Priority 3

I used the new weighting functionality but didn't get the results I expected. I expected that priority 3 would have precedence over 2 (and 2 over 1), in other words: The higher the number, the higher the priority. But with this setup all users where able to access all custom fields.

I then made some tests and realized:

  1. When I create a test setup with several rules that all refer to ONE SPECIFIC custom field group the weighting logic works like I expected: The higher number has the priority.
  2. When I create a test setup with several rules that all refer to ALL custom field groups, the weighting logic seems to be flipped: The smaller number has the higher priority.

So my guess is that somewhere in the ACL code the weighting logic is somehow flipped for "All custom field groups". This would explain why mixing rules for "All custom field groups" and rules for specific custom field groups in my test setup didn't work.

To my regret, this means I won't be able to show the new functionality to a live audience at CiviCamp in Leipzig next monday (2023-09-11). If there's any chance someone would be able to deliver a quick fix that would be absolutely awesome.

In any case - I hope my analysis makes sense and shed some light onto a potential bug. Let me know! :)

Best regards,

Tobias

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.

3 participants