Пример #1
0
 /**
  * Gets the ACL's for the module, will also expand them so the client side of the ACL's don't have to do as many checks.
  *
  * @param  string $module     The module we want to fetch the ACL for
  * @param  object $userObject The user object for the ACL's we are retrieving.
  * @param  object|bool $bean       The SugarBean for getting specific ACL's for a module
  * @param bool $showYes Do not unset Yes Results
  * @return array       Array of ACL's, first the action ACL's (access, create, edit, delete) then an array of the field level acl's
  */
 public function getAclForModule($module, $userObject, $bean = false, $showYes = false)
 {
     $outputAcl = array('fields' => array());
     $outputAcl['admin'] = $userObject->isAdminForModule($module) ? 'yes' : 'no';
     $outputAcl['developer'] = $userObject->isDeveloperForModule($module) ? 'yes' : 'no';
     if (!SugarACL::moduleSupportsACL($module)) {
         foreach (array('access', 'view', 'list', 'edit', 'delete', 'import', 'export', 'massupdate') as $action) {
             $outputAcl[$action] = 'yes';
         }
     } else {
         $context = array('user' => $userObject);
         if ($bean instanceof SugarBean) {
             $context['bean'] = $bean;
         }
         // if the bean is not set, or a new bean.. set the owner override
         // this will allow fields marked Owner to pass through ok.
         if ($bean == false || empty($bean->id) || isset($bean->new_with_id) && $bean->new_with_id == true) {
             $context['owner_override'] = true;
         }
         $moduleAcls = SugarACL::getUserAccess($module, array(), $context);
         // Bug56391 - Use the SugarACL class to determine access to different actions within the module
         foreach (SugarACL::$all_access as $action => $bool) {
             $outputAcl[$action] = $moduleAcls[$action] == true || !isset($moduleAcls[$action]) ? 'yes' : 'no';
         }
         // Only loop through the fields if we have a reason to, admins give full access on everything, no access gives no access to anything
         if ($outputAcl['access'] == 'yes') {
             // Currently create just uses the edit permission, but there is probably a need for a separate permission for create
             $outputAcl['create'] = $outputAcl['edit'];
             if ($bean === false) {
                 $bean = BeanFactory::newBean($module);
             }
             // we cannot use ACLField::getAvailableFields because it limits the fieldset we return.  We need all fields
             // for instance assigned_user_id is skipped in getAvailableFields, thus making the acl's look odd if Assigned User has ACL's
             // only assigned_user_name is returned which is a derived ["fake"] field.  We really need assigned_user_id to return as well.
             if (empty($GLOBALS['dictionary'][$bean->object_name]['fields'])) {
                 if (empty($bean->acl_fields)) {
                     $fieldsAcl = array();
                 } else {
                     $fieldsAcl = $bean->field_defs;
                 }
             } else {
                 $fieldsAcl = $GLOBALS['dictionary'][$bean->object_name]['fields'];
                 if (isset($GLOBALS['dictionary'][$bean->object_name]['acl_fields']) && $GLOBALS['dictionary'][$bean->object_name] === false) {
                     $fieldsAcl = array();
                 }
             }
             // get the field names
             SugarACL::listFilter($module, $fieldsAcl, $context, array('add_acl' => true));
             $fieldsAcl = $this->getMetaDataHacks()->fixAcls($fieldsAcl);
             foreach ($fieldsAcl as $field => $fieldAcl) {
                 switch ($fieldAcl['acl']) {
                     case SugarACL::ACL_READ_WRITE:
                         // Default, don't need to send anything down
                         break;
                     case SugarACL::ACL_READ_ONLY:
                         $outputAcl['fields'][$field]['write'] = 'no';
                         $outputAcl['fields'][$field]['create'] = 'no';
                         break;
                     case 2:
                         $outputAcl['fields'][$field]['read'] = 'no';
                         break;
                     case SugarACL::ACL_NO_ACCESS:
                     default:
                         $outputAcl['fields'][$field]['read'] = 'no';
                         $outputAcl['fields'][$field]['write'] = 'no';
                         $outputAcl['fields'][$field]['create'] = 'no';
                         break;
                 }
             }
         }
     }
     // there are times when we need the yes results, for instance comparing access for a record
     if ($showYes === false) {
         // for brevity, filter out 'yes' fields since UI assumes 'yes'
         foreach ($outputAcl as $k => $v) {
             if ($v == 'yes') {
                 unset($outputAcl[$k]);
             }
         }
     }
     $outputAcl['_hash'] = $this->hashChunk($outputAcl);
     return $outputAcl;
 }
Пример #2
0
 /**
  * Get the beans ACL's to pass back any that differ
  * @param  SugarBean $bean
  * @param  array     $fieldList
  * @return array
  */
 public function getBeanAcl(SugarBean $bean, array $fieldList)
 {
     $acl = array('fields' => (object) array());
     if (SugarACL::moduleSupportsACL($bean->module_dir)) {
         $mm = MetaDataManager::getManager($this->api->platform);
         $moduleAcl = $mm->getAclForModule($bean->module_dir, $this->api->user, false, true);
         $beanAcl = $mm->getAclForModule($bean->module_dir, $this->api->user, $bean, true);
         if ($beanAcl['_hash'] != $moduleAcl['_hash'] || !empty($fieldList)) {
             // diff the fields separately, they are usually empty anyway so we won't diff these often.
             $moduleAclFields = $moduleAcl['fields'];
             $beanAclFields = $beanAcl['fields'];
             // dont' need the fields here will append at the end
             unset($moduleAcl['fields']);
             unset($beanAcl['fields']);
             // don't need the hashes anymore
             unset($moduleAcl['_hash']);
             unset($beanAcl['_hash']);
             $acl = array_diff_assoc($beanAcl, $moduleAcl);
             $fieldAcls = array();
             /**
              * Fields are different than module level acces
              * if fields is empty that means all access is granted
              * beanAclFields is empty and moduleAclFields is empty -> all access -> return empty
              * beanAclFields is empty and moduleAclFields is !empty -> all access -> return yes's
              * beanAclFields is !empty and moduleAclFields is empty -> beanAclFields access restrictions -> return beanAclFields
              * beanAclFields is !empty and moduleAclFields is !empty -> return all access = "Yes" from moduleAcl and unset any in beanAcl that is in ModuleAcl [don't dupe data]
              */
             if (!empty($beanAclFields) && empty($moduleAclFields)) {
                 $fieldAcls = $beanAclFields;
             } elseif (!empty($beanAclFields) && !empty($moduleAclFields)) {
                 // we need the ones that are moduleAclFields but not in beanAclFields
                 foreach ($moduleAclFields as $field => $aclActions) {
                     foreach ($aclActions as $action => $access) {
                         if (!isset($beanAclFields[$field][$action])) {
                             $beanAclFields[$field][$action] = "yes";
                         }
                         // if the bean action is set and it matches the access from module, we do not need to send it down
                         if (isset($beanAclFields[$field][$action]) && $beanAclFields[$field][$action] == $access) {
                             unset($beanAclFields[$field][$action]);
                         }
                     }
                 }
                 // cleanup BeanAclFields, we don't want to pass a field that doens't have actions
                 foreach ($beanAclFields as $field => $actions) {
                     if (empty($actions)) {
                         unset($beanAclFields[$field]);
                     }
                 }
                 $fieldAcls = $beanAclFields;
             } elseif (empty($beanAclFields) && !empty($moduleAclFields)) {
                 // it is different because we now have access...
                 foreach ($moduleAclFields as $field => $aclActions) {
                     foreach ($aclActions as $action => $access) {
                         $fieldAcls[$field][$action] = "yes";
                     }
                 }
             }
             foreach ($fieldList as $fieldName) {
                 if (empty($fieldAcls[$fieldName]) && isset($moduleAclFields[$fieldName])) {
                     $fieldAcls[$fieldName] = $moduleAclFields[$fieldName];
                 }
             }
             $acl['fields'] = (object) $fieldAcls;
         }
     }
     return $acl;
 }
Пример #3
0
 /**
  * Check if module supports ACLs
  * @api
  * @param string $module
  * @return bool
  */
 public function moduleSupportsACL($module)
 {
     // FIXME: add support for non-bean ACLs
     if (!isset($GLOBALS['beanList'][$module])) {
         return false;
     }
     // Always use ACLs via SugarACL
     return SugarACL::moduleSupportsACL($module);
 }
Пример #4
0
 private function formatRequestData(SugarBean $bean, $event, array $arguments)
 {
     $data = array();
     $sfh = new SugarFieldHandler();
     $arguments['bean'] = get_class($bean);
     if (isset($bean->id)) {
         $data['id'] = $bean->id;
     }
     if (!SugarACL::moduleSupportsACL($bean->webhook_target_module) || $bean->ACLAccess('detail')) {
         $fieldList = $bean->field_defs;
         $this->ACLFilterFieldList($fieldList, array('bean' => $bean));
         $service = new RestService();
         foreach ($fieldList as $fieldName => $properties) {
             $fieldType = !empty($properties['custom_type']) ? $properties['custom_type'] : $properties['type'];
             $field = $sfh->getSugarField($fieldType);
             if ('link' !== $fieldType && !empty($field) && (isset($bean->{$fieldName}) || 'relate' === $fieldType)) {
                 $field->apiFormatField($data, $bean, array(), $fieldName, $properties, array(), $service);
             }
         }
     }
     $arguments['data'] = $data;
     $arguments['event'] = $event;
     return $arguments;
 }