Example #1
0
/**
 * Decide what permissions to check for an api call
 * The contact must have all of the returned permissions for the api call to be allowed
 *
 * @param $entity: (str) api entity
 * @param $action: (str) api action
 * @param $params: (array) api params
 *
 * @return array of permissions to check for this entity-action combo
 */
function _civicrm_api3_permissions($entity, $action, &$params)
{
    $entity = _civicrm_api_get_entity_name_from_camel($entity);
    $action = strtolower($action);
    /**
     * @var array of permissions
     *
     * For each entity, we declare an array of permissions required for each action
     * The action is the array key, possible values:
     *  * create: applies to create (with no id in params)
     *  * update: applies to update, setvalue, create (with id in params)
     *  * get: applies to getcount, getsingle, getvalue and other gets
     *  * delete: applies to delete, replace
     *  * meta: applies to getfields, getoptions, getspec
     *  * default: catch-all for anything not declared
     *
     *  Note: some APIs declare other actions as well
     */
    $permissions = array();
    // These are the default permissions - if any entity does not declare permissions for a given action,
    // (or the entity does not declare permissions at all) - then the action will be used from here
    $permissions['default'] = array('meta' => array('access CiviCRM'), 'default' => array('administer CiviCRM'));
    // Contact permissions
    $permissions['contact'] = array('create' => array('access CiviCRM', 'add contacts'), 'delete' => array('access CiviCRM', 'delete contacts'), 'get' => array(), 'update' => array('access CiviCRM', 'edit all contacts'), 'getquick' => array(array('access CiviCRM', 'access AJAX API')));
    // Contact-related data permissions
    $permissions['address'] = array('get' => array('access CiviCRM', 'view all contacts'), 'delete' => array('access CiviCRM', 'delete contacts'), 'default' => array('access CiviCRM', 'edit all contacts'));
    $permissions['email'] = $permissions['address'];
    $permissions['phone'] = $permissions['address'];
    $permissions['website'] = $permissions['address'];
    $permissions['im'] = $permissions['address'];
    $permissions['loc_block'] = $permissions['address'];
    $permissions['entity_tag'] = $permissions['address'];
    $permissions['note'] = $permissions['address'];
    // Activity permissions
    $permissions['activity'] = array('delete' => array('access CiviCRM', 'delete activities'), 'default' => array('access CiviCRM', 'view all activities'));
    // Case permissions
    $permissions['case'] = array('create' => array('access CiviCRM', 'add cases'), 'delete' => array('access CiviCRM', 'delete in CiviCase'), 'default' => array('access CiviCRM', 'access all cases and activities'));
    // Financial permissions
    $permissions['contribution'] = array('get' => array('access CiviCRM', 'access CiviContribute'), 'delete' => array('access CiviCRM', 'access CiviContribute', 'delete in CiviContribute'), 'completetransaction' => array('edit contributions'), 'default' => array('access CiviCRM', 'access CiviContribute', 'edit contributions'));
    $permissions['line_item'] = $permissions['contribution'];
    // Custom field permissions
    $permissions['custom_field'] = array('default' => array('administer CiviCRM', 'access all custom data'));
    $permissions['custom_group'] = $permissions['custom_field'];
    // Event permissions
    $permissions['event'] = array('create' => array('access CiviCRM', 'access CiviEvent', 'edit all events'), 'delete' => array('access CiviCRM', 'access CiviEvent', 'delete in CiviEvent'), 'get' => array('access CiviCRM', 'access CiviEvent', 'view event info'), 'update' => array('access CiviCRM', 'access CiviEvent', 'edit all events'));
    // File permissions
    $permissions['file'] = array('default' => array('access CiviCRM', 'access uploaded files'));
    $permissions['files_by_entity'] = $permissions['file'];
    // Group permissions
    $permissions['group'] = array('get' => array('access CiviCRM'), 'default' => array('access CiviCRM', 'edit groups'));
    $permissions['group_contact'] = $permissions['group'];
    $permissions['group_nesting'] = $permissions['group'];
    $permissions['group_organization'] = $permissions['group'];
    // Membership permissions
    $permissions['membership'] = array('get' => array('access CiviCRM', 'access CiviMember'), 'delete' => array('access CiviCRM', 'access CiviMember', 'delete in CiviMember'), 'default' => array('access CiviCRM', 'access CiviMember', 'edit memberships'));
    $permissions['membership_status'] = $permissions['membership'];
    $permissions['membership_type'] = $permissions['membership'];
    $permissions['membership_payment'] = array('create' => array('access CiviCRM', 'access CiviMember', 'edit memberships', 'access CiviContribute', 'edit contributions'), 'delete' => array('access CiviCRM', 'access CiviMember', 'delete in CiviMember', 'access CiviContribute', 'delete in CiviContribute'), 'get' => array('access CiviCRM', 'access CiviMember', 'access CiviContribute'), 'update' => array('access CiviCRM', 'access CiviMember', 'edit memberships', 'access CiviContribute', 'edit contributions'));
    // Participant permissions
    $permissions['participant'] = array('create' => array('access CiviCRM', 'access CiviEvent', 'register for events'), 'delete' => array('access CiviCRM', 'access CiviEvent', 'edit event participants'), 'get' => array('access CiviCRM', 'access CiviEvent', 'view event participants'), 'update' => array('access CiviCRM', 'access CiviEvent', 'edit event participants'));
    $permissions['participant_payment'] = array('create' => array('access CiviCRM', 'access CiviEvent', 'register for events', 'access CiviContribute', 'edit contributions'), 'delete' => array('access CiviCRM', 'access CiviEvent', 'edit event participants', 'access CiviContribute', 'delete in CiviContribute'), 'get' => array('access CiviCRM', 'access CiviEvent', 'view event participants', 'access CiviContribute'), 'update' => array('access CiviCRM', 'access CiviEvent', 'edit event participants', 'access CiviContribute', 'edit contributions'));
    // Pledge permissions
    $permissions['pledge'] = array('create' => array('access CiviCRM', 'access CiviPledge', 'edit pledges'), 'delete' => array('access CiviCRM', 'access CiviPledge', 'delete in CiviPledge'), 'get' => array('access CiviCRM', 'access CiviPledge'), 'update' => array('access CiviCRM', 'access CiviPledge', 'edit pledges'));
    $permissions['pledge_payment'] = array('create' => array('access CiviCRM', 'access CiviPledge', 'edit pledges', 'access CiviContribute', 'edit contributions'), 'delete' => array('access CiviCRM', 'access CiviPledge', 'delete in CiviPledge', 'access CiviContribute', 'delete in CiviContribute'), 'get' => array('access CiviCRM', 'access CiviPledge', 'access CiviContribute'), 'update' => array('access CiviCRM', 'access CiviPledge', 'edit pledges', 'access CiviContribute', 'edit contributions'));
    // Profile permissions
    $permissions['profile'] = array('get' => array());
    $permissions['uf_group'] = array('get' => array('access CiviCRM'));
    $permissions['uf_field'] = $permissions['uf_group'];
    // Translate 'create' action to 'update' if id is set
    if ($action == 'create' && (!empty($params['id']) || !empty($params[$entity . '_id']))) {
        $action = 'update';
    }
    // let third parties modify the permissions
    CRM_Utils_Hook::alterAPIPermissions($entity, $action, $params, $permissions);
    // Merge permissions for this entity with the defaults
    $perm = CRM_Utils_Array::value($entity, $permissions, array()) + $permissions['default'];
    // Return exact match if permission for this action has been declared
    if (isset($perm[$action])) {
        return $perm[$action];
    }
    // Translate specific actions into their generic equivalents
    $snippet = substr($action, 0, 3);
    if ($action == 'replace' || $snippet == 'del') {
        // 'Replace' is a combination of get+create+update+delete; however, the permissions
        // on each of those will be tested separately at runtime. This is just a sniff-test
        // based on the heuristic that 'delete' tends to be the most closesly guarded
        // of the necessary permissions.
        $action = 'delete';
    } elseif ($action == 'setvalue' || $snippet == 'upd') {
        $action = 'update';
    } elseif ($action == 'getfields' || $action == 'getspec' || $action == 'getoptions') {
        $action = 'meta';
    } elseif ($snippet == 'get') {
        $action = 'get';
    }
    return isset($perm[$action]) ? $perm[$action] : $perm['default'];
}
Example #2
0
/**
 * Decide what permissions to check for an api call
 *
 * @param $entity : (str) api entity
 * @param $action : (str) api action
 * @param $params : (array) api params
 *
 * @return array
 *   Array of permissions to check for this entity-action combo
 */
function _civicrm_api3_permissions($entity, $action, &$params)
{
    // FIXME: Lowercase entity_names are nonstandard but difficult to fix here
    // because this function invokes hook_civicrm_alterAPIPermissions
    $entity = _civicrm_api_get_entity_name_from_camel($entity);
    /**
     * @var array of permissions
     *
     * For each entity, we declare an array of permissions required for each action
     * The action is the array key, possible values:
     *  * create: applies to create (with no id in params)
     *  * update: applies to update, setvalue, create (with id in params)
     *  * get: applies to getcount, getsingle, getvalue and other gets
     *  * delete: applies to delete, replace
     *  * meta: applies to getfields, getoptions, getspec
     *  * default: catch-all for anything not declared
     *
     *  Note: some APIs declare other actions as well
     *
     * Permissions should use arrays for AND and arrays of arrays for OR
     * @see CRM_Core_Permission::check for more documentation
     */
    $permissions = array();
    // These are the default permissions - if any entity does not declare permissions for a given action,
    // (or the entity does not declare permissions at all) - then the action will be used from here
    $permissions['default'] = array('meta' => array('access CiviCRM'), 'default' => array('administer CiviCRM'));
    // Note: Additional permissions in DynamicFKAuthorization
    $permissions['attachment'] = array('default' => array(array('access CiviCRM', 'access AJAX API')));
    // Contact permissions
    $permissions['contact'] = array('create' => array('access CiviCRM', 'add contacts'), 'delete' => array('access CiviCRM', 'delete contacts'), 'get' => array(), 'update' => array(), 'getquick' => array(array('access CiviCRM', 'access AJAX API')));
    // CRM-16963 - Permissions for country.
    $permissions['country'] = array('get' => array('access CiviCRM'), 'default' => array('administer CiviCRM'));
    // Contact-related data permissions.
    $permissions['address'] = array('default' => array());
    $permissions['email'] = $permissions['address'];
    $permissions['phone'] = $permissions['address'];
    $permissions['website'] = $permissions['address'];
    $permissions['im'] = $permissions['address'];
    // @todo - implement CRM_Core_BAO_EntityTag::addSelectWhereClause and remove this heavy-handed restriction
    $permissions['entity_tag'] = array('get' => array('access CiviCRM', 'view all contacts'), 'default' => array('access CiviCRM', 'edit all contacts'));
    // @todo - ditto
    $permissions['note'] = $permissions['entity_tag'];
    // Allow non-admins to get and create tags to support tagset widget
    // Delete is still reserved for admins
    $permissions['tag'] = array('get' => array('access CiviCRM'), 'create' => array('access CiviCRM'), 'update' => array('access CiviCRM'));
    //relationship permissions
    $permissions['relationship'] = array('get' => array(), 'delete' => array('access CiviCRM', 'edit all contacts'), 'default' => array('access CiviCRM', 'edit all contacts'));
    // CRM-17741 - Permissions for RelationshipType.
    $permissions['relationship_type'] = array('get' => array('access CiviCRM'), 'default' => array('administer CiviCRM'));
    // Activity permissions
    $permissions['activity'] = array('delete' => array('access CiviCRM', 'delete activities'), 'default' => array('access CiviCRM', 'view all activities'));
    // Case permissions
    $permissions['case'] = array('create' => array('access CiviCRM', 'add cases'), 'delete' => array('access CiviCRM', 'delete in CiviCase'), 'default' => array(array('access my cases and activities', 'access all cases and activities')));
    $permissions['case_contact'] = $permissions['case'];
    $permissions['case_type'] = array('default' => array('administer CiviCase'), 'get' => array(array('access my cases and activities', 'access all cases and activities')));
    // Campaign permissions
    $permissions['campaign'] = array('get' => array('access CiviCRM'), 'default' => array(array('administer CiviCampaign', 'manage campaign')));
    $permissions['survey'] = $permissions['campaign'];
    // Financial permissions
    $permissions['contribution'] = array('get' => array('access CiviCRM', 'access CiviContribute'), 'delete' => array('access CiviCRM', 'access CiviContribute', 'delete in CiviContribute'), 'completetransaction' => array('edit contributions'), 'default' => array('access CiviCRM', 'access CiviContribute', 'edit contributions'));
    $permissions['line_item'] = $permissions['contribution'];
    // Custom field permissions
    $permissions['custom_field'] = array('default' => array('administer CiviCRM', 'access all custom data'));
    $permissions['custom_group'] = $permissions['custom_field'];
    // Event permissions
    $permissions['event'] = array('create' => array('access CiviCRM', 'access CiviEvent', 'edit all events'), 'delete' => array('access CiviCRM', 'access CiviEvent', 'delete in CiviEvent'), 'get' => array('access CiviCRM', 'access CiviEvent', 'view event info'), 'update' => array('access CiviCRM', 'access CiviEvent', 'edit all events'));
    // Loc block is only used for events
    $permissions['loc_block'] = $permissions['event'];
    // File permissions
    $permissions['file'] = array('default' => array('access CiviCRM', 'access uploaded files'));
    $permissions['files_by_entity'] = $permissions['file'];
    // Group permissions
    $permissions['group'] = array('get' => array('access CiviCRM'), 'default' => array('access CiviCRM', 'edit groups'));
    $permissions['group_nesting'] = $permissions['group'];
    $permissions['group_organization'] = $permissions['group'];
    //Group Contact permission
    $permissions['group_contact'] = array('get' => array('access CiviCRM'), 'default' => array('access CiviCRM', 'edit all contacts'));
    // CiviMail Permissions
    $civiMailBasePerms = array('access CiviMail', 'create mailings', 'schedule mailings', 'approve mailings');
    $permissions['mailing'] = array('get' => array('access CiviCRM', $civiMailBasePerms), 'delete' => array('access CiviCRM', $civiMailBasePerms, 'delete in CiviMail'), 'submit' => array('access CiviCRM', array('access CiviMail', 'schedule mailings')), 'default' => array('access CiviCRM', $civiMailBasePerms));
    $permissions['mailing_group'] = $permissions['mailing'];
    $permissions['mailing_job'] = $permissions['mailing'];
    $permissions['mailing_recipients'] = $permissions['mailing'];
    $permissions['mailing_a_b'] = array('get' => array('access CiviCRM', 'access CiviMail'), 'delete' => array('access CiviCRM', 'access CiviMail', 'delete in CiviMail'), 'submit' => array('access CiviCRM', array('access CiviMail', 'schedule mailings')), 'default' => array('access CiviCRM', 'access CiviMail'));
    // Membership permissions
    $permissions['membership'] = array('get' => array('access CiviCRM', 'access CiviMember'), 'delete' => array('access CiviCRM', 'access CiviMember', 'delete in CiviMember'), 'default' => array('access CiviCRM', 'access CiviMember', 'edit memberships'));
    $permissions['membership_status'] = $permissions['membership'];
    $permissions['membership_type'] = $permissions['membership'];
    $permissions['membership_payment'] = array('create' => array('access CiviCRM', 'access CiviMember', 'edit memberships', 'access CiviContribute', 'edit contributions'), 'delete' => array('access CiviCRM', 'access CiviMember', 'delete in CiviMember', 'access CiviContribute', 'delete in CiviContribute'), 'get' => array('access CiviCRM', 'access CiviMember', 'access CiviContribute'), 'update' => array('access CiviCRM', 'access CiviMember', 'edit memberships', 'access CiviContribute', 'edit contributions'));
    // Participant permissions
    $permissions['participant'] = array('create' => array('access CiviCRM', 'access CiviEvent', 'register for events'), 'delete' => array('access CiviCRM', 'access CiviEvent', 'edit event participants'), 'get' => array('access CiviCRM', 'access CiviEvent', 'view event participants'), 'update' => array('access CiviCRM', 'access CiviEvent', 'edit event participants'));
    $permissions['participant_payment'] = array('create' => array('access CiviCRM', 'access CiviEvent', 'register for events', 'access CiviContribute', 'edit contributions'), 'delete' => array('access CiviCRM', 'access CiviEvent', 'edit event participants', 'access CiviContribute', 'delete in CiviContribute'), 'get' => array('access CiviCRM', 'access CiviEvent', 'view event participants', 'access CiviContribute'), 'update' => array('access CiviCRM', 'access CiviEvent', 'edit event participants', 'access CiviContribute', 'edit contributions'));
    // Pledge permissions
    $permissions['pledge'] = array('create' => array('access CiviCRM', 'access CiviPledge', 'edit pledges'), 'delete' => array('access CiviCRM', 'access CiviPledge', 'delete in CiviPledge'), 'get' => array('access CiviCRM', 'access CiviPledge'), 'update' => array('access CiviCRM', 'access CiviPledge', 'edit pledges'));
    //CRM-16777: Disable schedule reminder for user that have 'edit all events' and 'administer CiviCRM' permission.
    $permissions['action_schedule'] = array('update' => array(array('access CiviCRM', 'edit all events')));
    $permissions['pledge_payment'] = array('create' => array('access CiviCRM', 'access CiviPledge', 'edit pledges', 'access CiviContribute', 'edit contributions'), 'delete' => array('access CiviCRM', 'access CiviPledge', 'delete in CiviPledge', 'access CiviContribute', 'delete in CiviContribute'), 'get' => array('access CiviCRM', 'access CiviPledge', 'access CiviContribute'), 'update' => array('access CiviCRM', 'access CiviPledge', 'edit pledges', 'access CiviContribute', 'edit contributions'));
    // Profile permissions
    $permissions['profile'] = array('get' => array());
    $permissions['uf_group'] = array('create' => array('access CiviCRM', array('administer CiviCRM', 'manage event profiles')), 'get' => array('access CiviCRM'), 'update' => array('access CiviCRM', array('administer CiviCRM', 'manage event profiles')));
    $permissions['uf_field'] = $permissions['uf_join'] = $permissions['uf_group'];
    $permissions['uf_field']['delete'] = array('access CiviCRM', array('administer CiviCRM', 'manage event profiles'));
    $permissions['option_value'] = $permissions['uf_group'];
    $permissions['option_group'] = $permissions['option_value'];
    $permissions['message_template'] = array('get' => array('access CiviCRM'), 'create' => array('edit message templates'), 'update' => array('edit message templates'));
    // Translate 'create' action to 'update' if id is set
    if ($action == 'create' && (!empty($params['id']) || !empty($params[$entity . '_id']))) {
        $action = 'update';
    }
    // let third parties modify the permissions
    CRM_Utils_Hook::alterAPIPermissions($entity, $action, $params, $permissions);
    // Merge permissions for this entity with the defaults
    $perm = CRM_Utils_Array::value($entity, $permissions, array()) + $permissions['default'];
    // Return exact match if permission for this action has been declared
    if (isset($perm[$action])) {
        return $perm[$action];
    }
    // Translate specific actions into their generic equivalents
    $snippet = substr($action, 0, 3);
    if ($action == 'replace' || $snippet == 'del') {
        // 'Replace' is a combination of get+create+update+delete; however, the permissions
        // on each of those will be tested separately at runtime. This is just a sniff-test
        // based on the heuristic that 'delete' tends to be the most closely guarded
        // of the necessary permissions.
        $action = 'delete';
    } elseif ($action == 'setvalue' || $snippet == 'upd') {
        $action = 'update';
    } elseif ($action == 'getfields' || $action == 'getfield' || $action == 'getspec' || $action == 'getoptions') {
        $action = 'meta';
    } elseif ($snippet == 'get') {
        $action = 'get';
    }
    return isset($perm[$action]) ? $perm[$action] : $perm['default'];
}