Merge pull request #10540 from colemanw/CRM-20091
[civicrm-core.git] / CRM / Core / Permission.php
index c5307c9e8535c2f0a281d859afb0fa8dddcaef37..0b9979d599f0aa50d1048c9050cdcb0c70da68f8 100644 (file)
@@ -874,6 +874,601 @@ class CRM_Core_Permission {
     return $permissions;
   }
 
+  /**
+   * For each entity provides 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
+   *
+   * @return array of permissions
+   */
+  public static function getEntityActionPermissions() {
+    $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(
+      // applies to getfields, getoptions, etc.
+      'meta' => array('access CiviCRM'),
+      // catch-all, applies to create, get, delete, etc.
+      // If an entity declares it's own 'default' action it will override this one
+      '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',
+      ),
+      // managed by query object
+      'get' => array(),
+      // managed by _civicrm_api3_check_edit_permissions
+      '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(
+      // get is managed by BAO::addSelectWhereClause
+      // create/delete are managed by _civicrm_api3_check_edit_permissions
+      'default' => array(),
+    );
+    $permissions['email'] = $permissions['address'];
+    $permissions['phone'] = $permissions['address'];
+    $permissions['website'] = $permissions['address'];
+    $permissions['im'] = $permissions['address'];
+    $permissions['open_i_d'] = $permissions['address'];
+
+    // Also managed by ACLs - CRM-19448
+    $permissions['entity_tag'] = array('default' => array());
+    $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 is managed by BAO::addSelectWhereClause
+      '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',
+      ),
+      'get' => array(
+        'access CiviCRM',
+        // Note that view all activities is also required within the api
+        // if the id is not passed in. Where the id is passed in the activity
+        // specific check functions are used and tested.
+      ),
+      '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',
+      ),
+      'restore' => array(
+        'administer CiviCase',
+      ),
+      'merge' => array(
+        'administer CiviCase',
+      ),
+      'default' => array(
+        // At minimum the user needs one of the following. Finer-grained access is controlled by CRM_Case_BAO_Case::addSelectWhereClause
+        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(
+        // nested array = OR
+        array('access my cases and activities', 'access all cases and activities'),
+      ),
+    );
+
+    // Campaign permissions
+    $permissions['campaign'] = array(
+      'get' => array('access CiviCRM'),
+      'default' => array(
+        // nested array = OR
+        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'];
+
+    // Payment permissions
+    $permissions['payment'] = array(
+      'get' => array(
+        'access CiviCRM',
+        'access CiviContribute',
+      ),
+      'delete' => array(
+        'access CiviCRM',
+        'access CiviContribute',
+        'delete in CiviContribute',
+      ),
+      'cancel' => array(
+        'access CiviCRM',
+        'access CiviContribute',
+        'edit contributions',
+      ),
+      'create' => array(
+        'access CiviCRM',
+        'access CiviContribute',
+        'edit contributions',
+      ),
+      'default' => array(
+        'access CiviCRM',
+        'access CiviContribute',
+        'edit contributions',
+      ),
+    );
+
+    // 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'];
+
+    $permissions['state_province'] = array(
+      'get' => array(
+        'access CiviCRM',
+      ),
+    );
+
+    // Price sets are shared by several components, user needs access to at least one of them
+    $permissions['price_set'] = array(
+      'default' => array(
+        array('access CiviEvent', 'access CiviContribute', 'access CiviMember'),
+      ),
+      'get' => array(
+        array('access CiviCRM', 'view event info', 'make online contributions'),
+      ),
+    );
+
+    // 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(
+      // To get/preview/update, one must have least one of these perms:
+      // Mailing API implementations enforce nuances of create/approve/schedule permissions.
+      '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(), // the profile will take care of this
+    );
+
+    $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'),
+    );
+    return $permissions;
+  }
+
+  /**
+   * Translate an unknown action to a canonical form.
+   *
+   * @param string $action
+   *
+   * @return string
+   *   the standardised action name
+   */
+  public static function getGenericAction($action) {
+    $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 $action;
+  }
+
   /**
    * Validate user permission across.
    * edit or view or with supportable acls.