'edit all contacts',
),
'getquick' => array(
- 'access CiviCRM',
+ array('access CiviCRM', 'access AJAX API'),
),
);
}
/**
- * given a permission string, check for access requirements
+ * given a permission string or array, check for access requirements
+ * @param mixed $permissions the permission to check as an array or string -see examples
+ * arrays
*
- * @param string $str the permission to check
+ * Ex 1
+ *
+ * Must have 'access CiviCRM'
+ * (string) 'access CiviCRM'
+ *
+ *
+ * Ex 2 Must have 'access CiviCRM' and 'access Ajax API'
+ * array('access CiviCRM', 'access Ajax API')
+ *
+ * Ex 3 Must have 'access CiviCRM' or 'access Ajax API'
+ * array(
+ * array('access CiviCRM', 'access Ajax API'),
+ * ),
+ *
+ * Ex 4 Must have 'access CiviCRM' or 'access Ajax API' AND 'access CiviEvent'
+ * array(
+ * array('access CiviCRM', 'access Ajax API'),
+ * 'access CiviEvent',
+ * ),
+ *
+ * Note that in permissions.php this is keyed by the action eg.
+ * (access Civi || access AJAX) && (access CiviEvent || access CiviContribute)
+ * 'myaction' => array(
+ * array('access CiviCRM', 'access Ajax API'),
+ * array('access CiviEvent', 'access CiviContribute')
+ * ),
*
* @return boolean true if yes, else false
* @static
* @access public
*/
- static function check($str) {
- $config = CRM_Core_Config::singleton();
- return $config->userPermissionClass->check($str);
+ static function check($permissions) {
+ $permissions = (array) $permissions;
+
+ foreach ($permissions as $permission) {
+ if(is_array($permission)) {
+ foreach ($permission as $orPerm) {
+ if(self::check($orPerm)) {
+ //one of our 'or' permissions has succeeded - stop checking this permission
+ return TRUE;;
+ }
+ }
+ //none of our our conditions was met
+ return FALSE;
+ }
+ else {
+ if(!CRM_Core_Config::singleton()->userPermissionClass->check($permission)) {
+ //one of our 'and' conditions has not been met
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
}
/**
* @param $entity string API entity being accessed
* @param $action string API action being performed
* @param $params array params of the API call
- * @param $throw bool whether to throw exception instead of returning false
+ * @param $throw deprecated bool whether to throw exception instead of returning false
*
* @throws Exception
* @return bool whether the current API user has the permission to make the call
return TRUE;
}
- foreach ($permissions as $perm) {
- if (!CRM_Core_Permission::check($perm)) {
- if ($throw) {
- throw new Exception("API permission check failed for $entity/$action call; missing permission: $perm.");
- }
- else {
- return FALSE;
+ if (!CRM_Core_Permission::check($permissions)) {
+ if ($throw) {
+ if(is_array($permissions)) {
+ $permissions = implode(' and ', $permissions);
}
+ throw new Exception("API permission check failed for $entity/$action call; insufficient permission: require $permissions");
+ }
+ else {
+ //@todo remove this - this is an internal api function called with $throw set to TRUE. It is only called with false
+ // in tests & that should be tidied up
+ return FALSE;
}
}
+
return TRUE;
}
$config = CRM_Core_Config::singleton();
$config->userPermissionClass->permissions = array('access CiviCRM');
$result = $this->callAPIFailure('contact', 'create', $params);
- $this->assertEquals('API permission check failed for contact/create call; missing permission: add contacts.', $result['error_message'], 'lacking permissions should not be enough to create a contact');
+ $this->assertEquals('API permission check failed for contact/create call; insufficient permission: require access CiviCRM and add contacts', $result['error_message'], 'lacking permissions should not be enough to create a contact');
$config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
$result = $this->callAPISuccess('contact', 'create', $params, NULL, 'overfluous permissions should be enough to create a contact');
$config->userPermissionClass->permissions = array('access CiviCRM');
$result = $this->callAPIFailure('contact', 'update', $params);
- $this->assertEquals('API permission check failed for contact/update call; missing permission: edit all contacts.', $result['error_message'], 'lacking permissions should not be enough to update a contact');
+ $this->assertEquals('API permission check failed for contact/update call; insufficient permission: require access CiviCRM and edit all contacts', $result['error_message'], 'lacking permissions should not be enough to update a contact');
$config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'view all contacts', 'edit all contacts', 'import contacts');
$result = $this->callAPISuccess('contact', 'update', $params, NULL, 'overfluous permissions should be enough to update a contact');
$result = $this->callAPISuccess('contact', 'proximity', $proxParams);
$this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
}
+
+ /**
+ * Test that Ajax API permission is suffient to access quicksearch api
+ * (note that quicksearch api is required for autocomplete & has ACL permissions applied)
+ */
+ function testQuickSearchPermission_CRM_13744() {
+ CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviEvent');
+ $result = $this->callAPIFailure('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
+ CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
+ $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
+ CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access AJAX API');
+ $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
+ }
}
$config = &CRM_Core_Config::singleton();
$config->userPermissionClass->permissions = array('access CiviCRM');
$result = $this->callAPIFailure('event', 'create', $params);
- $this->assertEquals('API permission check failed for event/create call; missing permission: access CiviEvent.', $result['error_message'], 'lacking permissions should not be enough to create an event');
+ $this->assertEquals('API permission check failed for event/create call; insufficient permission: require access CiviCRM and access CiviEvent and edit all events', $result['error_message'], 'lacking permissions should not be enough to create an event');
$config->userPermissionClass->permissions = array('access CiviEvent', 'edit all events', 'access CiviCRM');
$result = $this->callAPISuccess('event', 'create', $params);
catch(Exception $e) {
$message = $e->getMessage();
}
- $this->assertEquals($message, 'API permission check failed for contact/create call; missing permission: add contacts.', 'lacking permissions should throw an exception');
+ $this->assertEquals($message, 'API permission check failed for contact/create call; insufficient permission: require access CiviCRM and add contacts', 'lacking permissions should throw an exception');
$config->userPermissionClass->permissions = array('access CiviCRM', 'add contacts', 'import contacts');
$this->assertTrue(_civicrm_api3_api_check_permission('contact', 'create', $check), 'overfluous permissions should return true');