Merge pull request #6202 from jitendrapurohit/CRM-16823
[civicrm-core.git] / Civi / API / Subscriber / PermissionCheck.php
index f9fecfe5182778c28cf66d05c011c443810d9803..0b39d1d1fcd5db5b7a0c7999f1d19133219b7236 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 namespace Civi\API\Subscriber;
+
 use Civi\API\Events;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 /**
- * For any API requests that correspond to a Doctrine entity ($apiRequest['doctrineClass']), check
- * permissions specified in Civi\API\Annotation\Permission.
+ * For any API requests that correspond to a Doctrine entity
+ * ($apiRequest['doctrineClass']), check permissions specified in
+ * Civi\API\Annotation\Permission.
  */
 class PermissionCheck implements EventSubscriberInterface {
   /**
@@ -47,6 +49,7 @@ class PermissionCheck implements EventSubscriberInterface {
 
   /**
    * @param \Civi\API\Event\AuthorizeEvent $event
+   *   API authorization event.
    *
    * @throws \Civi\API\Exception\UnauthorizedException
    */
@@ -70,11 +73,12 @@ class PermissionCheck implements EventSubscriberInterface {
         return;
       }
 
-      if (!\CRM_Core_Permission::check($permissions)) {
+      if (!\CRM_Core_Permission::check($permissions) and !self::checkACLPermission($apiRequest)) {
         if (is_array($permissions)) {
           $permissions = implode(' and ', $permissions);
         }
-        // FIXME: Generating the exception ourselves allows for detailed error but doesn't play well with multiple authz subscribers.
+        // FIXME: Generating the exception ourselves allows for detailed error
+        // but doesn't play well with multiple authz subscribers.
         throw new \Civi\API\Exception\UnauthorizedException("API permission check failed for {$apiRequest['entity']}/{$apiRequest['action']} call; insufficient permission: require $permissions");
       }
 
@@ -82,4 +86,40 @@ class PermissionCheck implements EventSubscriberInterface {
       $event->stopPropagation();
     }
   }
+
+  /**
+   * Check API for ACL permission.
+   *
+   * @param array $apiRequest
+   *
+   * @return bool
+   */
+  public function checkACLPermission($apiRequest) {
+    switch ($apiRequest['entity']) {
+      case 'UFGroup':
+      case 'UFField':
+        $ufGroups = \CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
+        $aclCreate = \CRM_ACL_API::group(\CRM_Core_Permission::CREATE, NULL, 'civicrm_uf_group', $ufGroups);
+        $aclEdit = \CRM_ACL_API::group(\CRM_Core_Permission::EDIT, NULL, 'civicrm_uf_group', $ufGroups);
+        $ufGroupId = $apiRequest['entity'] == 'UFGroup' ? $apiRequest['params']['id'] : $apiRequest['params']['uf_group_id'];
+        if (in_array($ufGroupId, $aclEdit) or $aclCreate) {
+          return TRUE;
+        }
+        break;
+
+      //CRM-16777: Disable schedule reminder with ACLs.
+      case 'ActionSchedule':
+        $events = \CRM_Event_BAO_Event::getEvents();
+        $aclEdit = \CRM_ACL_API::group(\CRM_Core_Permission::EDIT, NULL, 'civicrm_event', $events);
+        $param = array('id' => $apiRequest['params']['id']);
+        $eventId = \CRM_Core_BAO_ActionSchedule::retrieve($param, $value = array());
+        if (in_array($eventId->entity_value, $aclEdit)) {
+          return TRUE;
+        }
+        break;
+    }
+
+    return FALSE;
+  }
+
 }