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

dev/core#61 Split Edit Message Templates Permission #11974

Conversation

ajesamson
Copy link
Contributor

@ajesamson ajesamson commented Apr 13, 2018

Overview

The edit message templates permission currently grants access to user-driven messages and system workflow message. The implication of this is that, there is no way of restricting a particular user to just user-driven messages or system workflow messages.

This PR adds 2 new granular permissions called edit user-driven message templates and edit system workflow message templates. This helps to further limit which of the templates a user can view and edit, while retaining exiting edit message templates permission for backward compability.

Before

before

After

after

Technical Details

New permissions were added to existing ones

      'edit system workflow message templates' => array(
        $prefix . ts('edit system workflow message templates'),
      ),
      'edit user-driven message templates' => array(
        $prefix . ts('edit user-driven message templates'),
      ),

and applied to message template urls.

<item>
     <path>civicrm/admin/messageTemplates</path>
     <title>Message Templates</title>
     <desc>Message templates allow you to save and re-use messages with layouts which you can use when sending email to one or more contacts.</desc>
     <page_callback>CRM_Admin_Page_MessageTemplates</page_callback>
     <adminGroup>Communications</adminGroup>
     <icon>admin/small/template.png</icon>
     <access_arguments>edit message templates;edit user-driven message templates;edit system workflow message templates</access_arguments>
     <weight>30</weight>
  </item>

Permission checks were applied on the view page, restricting tab access. Checks were also carried out while building the form to ensure users with one permission, does not edit forms belonging to other permission group.

  private function checkUserPermission($workflowId) {
    if (isset($workflowId)) {
      $canView = CRM_Core_Permission::check('edit system workflow message templates');
    } else {
      $canView = CRM_Core_Permission::check('edit user-driven message templates');
    }

    if (! $canView && ! CRM_Core_Permission::check('edit message templates')) {
      CRM_Core_Session::setStatus(ts('You do not have permission to view requested page.'), ts('Access Denied'));
      $url = CRM_Utils_System::url('civicrm/admin/messageTemplates', "reset=1");
      CRM_Utils_System::redirect($url);
    }
  }

For existing users to be aware of these changes, a pre-upgrade message notification was provided. This affords them the opportunity of deciding whether to upgrade existing user permissions or not.

if ($rev == '5.2.alpha1') {
  $params = array(
    1 => 'edit user-driven message templates',
    2 => 'edit system workflow message templates',
    3 => 'edit message templates',
  );
  $preUpgradeMessage .= '<p>' . ts('New granular permissions called %1 and %2 have been added for %3 permission. These permissions help to limit user access per template', $params) . '</p>';
}

@civicrm-builder
Copy link

Can one of the admins verify this patch?

@seamuslee001
Copy link
Contributor

Jenkins ok to test

@eileenmcnaughton
Copy link
Contributor

@mattwire perhaps you can trade with Compucorp to review one of yours? I know you want review on your membership tidy up one.

I think the idea of splitting up the permissions makes sense in principle. I'm a bit alarmed to see those php calls from the tpl file but I'm sure there are ample other places where we check permissions to compare to. If we really don't have an existing smarty permission check maybe we should add one in CRM_Core_Smarty_Plugins?

@@ -262,15 +262,15 @@
<page_callback>CRM_Admin_Page_MessageTemplates</page_callback>
<adminGroup>Communications</adminGroup>
<icon>admin/small/template.png</icon>
<access_arguments>edit message templates</access_arguments>
<access_arguments>edit message templates;edit user-driven message templates;edit system workflow message templates</access_arguments>
Copy link
Contributor

Choose a reason for hiding this comment

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

I see the xml sometimes uses commas & sometimes semi-colons - do they have the same meaning?

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 it’s the diff between or and I think ; == or , == and

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 Seamus is right

@ajesamson ajesamson force-pushed the 61-split-edit-message-templates-permission branch from 2665aa1 to 4766edc Compare April 16, 2018 10:13
Copy link
Contributor

@mickadoo mickadoo left a comment

Choose a reason for hiding this comment

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

looks pretty good overall, some minor comments

<li id='tab_user'> <a href='#user' title='{ts}User-driven Messages{/ts}'> {ts}User-driven Messages{/ts} </a></li>
<li id='tab_workflow'><a href='#workflow' title='{ts}System Workflow Messages{/ts}'>{ts}System Workflow Messages{/ts}</a></li>
{if $canEditUserDrivenMessageTemplates or $canEditMessageTemplates}
<li id='tab_user'> <a href='#user' title='{ts}User-driven Messages{/ts}'> {ts}User-driven Messages{/ts} </a></li>
Copy link
Contributor

Choose a reason for hiding this comment

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

I know it wasn't something you introduced, but can you remove the extra spaces here like in the second link below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright i will.

* @param int $workflowId
*/
private function checkUserPermission($workflowId) {
if (isset($workflowId)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not really familiar with message templates so just a question here, is it impossible for user driven message templates to have a workflow ID?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

User driven message templates do not have workflow ID. A template becomes system workflow message template the moment it has workflow ID.

@ajesamson ajesamson force-pushed the 61-split-edit-message-templates-permission branch from 4766edc to 3b23dae Compare April 16, 2018 11:56
Copy link
Contributor

@mickadoo mickadoo left a comment

Choose a reason for hiding this comment

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

Looks ok to me, it'll require someone (non compucorp) to review too though

@mickadoo
Copy link
Contributor

  • Explain (r-explain)
    • PASS : The goal/problem/solution have been adequately explained in the PR.
  • Test results (r-test)
    • UNREVIEWED
  • Code quality (r-code)
    • PASS: The functionality, purpose, and style of the code seems clear+sensible.
  • Documentation (r-doc)
    • UNREVIEWED
    • COMMENTS: Do you think this needs a documentation change @ajesamson?
  • Maintainability (r-maint)
    • UNREVIEWED
  • Run it (r-run)
    • UNREVIEWED
  • User impact (r-user)
    • UNREVIEWED

@eileenmcnaughton
Copy link
Contributor

test this please

@colemanw
Copy link
Member

@eileenmcnaughton

If we really don't have an existing smarty permission check maybe we should add one in CRM_Core_Smarty_Plugins?

I just looked into this because it's a very sensible suggestion, but the problem is that smarty functions can't be called from within {if} statements, as far as I can tell. So you can create a smarty function that behaves like this {crmCheck permission="administer CiviCRM"} but then how would you use it? I'm pretty sure you can't do {if {foo} } Conditional something {/if}

@colemanw
Copy link
Member

Hi @ajesamson thanks for this contribution. I'm just looking at it for the first time and my initial question is about whether the original permission indeed ought to be kept around. That seems needlessly confusing, as it will have significant overlap with the new permissions.

@eileenmcnaughton
Copy link
Contributor

@colemanw ah yeah - you'd need to add in a capture I suppose which starts to get a bit complex

@ajesamson
Copy link
Contributor Author

Hi @colemanw the reason why it was left behind is more or less for backward compatibility. It was meant to allow existing users with permission continue working without impacting their process on upgrade. Your suggestions are highly welcomed on how best to handle this.

@mattwire
Copy link
Contributor

@ajesamson I would have thought we could remove the old permission, making sure we add an upgrader message (there was one when batch permissions were added) telling the user that they will need to reconfigure permissions for message templates. The only other place it may cause a problem is if that permission is used in extensions, @totten normally says "grep universe" to find out.

@colemanw
Copy link
Member

I agree. As part of the upgrade, I think all users with the old permission should be granted the 2 new ones. And the upgrade message can give admins a heads up that they now have finer control if they want it.

@eileenmcnaughton
Copy link
Contributor

Do we actually have an effective methodology for adding permissions during upgrade?

@ajesamson
Copy link
Contributor Author

ajesamson commented May 8, 2018

@colemanw Please can you provide a guide on how best to migrate the old permission for existing users to 2 new ones. I have spent some time looking through the code base but could not get a method that provides easy access to CMS permission table for such upgrade.

The suggested sample code by @mattwire used setPreUpgradeMessage and left decision to the user. Also, i discovered there is another extension depending on edit message template after grep universe. It might be advisable to just add upgrade notification.

@eileenmcnaughton
Copy link
Contributor

@ajesamson @colemanw I think adding perms on upgrade across the CMS is too hard looking at it. I think historically we have set a message on upgrade & that will have to do

  /**
   * Compute any messages which should be displayed beforeupgrade.
   *
   * Note: This function is called iteratively for each upcoming
   * revision to the database.
   *
   * @param string $preUpgradeMessage
   * @param string $rev
   *   a version number, e.g. '4.4.alpha1', '4.4.beta3', '4.4.0'.
   * @param null $currentVer
   */
  public function setPreUpgradeMessage(&$preUpgradeMessage, $rev, $currentVer = NULL) {
    if ($rev == '4.7.alpha1') {
      // CRM-16478 Remove custom fatal error template path option
      $config = CRM_Core_Config::singleton();
      if (!empty($config->fatalErrorTemplate) && $config->fatalErrorTemplate != 'CRM/common/fatal.tpl') {
        $preUpgradeMessage .= '<p>' . ts('The custom fatal error template setting will be removed during the upgrade. You are currently using this custom template: %1 . Following the upgrade you will need to use the standard approach to overriding template files, as described in the documentation.', array(1 => $config->fatalErrorTemplate)) . '</p>';
      }
    }
    if ($rev == '4.7.alpha4') {
      // CRM-17004 Warn of Moneris removal
      $count = 1;
      // Query only works in 4.3+
      if (version_compare($currentVer, "4.3.0") > 0) {
        $count = CRM_Core_DAO::singleValueQuery("SELECT COUNT(id) FROM civicrm_payment_processor WHERE payment_processor_type_id IN (SELECT id FROM civicrm_payment_processor_type WHERE name = 'Moneris')");
      }
      if ($count && !function_exists('moneris_civicrm_managed')) {
        $preUpgradeMessage .= '<p>' . ts('The %1 payment processor is no longer bundled with CiviCRM. After upgrading you will need to install the extension to continue using it.', array(1 => 'Moneris')) . '</p>';
      }
    }
    if ($rev == '4.7.13') {
      $preUpgradeMessage .= '<p>' . ts('A new permission has been added called %1 This Permission is now used to control access to the Manage Tags screen', array(1 => 'manage tags')) . '</p>';
    }
    if ($rev == '4.7.22') {
      // Based on support inquiries for 4.7.21, show message during 4.7.22.
      // For affected users, this issue prevents loading the regular status screen.
      if (!$this->checkImageUploadDir()) {
        $preUpgradeMessage .= '<p>' . ts('There appears to be an inconsistency in the configuration of "Image Upload URL" and "Image Upload Directory".') . '</p>'
          . '<p>'
          . ts('Further advice will be displayed at the end of the upgrade.')
          . '</p>';
      }
    }
    if ($rev == '4.7.27') {
      $params = array(
        1 => 'Close accounting batches created by user',
        2 => 'Close all accounting batches',
        3 => 'Reopen accounting batches created by user',
        4 => 'Reopen all accounting batches',
        5 => 'https://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles',
      );
      $preUpgradeMessage .= '<p>' . ts('A new set of batch permissions has been added called "%1", "%2", "%3" and "%4". These permissions are now used to control access to the Accounting Batches tasks. If your users need to be able to Reopen or Close batches you may need to give them additional permissions. <a href=%5>Read more</a>', $params) . '</p>';
    }
    if ($rev == '4.7.32') {
      $preUpgradeMessage .= '<p>' . ts('A new %1 permission has been added. It is not granted by default. If you use SMS, you may wish to review your permissions.', array(1 => 'send SMS')) . '</p>';
    }
  }

Copy link
Contributor

@mickadoo mickadoo left a comment

Choose a reason for hiding this comment

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

re-approving after revision changes

@eileenmcnaughton
Copy link
Contributor

OK - I'm happy to go with @mickadoo's re-review on this. It seems to have been conceptually agreed & the code makes sense from a quick skim so I don't have any concerns over & above @mickadoo having tested /reviewed

@eileenmcnaughton eileenmcnaughton merged commit 40a732a into civicrm:master May 31, 2018
// if ($rev == '5.12.34') {
// $preUpgradeMessage .= '<p>' . ts('A new permission has been added called %1 This Permission is now used to control access to the Manage Tags screen', array(1 => 'manage tags')) . '</p>';
// }
if ($rev == '5.3.0') {
Copy link
Contributor

Choose a reason for hiding this comment

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

@eileenmcnaughton can you move this code into FiveThree.php

Copy link
Contributor

Choose a reason for hiding this comment

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

ah dang - didn't spot that!

@eileenmcnaughton
Copy link
Contributor

This appears to have caused a regression - see #12896

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.

7 participants