From 3efe22a0207c505a6a420c96251e2a6b3822ee90 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 27 Feb 2015 18:38:57 -0700 Subject: [PATCH] CRM-15854 - Fix previews for user without 'create mailings' --- CRM/Mailing/BAO/Mailing.php | 27 +++++++++++++++++++++++++++ api/v3/Mailing.php | 25 +++++++++++-------------- js/angular-crmMailing/services.js | 30 +++++++++++++++++++----------- 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/CRM/Mailing/BAO/Mailing.php b/CRM/Mailing/BAO/Mailing.php index 946558d301..998a4d74bb 100644 --- a/CRM/Mailing/BAO/Mailing.php +++ b/CRM/Mailing/BAO/Mailing.php @@ -3132,4 +3132,31 @@ AND m.id = %1 return civicrm_api('MailingContact', 'getcount', $params); } + /** + * Get a list of permissions required for CRUD'ing each field + * (when workflow is enabled). + * + * @return array + * Array (string $fieldName => string $permName) + */ + public static function getWorkflowFieldPerms() { + $fieldNames = array_keys(CRM_Mailing_DAO_Mailing::fields()); + $fieldPerms = array(); + foreach ($fieldNames as $fieldName) { + if ($fieldName == 'id') { + $fieldPerms[$fieldName] = 'access CiviMail'; + } + if (in_array($fieldName, array('scheduled_date', 'scheduled_id'))) { + $fieldPerms[$fieldName] = 'schedule mailings'; + } + elseif (in_array($fieldName, array('approval_date', 'approver_id', 'approval_status_id', 'approval_note'))) { + $fieldPerms[$fieldName] = 'approve mailings'; + } + else { + $fieldPerms[$fieldName] = 'create mailings'; + } + } + return $fieldPerms; + } + } diff --git a/api/v3/Mailing.php b/api/v3/Mailing.php index d97176c1e7..46a808a98b 100755 --- a/api/v3/Mailing.php +++ b/api/v3/Mailing.php @@ -44,22 +44,19 @@ */ function civicrm_api3_mailing_create($params) { if (CRM_Mailing_Info::workflowEnabled()) { - if (!CRM_Core_Permission::check('create mailings')) { - throw new \Civi\API\Exception\UnauthorizedException("This system uses advanced CiviMail workflows which require additional permissions"); - } - if (!CRM_Core_Permission::check('schedule mailings')) { - unset($params['scheduled_date']); - unset($params['scheduled_id']); - } - if (!CRM_Core_Permission::check('approve mailings')) { - unset($params['approval_date']); - unset($params['approver_id']); - unset($params['approval_status_id']); - unset($params['approval_note']); + $safeParams = array(); + $fieldPerms = CRM_Mailing_BAO_Mailing::getWorkflowFieldPerms(); + foreach (array_keys($params) as $field) { + if (CRM_Core_Permission::check($fieldPerms[$field])) { + $safeParams[$field] = $params[$field]; + } } } - $params['_evil_bao_validator_'] = 'CRM_Mailing_BAO_Mailing::checkSendable'; - return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params); + else { + $safeParams = $params; + } + $safeParams['_evil_bao_validator_'] = 'CRM_Mailing_BAO_Mailing::checkSendable'; + return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $safeParams); } /** diff --git a/js/angular-crmMailing/services.js b/js/angular-crmMailing/services.js index f2669367f6..deafdc5b64 100644 --- a/js/angular-crmMailing/services.js +++ b/js/angular-crmMailing/services.js @@ -262,17 +262,25 @@ // @param mailing Object (per APIv3) // @return Promise an object with "subject", "body_text", "body_html" preview: function preview(mailing) { - var params = angular.extend({}, mailing, mailing.recipients, { - options: {force_rollback: 1}, - 'api.Mailing.preview': { - id: '$value.id' - } - }); - delete params.recipients; // the content was merged in - return crmApi('Mailing', 'create', params).then(function (result) { - // changes rolled back, so we don't care about updating mailing - return result.values[result.id]['api.Mailing.preview'].values; - }); + if (CRM.crmMailing.workflowEnabled && !CRM.checkPerm('create mailings')) { + return crmApi('Mailing', 'preview', {id: mailing.id}).then(function(result) { + return result.values; + }); + } + else { + // Protect against races in saving and previewing by chaining create+preview. + var params = angular.extend({}, mailing, mailing.recipients, { + options: {force_rollback: 1}, + 'api.Mailing.preview': { + id: '$value.id' + } + }); + delete params.recipients; // the content was merged in + return crmApi('Mailing', 'create', params).then(function(result) { + // changes rolled back, so we don't care about updating mailing + return result.values[result.id]['api.Mailing.preview'].values; + }); + } }, // @param mailing Object (per APIv3) -- 2.25.1