function getView($module, $role_id) { $fields = ACLField::getFields($module, '', $role_id); $sugar_smarty = new Sugar_Smarty(); if (substr($module, 0, 2) == 'KB') { $sugar_smarty->assign('LBL_MODULE', 'KBDocuments'); } else { $sugar_smarty->assign('LBL_MODULE', $module); } $GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], 'ACLFields'); $sugar_smarty->assign('MOD', $GLOBALS['mod_strings']); $sugar_smarty->assign('APP', $GLOBALS['app_strings']); $sugar_smarty->assign('FLC_MODULE', $module); $sugar_smarty->assign('APP_LIST', $GLOBALS['app_list_strings']); $sugar_smarty->assign('FIELDS', $fields); foreach ($GLOBALS['aclFieldOptions'] as $key => $option) { $GLOBALS['aclFieldOptions'][$key] = translate($option, 'ACLFields'); } $sugar_smarty->assign('OPTIONS', $GLOBALS['aclFieldOptions']); $req_options = $GLOBALS['aclFieldOptions']; unset($req_options[-99]); $sugar_smarty->assign('OPTIONS_REQUIRED', $req_options); return $sugar_smarty->fetch('modules/ACLFields/EditView.tpl'); }
function addDefaultRoles($defaultRoles = array()) { global $db; foreach ($defaultRoles as $roleName => $role) { $ACLField = new ACLField(); $role1 = new ACLRole(); $role1->name = $roleName; $role1->description = $roleName . " Role"; $role1_id = $role1->save(); foreach ($role as $category => $actions) { foreach ($actions as $name => $access_override) { if ($name == 'fields') { foreach ($access_override as $field_id => $access) { $ACLField->setAccessControl($category, $role1_id, $field_id, $access); } } else { $queryACL = "SELECT id FROM acl_actions where category='{$category}' and name='{$name}'"; $result = $db->query($queryACL); $actionId = $db->fetchByAssoc($result); if (isset($actionId['id']) && !empty($actionId['id'])) { $role1->setAction($role1_id, $actionId['id'], $access_override); } } } } } }
/** * If current user have not permit to change field function replace default value * * @param SugarBean $focus */ function populateFromPostACL(SugarBean $focus) { $insert = !isset($focus->id) || $focus->new_with_id; $isOwner = $focus->isOwner($GLOBALS['current_user']->id); // set up a default bean as per bug 46448, without bringing EditView into the mix // bug 58730 require_once 'data/BeanFactory.php'; $defaultBean = BeanFactory::getBean($focus->module_name); $defaultBean->fill_in_additional_detail_fields(); $defaultBean->assigned_user_id = $GLOBALS['current_user']->id; foreach (array_keys($focus->field_defs) as $field) { $fieldAccess = ACLField::hasAccess($field, $focus->module_dir, $GLOBALS['current_user']->id, $isOwner); if (!in_array($fieldAccess, array(2, 4))) { if ($insert) { $focus->{$field} = $defaultBean->{$field}; } else { unset($focus->{$field}); } } } }
/** * @Deprecated */ public function get_audit_list() { global $focus, $genericAssocFieldsArray, $moduleAssocFieldsArray, $current_user, $timedate, $app_strings; $audit_list = array(); if (!empty($_REQUEST['record'])) { $result = $focus->retrieve($_REQUEST['record']); if ($result == null || !$focus->ACLAccess('', $focus->isOwner($current_user->id))) { sugar_die($app_strings['ERROR_NO_RECORD']); } } if ($focus->is_AuditEnabled()) { $order = ' order by ' . $focus->get_audit_table_name() . '.date_created desc'; //order by contacts_audit.date_created desc $query = "SELECT " . $focus->get_audit_table_name() . ".*, users.user_name FROM " . $focus->get_audit_table_name() . ", users WHERE " . $focus->get_audit_table_name() . ".created_by = users.id AND " . $focus->get_audit_table_name() . ".parent_id = '{$focus->id}'" . $order; $result = $focus->db->query($query); // We have some data. require 'metadata/audit_templateMetaData.php'; $fieldDefs = $dictionary['audit']['fields']; while (($row = $focus->db->fetchByAssoc($result)) != null) { if (!ACLField::hasAccess($row['field_name'], $focus->module_dir, $GLOBALS['current_user']->id, $focus->isOwner($GLOBALS['current_user']->id))) { continue; } //If the team_set_id field has a log entry, we retrieve the list of teams to display if ($row['field_name'] == 'team_set_id') { $row['field_name'] = 'team_name'; require_once 'modules/Teams/TeamSetManager.php'; $row['before_value_string'] = TeamSetManager::getCommaDelimitedTeams($row['before_value_string']); $row['after_value_string'] = TeamSetManager::getCommaDelimitedTeams($row['after_value_string']); } $temp_list = array(); foreach ($fieldDefs as $field) { if (array_key_exists($field['name'], $row)) { if (($field['name'] == 'before_value_string' || $field['name'] == 'after_value_string') && (array_key_exists($row['field_name'], $genericAssocFieldsArray) || !empty($moduleAssocFieldsArray[$focus->object_name]) && array_key_exists($row['field_name'], $moduleAssocFieldsArray[$focus->object_name]))) { $temp_list[$field['name']] = Audit::getAssociatedFieldName($row['field_name'], $row[$field['name']]); } else { $temp_list[$field['name']] = $row[$field['name']]; } if ($field['name'] == 'date_created') { $date_created = ''; if (!empty($temp_list[$field['name']])) { $date_created = $timedate->to_display_date_time($temp_list[$field['name']]); $date_created = !empty($date_created) ? $date_created : $temp_list[$field['name']]; } $temp_list[$field['name']] = $date_created; } if (($field['name'] == 'before_value_string' || $field['name'] == 'after_value_string') && ($row['data_type'] == "enum" || $row['data_type'] == "multienum")) { global $app_list_strings; $enum_keys = unencodeMultienum($temp_list[$field['name']]); $enum_values = array(); foreach ($enum_keys as $enum_key) { if (isset($focus->field_defs[$row['field_name']]['options'])) { $domain = $focus->field_defs[$row['field_name']]['options']; if (isset($app_list_strings[$domain][$enum_key])) { $enum_values[] = $app_list_strings[$domain][$enum_key]; } } } if (!empty($enum_values)) { $temp_list[$field['name']] = implode(', ', $enum_values); } if ($temp_list['data_type'] === 'date') { $temp_list[$field['name']] = $timedate->to_display_date($temp_list[$field['name']], false); } } elseif (($field['name'] == 'before_value_string' || $field['name'] == 'after_value_string') && $row['data_type'] == "datetimecombo") { if (!empty($temp_list[$field['name']]) && $temp_list[$field['name']] != 'NULL') { $temp_list[$field['name']] = $timedate->to_display_date_time($temp_list[$field['name']]); } else { $temp_list[$field['name']] = ''; } } elseif ($field['name'] == 'field_name') { global $mod_strings; if (isset($focus->field_defs[$row['field_name']]['vname'])) { $label = $focus->field_defs[$row['field_name']]['vname']; $temp_list[$field['name']] = translate($label, $focus->module_dir); } } } } $temp_list['created_by'] = $row['user_name']; $audit_list[] = $temp_list; } } return $audit_list; }
/** * Used by the dependency manager to pre-load all the related fields required * to load an entire view. */ public function action_getRelatedValues() { /** @var LoggerManager */ global $log; $ret = array(); if (empty($_REQUEST['tmodule']) || empty($_REQUEST['fields'])) { return; } $fields = json_decode(html_entity_decode($_REQUEST['fields']), true); if (!is_array($fields)) { $log->fatal('"fields" is not a valid JSON string'); $this->display($ret); return; } $module = $_REQUEST['tmodule']; $id = empty($_REQUEST['record_id']) ? null : $_REQUEST['record_id']; $focus = BeanFactory::retrieveBean($module, $id); if (!$focus) { $log->fatal('Unable to load bean'); $this->display($ret); return; } foreach ($fields as $rfDef) { if (!isset($rfDef['link'], $rfDef['type'])) { $log->fatal('At least one of "link" and "type" attributes is not specified'); continue; } $link = $rfDef['link']; $type = $rfDef['type']; if (!isset($ret[$link])) { $ret[$link] = array(); } if (empty($ret[$link][$type])) { $ret[$link][$type] = array(); } switch ($type) { //The Related function is used for pulling a sing field from a related record case "related": if (!isset($rfDef['relate'])) { $log->fatal('"relate" attribute of related expression is not specified'); break; } //Default it to a blank value $ret[$link]['related'][$rfDef['relate']] = ""; //If we have neither a focus id nor a related record id, we can't retrieve anything if (!empty($id) || !empty($rfDef['relId'])) { $relBean = null; if (empty($rfDef['relId']) || empty($rfDef['relModule'])) { //If the relationship is invalid, just move onto another field if (!$focus->load_relationship($link)) { break; } $beans = $focus->{$link}->getBeans(array("enforce_teams" => true)); //No related beans means no value if (empty($beans)) { break; } //Grab the first bean on the list reset($beans); $relBean = current($beans); } else { $relBean = BeanFactory::getBean($rfDef['relModule'], $rfDef['relId']); } //If we found a bean and the current user has access to the related field, grab a value from it if (!empty($relBean) && ACLField::hasAccess($rfDef['relate'], $relBean->module_dir, $GLOBALS['current_user']->id, true)) { $validFields = FormulaHelper::cleanFields($relBean->field_defs, false, true, true); if (isset($validFields[$rfDef['relate']])) { $ret[$link]['relId'] = $relBean->id; $ret[$link]['related'][$rfDef['relate']] = FormulaHelper::getFieldValue($relBean, $rfDef['relate']); } } } break; case "count": if (!empty($id) && $focus->load_relationship($link)) { $ret[$link][$type] = count($focus->{$link}->get()); } else { $ret[$link][$type] = 0; } break; case "rollupSum": case "rollupAve": case "rollupMin": case "rollupMax": //If we are going to calculate one rollup, calculate all the rollups since there is so little cost if (!isset($rfDef['relate'])) { $log->fatal('"relate" attribute of rollup expression is not specified'); break; } $rField = $rfDef['relate']; if (!empty($id) && $focus->load_relationship($link)) { $relBeans = $focus->{$link}->getBeans(array("enforce_teams" => true)); $sum = 0; $count = 0; $min = false; $max = false; if (!empty($relBeans)) { //Check if the related record vardef has banned this field from formulas $relBean = reset($relBeans); $validFields = FormulaHelper::cleanFields($relBean->field_defs, false, true, true); if (!isset($validFields[$rField])) { break; } } foreach ($relBeans as $bean) { if (isset($bean->{$rField}) && is_numeric($bean->{$rField}) && ACLField::hasAccess($rField, $bean->module_dir, $GLOBALS['current_user']->id, true)) { $count++; $sum += floatval($bean->{$rField}); if ($min === false || $bean->{$rField} < $min) { $min = floatval($bean->{$rField}); } if ($max === false || $bean->{$rField} > $max) { $max = floatval($bean->{$rField}); } } } if ($type == "rollupSum") { $ret[$link][$type][$rField] = $sum; } if ($type == "rollupAve") { $ret[$link][$type][$rField] = $count == 0 ? 0 : $sum / $count; } if ($type == "rollupMin") { $ret[$link][$type][$rField] = $min; } if ($type == "rollupMax") { $ret[$link][$type][$rField] = $max; } } else { $ret[$link][$type][$rField] = 0; } break; } } $this->display($ret); }
/** * Constructor for the bean, it performs following tasks: * * 1. Initalized a database connections * 2. Load the vardefs for the module implemeting the class. cache the entries * if needed * 3. Setup row-level security preference * All implementing classes must call this constructor using the parent::__construct() * */ public function __construct() { // FIXME: this will be removed, needed for ensuring BeanFactory is always used //$this->checkBacktrace(); global $dictionary, $current_user; $this->db = DBManagerFactory::getInstance(); if (empty($this->module_name)) { $this->module_name = $this->module_dir; } if (isset($this->disable_team_security)) { $this->disable_row_level_security = $this->disable_team_security; } // Verify that current user is not null then do an ACL check. The current user check is to support installation. if (!$this->disable_row_level_security && !empty($current_user->id) && (is_admin($current_user) || $this->bean_implements('ACL') && (ACLAction::getUserAccessLevel($current_user->id, $this->module_dir, 'access') == ACL_ALLOW_ENABLED && (ACLAction::getUserAccessLevel($current_user->id, $this->module_dir, 'admin') == ACL_ALLOW_ADMIN || ACLAction::getUserAccessLevel($current_user->id, $this->module_dir, 'admin') == ACL_ALLOW_ADMIN_DEV)))) { $this->disable_row_level_security = true; } if (false == $this->disable_vardefs && (empty(self::$loadedDefs[$this->object_name]) || !empty($GLOBALS['reload_vardefs']))) { $refresh = inDeveloperMode() || !empty($_SESSION['developerMode']); if ($refresh && !empty(VardefManager::$inReload["{$this->module_dir}:{$this->object_name}"])) { // if we're already reloading this vardef, no need to do it again $refresh = false; } VardefManager::loadVardef($this->module_dir, $this->object_name, $refresh, array("bean" => $this)); // build $this->column_fields from the field_defs if they exist if (!empty($dictionary[$this->object_name]['fields'])) { foreach ($dictionary[$this->object_name]['fields'] as $key => $value_array) { $column_fields[] = $key; if (!empty($value_array['required']) && !empty($value_array['name'])) { $this->required_fields[$value_array['name']] = 1; } } $this->column_fields = $column_fields; } //setup custom fields if (!isset($this->custom_fields) && empty($this->disable_custom_fields)) { $this->setupCustomFields($this->module_dir); } //load up field_arrays from CacheHandler; if (empty($this->list_fields)) { $this->list_fields = $this->_loadCachedArray($this->module_dir, $this->object_name, 'list_fields'); } if (empty($this->column_fields)) { $this->column_fields = $this->_loadCachedArray($this->module_dir, $this->object_name, 'column_fields'); } if (empty($this->required_fields)) { $this->required_fields = $this->_loadCachedArray($this->module_dir, $this->object_name, 'required_fields'); } if (isset($GLOBALS['dictionary'][$this->object_name]) && !$this->disable_vardefs) { $this->field_name_map = $dictionary[$this->object_name]['fields']; $this->field_defs = $dictionary[$this->object_name]['fields']; if (isset($dictionary[$this->object_name]['name_format_map'])) { $this->name_format_map = $dictionary[$this->object_name]['name_format_map']; } if (!empty($dictionary[$this->object_name]['optimistic_locking'])) { $this->optimistic_lock = true; } if (isset($dictionary[$this->object_name]['importable'])) { $this->importable = isTruthy($dictionary[$this->object_name]['importable']); } } self::$loadedDefs[$this->object_name]['column_fields'] =& $this->column_fields; self::$loadedDefs[$this->object_name]['list_fields'] =& $this->list_fields; self::$loadedDefs[$this->object_name]['required_fields'] =& $this->required_fields; self::$loadedDefs[$this->object_name]['field_name_map'] =& $this->field_name_map; self::$loadedDefs[$this->object_name]['field_defs'] =& $this->field_defs; self::$loadedDefs[$this->object_name]['name_format_map'] =& $this->name_format_map; } else { $this->column_fields =& self::$loadedDefs[$this->object_name]['column_fields']; $this->list_fields =& self::$loadedDefs[$this->object_name]['list_fields']; $this->required_fields =& self::$loadedDefs[$this->object_name]['required_fields']; $this->field_name_map =& self::$loadedDefs[$this->object_name]['field_name_map']; $this->field_defs =& self::$loadedDefs[$this->object_name]['field_defs']; $this->name_format_map =& self::$loadedDefs[$this->object_name]['name_format_map']; $this->added_custom_field_defs = true; if (!isset($this->custom_fields) && empty($this->disable_custom_fields)) { $this->setupCustomFields($this->module_dir, false); } if (!empty($dictionary[$this->object_name]['optimistic_locking'])) { $this->optimistic_lock = true; } } // Verify that current user is not null then do an ACL check. The current user check is to support installation. if (!$this->disable_row_level_security && !empty($current_user->id) && !isset($this->disable_team_security) && !SugarACL::checkAccess($this->module_dir, 'team_security', array('bean' => $this))) { // We can disable team security for this module $this->disable_row_level_security = true; } if ($this->bean_implements('ACL')) { $this->acl_fields = isset($dictionary[$this->object_name]['acl_fields']) && $dictionary[$this->object_name]['acl_fields'] === false ? false : true; if (!empty($current_user->id)) { ACLField::loadUserFields($this->module_dir, $this->object_name, $current_user->id); } $this->addVisibilityStrategy("ACLVisibility"); } $this->populateDefaultValues(); if (isset($this->disable_team_security)) { $this->disable_row_level_security = $this->disable_team_security; } }
public function getFieldListAccess($module, $field_list, $context) { $user = $this->getCurrentUser($context); if (empty($user) || empty($user->id) || is_admin($user)) { return array(); } if (!ACLField::hasACLs($user->id, $module)) { return array(); } return parent::getFieldListAccess($module, $field_list, $context); }
/** * Used by the dependency manager to pre-load all the related fields required * to load an entire view. */ public function getRelatedValues($api, $args) { if (empty($args['module']) || empty($args['fields'])) { return; } $fields = json_decode(html_entity_decode($args['fields']), true); $focus = $this->loadBean($api, $args); $ret = array(); foreach ($fields as $rfDef) { if (!isset($rfDef['link']) || !isset($rfDef['type'])) { continue; } $link = $rfDef['link']; $type = $rfDef['type']; $rField = ''; if (!isset($ret[$link])) { $ret[$link] = array(); } if (empty($ret[$link][$type])) { $ret[$link][$type] = array(); } // count formulas don't have a relate attribute if (isset($rfDef['relate'])) { $rField = $rfDef['relate']; } switch ($type) { //The Related function is used for pulling a sing field from a related record case "related": //Default it to a blank value $ret[$link]['related'][$rfDef['relate']] = ""; //If we have neither a focus id nor a related record id, we can't retrieve anything $relBean = null; if (empty($rfDef['relId']) || empty($rfDef['relModule'])) { //If the relationship is invalid, just move onto another field if (!$focus->load_relationship($link)) { break; } $beans = $focus->{$link}->getBeans(array("enforce_teams" => true)); //No related beans means no value if (empty($beans)) { break; } //Grab the first bean on the list reset($beans); $relBean = current($beans); } else { $relBean = BeanFactory::getBean($rfDef['relModule'], $rfDef['relId']); } //If we found a bean and the current user has access to the related field, grab a value from it if (!empty($relBean) && ACLField::hasAccess($rfDef['relate'], $relBean->module_dir, $GLOBALS['current_user']->id, true)) { $validFields = FormulaHelper::cleanFields($relBean->field_defs, false, true, true); if (isset($validFields[$rfDef['relate']])) { $ret[$link]['relId'] = $relBean->id; $ret[$link]['related'][$rfDef['relate']] = FormulaHelper::getFieldValue($relBean, $rfDef['relate']); } } break; case "count": if ($focus->load_relationship($link)) { $ret[$link][$type] = count($focus->{$link}->get()); } else { $ret[$link][$type] = 0; } break; case "rollupSum": case "rollupAve": case "rollupMin": case "rollupMax": //If we are going to calculate one rollup, calculate all the rollups since there is so little cost if ($focus->load_relationship($link)) { $relBeans = $focus->{$link}->getBeans(array("enforce_teams" => true)); $sum = 0; $count = 0; $min = false; $max = false; if (!empty($relBeans)) { //Check if the related record vardef has banned this field from formulas $relBean = reset($relBeans); $validFields = FormulaHelper::cleanFields($relBean->field_defs, false, true, true); if (!isset($validFields[$rField])) { $ret[$link][$type][$rField] = 0; break; } } foreach ($relBeans as $bean) { if (isset($bean->{$rField}) && is_numeric($bean->{$rField}) && ACLField::hasAccess($rField, $bean->module_dir, $GLOBALS['current_user']->id, true)) { $count++; $sum += floatval($bean->{$rField}); if ($min === false || $bean->{$rField} < $min) { $min = floatval($bean->{$rField}); } if ($max === false || $bean->{$rField} > $max) { $max = floatval($bean->{$rField}); } } } if ($type == "rollupSum") { $ret[$link][$type][$rField] = $sum; } if ($type == "rollupAve") { $ret[$link][$type][$rField] = $count == 0 ? 0 : $sum / $count; } if ($type == "rollupMin") { $ret[$link][$type][$rField] = $min; } if ($type == "rollupMax") { $ret[$link][$type][$rField] = $max; } } else { $ret[$link][$type][$rField] = 0; } break; case "rollupCurrencySum": $ret[$link][$type][$rField] = 0; if ($focus->load_relationship($link)) { $toRate = isset($focus->base_rate) ? $focus->base_rate : null; $relBeans = $focus->{$link}->getBeans(array("enforce_teams" => true)); $sum = 0; foreach ($relBeans as $bean) { if (!empty($bean->{$rField}) && is_numeric($bean->{$rField}) && ACLField::hasAccess($rField, $bean->module_dir, $GLOBALS['current_user']->id, true)) { $sum = SugarMath::init($sum)->add(SugarCurrency::convertWithRate($bean->{$rField}, $bean->base_rate, $toRate))->result(); } } $ret[$link][$type][$rField] = $sum; } break; } } return $ret; }
/** * returnFieldsWithAccess * * @param object $seed an instance of the bean we are checking acl's on * @param array $select_fields array of fields being explicitly checked for access, empty array means check all * @return array Array of the fields for this bean that passed the acl filter test */ function returnFieldsWithAccess($seed, $select_fields = array()) { //can't do anything if there is no bean if (empty($seed)) { return $select_fields; } //if the select fields array is empty, then use all the fields for this bean if (empty($select_fields)) { $fields = $seed->field_name_map; $select_fields = array_keys($fields); } //check to see if bean implements acl and this is not an admin so we can remove any restricted fields if ($seed->bean_implements('ACL') && !empty($GLOBALS['current_user']) && !$GLOBALS['current_user']->is_admin) { //lets load up any acl fields for this uer ACLField::loadUserFields($seed->module_dir, $seed->object_name, $GLOBALS['current_user']->id); //iterate through the select fields array and remove any restricted acl fields (less than 0) foreach ($select_fields as $fieldnum => $fieldname) { if (isset($_SESSION['ACL'][$GLOBALS['current_user']->id][$seed->module_dir]['fields'][$fieldname]) && $_SESSION['ACL'][$GLOBALS['current_user']->id][$seed->module_dir]['fields'][$fieldname] < 0) { //this field has an acl restricting the user from accessing it, unset it unset($select_fields[$fieldnum]); } } } return $select_fields; }
foreach ($role_actions as $module) { foreach ($module as $type) { foreach ($type as $act) { $role->setAction($role->id, $act['id'], $act['aclaccess']); } } } // duplicate field ACL $fields = ACLField::getACLFieldsByRole($_REQUEST['isduplicate']); foreach ($fields as $field) { ACLField::setAccessControl($field['category'], $role->id, $field['name'], $field['aclaccess']); } } } else { ob_clean(); $flc_module = 'All'; foreach ($_POST as $name => $value) { if (substr_count($name, 'act_guid') > 0) { $name = str_replace('act_guid', '', $name); $role->setAction($role->id, $name, $value); } if (substr_count($name, 'flc_guid') > 0) { $flc_module = $_REQUEST['flc_module']; $name = str_replace('flc_guid', '', $name); ACLField::setAccessControl($flc_module, $role->id, $name, $value); } } echo "result = {role_id:'{$role->id}', module:'{$flc_module}'}"; sugar_cleanup(true); } header("Location: index.php?module=ACLRoles&action=DetailView&record=" . $role->id);
public function clearACLCache() { self::$acl_fields = array(); parent::clearACLCache(); }