/** * Construct a WHERE clause to handle permissions to $object_* * * @param array ref $tables - Any tables that may be needed in the FROM * @param string $operation - The operation being attempted * @param string $object_table - The table of the object in question * @param int $object_id - The ID of the object in question * @param int $acl_id - If it's a grant/revoke operation, the ACL ID * @param boolean $acl_group - For grant operations, this flag determines if we're granting a single acl (false) or an entire group. * @return string - The WHERE clause, or 0 on failure * @access public * @static */ function permissionClause(&$tables, $operation, $object_table = null, $object_id = null, $acl_id = null, $acl_group = false) { $dao =& new CRM_Core_DAO_ACL(); $t = array('ACL' => CRM_Core_BAO_ACL::getTableName(), 'ACLGroup' => CRM_Core_DAO_ACLGroup::getTableName(), 'ACLGroupJoin' => CRM_Core_DAO_ACLGroupJoin::getTableName(), 'Contact' => CRM_Contact_DAO_Contact::getTableName(), 'Domain' => CRM_Core_DAO_Domain::getTableName(), 'Group' => CRM_Contact_DAO_Group::getTableName(), 'GroupContact' => CRM_Contact_DAO_GroupContact::getTableName()); $session =& CRM_Core_Session::singleton(); $contact_id = $session->get('userID'); $domainId = $session->get('domainID'); $where = " {$t['ACL']}.operation = '" . CRM_Utils_Type::escape($operation, 'String') . "'"; /* Include clause if we're looking for a specific table/id permission */ if (!empty($object_table)) { $where .= " AND ( {$t['ACL']}.object_table IS null\n OR ({$t['ACL']}.object_table = '" . CRM_Utils_Type::escape($object_table, 'String') . "'"; if (!empty($object_id)) { $where .= " AND ({$t['ACL']}.object_id IS null\n OR {$t['ACL']}.object_id = " . CRM_Utils_Type::escape($object_id, 'Integer') . ')'; } $where .= '))'; } /* Include clause if we're granting an ACL or ACL Group */ if (!empty($acl_id)) { $where .= " AND ({$t['ACL']}.acl_id IS null \n OR {$t['ACL']}.acl_id = " . CRM_Utils_Type::escape($acl_id, 'Integer') . ')'; if ($acl_group) { $where .= " AND {$t['ACL']}.acl_table = '{$t['ACLGroup']}'"; } else { $where .= " AND {$t['ACL']}.acl_table = '{$t['ACL']}'"; } } $query = array(); /* Query for permissions granted to all contacts in the domain */ $query[] = "SELECT {$t['ACL']}.*, 0 as override\n FROM {$t['ACL']}\n \n WHERE {$t['ACL']}.entity_table = '{$t['Domain']}'\n AND {$t['ACL']}.entity_id = {$domainId}\n AND ({$where})"; /* Query for permissions granted to all contacts through an ACL group */ $query[] = "SELECT {$t['ACL']}.*, 0 as override\n FROM {$t['ACL']}\n \n INNER JOIN {$t['ACLGroupJoin']}\n ON ({$t['ACL']}.entity_table = '{$t['ACLGroup']}'\n AND {$t['ACL']}.entity_id = \n {$t['ACLGroupJoin']}.acl_group_id)\n \n INNER JOIN {$t['ACLGroup']}\n ON {$t['ACL']}.entity_id = \n {$t['ACLGroup']}.id\n \n WHERE {$t['ACLGroupJoin']}.entity_table =\n '{$t['Domain']}'\n AND {$t['ACLGroup']}.is_active = 1\n AND {$t['ACLGroupJoin']}.entity_id = {$domainId}\n AND ({$where})"; /* Query for permissions granted directly to the contact */ $query[] = "SELECT {$t['ACL']}.*, 1 as override\n FROM {$t['ACL']}\n \n INNER JOIN {$t['Contact']}\n ON ({$t['ACL']}.entity_table = '{$t['Contact']}'\n AND {$t['ACL']}.entity_id = {$t['Contact']}.id)\n \n WHERE {$t['Contact']}.id = {$contact_id} \n AND ({$where})"; /* Query for permissions granted to the contact through an ACL group */ $query[] = "SELECT {$t['ACL']}.*, 1 as override\n FROM {$t['ACL']}\n \n INNER JOIN {$t['ACLGroupJoin']}\n ON ({$t['ACL']}.entity_table = '{$t['ACLGroup']}'\n AND {$t['ACL']}.entity_id =\n {$t['ACLGroupJoin']}.acl_group_id)\n \n INNER JOIN {$t['ACLGroup']}\n ON {$t['ACL']}.entity_id = {$t['ACLGroup']}.id\n \n WHERE {$t['ACLGroupJoin']}.entity_table = \n '{$t['Contact']}' \n AND {$t['ACLGroup']}.is_active = 1\n AND {$t['ACLGroupJoin']}.entity_id = {$contact_id}\n AND ({$where})"; /* Query for permissions granted to the contact through a group */ $query[] = "SELECT {$t['ACL']}.*, 0 as override\n FROM {$t['ACL']}\n \n INNER JOIN {$t['GroupContact']}\n ON ({$t['ACL']}.entity_table = '{$t['Group']}'\n AND {$t['ACL']}.entity_id =\n {$t['GroupContact']}.group_id)\n \n WHERE ({$where})\n AND {$t['GroupContact']}.contact_id = {$contact_id}\n AND {$t['GroupContact']}.status = 'Added')"; /* Query for permissions granted through an ACL group to a Contact * group */ $query[] = "SELECT {$t['ACL']}.*, 0 as override\n FROM {$t['ACL']}\n \n INNER JOIN {$t['ACLGroupJoin']}\n ON ({$t['ACL']}.entity_table = '{$t['ACLGroup']}'\n AND {$t['ACL']}.entity_id = \n {$t['ACLGroupJoin']}.acl_group_id)\n \n INNER JOIN {$t['ACLGroup']}\n ON {$t['ACL']}.entity_id = {$t['ACLGroup']}.id\n \n INNER JOIN {$t['GroupContact']}\n ON ({$t['ACLGroupJoin']}.entity_table =\n '{$t['Group']}'\n AND {$t['ACLGroupJoin']}.entity_id =\n {$t['GroupContact']}.group_id)\n \n WHERE ({$where})\n AND {$t['ACLGroup']}.is_active = 1\n AND {$t['GroupContact']}.contact_id = {$contact_id}\n AND {$t['GroupContact']}.status = 'Added'"; $union = '(' . implode(') UNION DISTINCT (', $query) . ')'; $dao->query($union); $allow = array(0); $deny = array(0); $override = array(); while ($dao->fetch()) { /* Instant bypass for the following cases: * 1) the rule governs all tables * 2) the rule governs all objects in the table in question * 3) the rule governs the specific object we want */ if (empty($dao->object_table) || $dao->object_table == $object_table && (empty($dao->object_id) || $dao->object_id == $object_id)) { $clause = 1; } else { /* Otherwise try to generate a clause for this rule */ $clause = CRM_Core_BAO_ACL::getClause($dao->object_table, $dao->object_id, $tables); /* If the clause returned is null, then the rule is a blanket * (id is null) on a table other than the one we're interested * in. So skip it. */ if (empty($clause)) { continue; } } /* Now we figure out if this is an allow or deny rule, and possibly * a contact-level override */ if ($dao->deny) { $deny[] = $clause; } else { $allow[] = $clause; if ($dao->override) { $override[] = $clause; } } } $allows = '(' . implode(' OR ', $allow) . ')'; $denies = '(' . implode(' OR ', $deny) . ')'; if (!empty($override)) { $denies = '(NOT (' . implode(' OR ', $override) . ") AND {$denies})"; } return "({$allows} AND NOT {$denies})"; }
/** * returns the list of fields that can be exported * * @access public * return array */ function &export($prefix = false) { if (!$GLOBALS['_CRM_CORE_DAO_ACLGROUPJOIN']['_export']) { $GLOBALS['_CRM_CORE_DAO_ACLGROUPJOIN']['_export'] = array(); $fields =& CRM_Core_DAO_ACLGroupJoin::fields(); foreach ($fields as $name => $field) { if (CRM_Utils_Array::value('export', $field)) { if ($prefix) { $GLOBALS['_CRM_CORE_DAO_ACLGROUPJOIN']['_export']['acl_group_join'] =& $fields[$name]; } else { $GLOBALS['_CRM_CORE_DAO_ACLGROUPJOIN']['_export'][$name] =& $fields[$name]; } } } } return $GLOBALS['_CRM_CORE_DAO_ACLGROUPJOIN']['_export']; }