Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

modules/UserPreferences/UserPreference.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
 *
7
 * This program is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU Affero General Public License version 3 as published by the
9
 * Free Software Foundation with the addition of the following permission added
10
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13
 *
14
 * This program is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17
 * details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License along with
20
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
 * 02110-1301 USA.
23
 *
24
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
26
 *
27
 * The interactive user interfaces in modified source and object code versions
28
 * of this program must display Appropriate Legal Notices, as required under
29
 * Section 5 of the GNU Affero General Public License version 3.
30
 *
31
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32
 * these Appropriate Legal Notices must retain the display of the "Powered by
33
 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34
 * technical reasons, the Appropriate Legal Notices must display the words
35
 * "Powered by SugarCRM".
36
 ********************************************************************************/
37
38
/*********************************************************************************
39
40
 * Description: Handles the User Preferences and stores them in a separate table.
41
 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
42
 * All Rights Reserved.
43
 * Contributor(s): ______________________________________..
44
 ********************************************************************************/
45
46
class UserPreference extends SugarBean
47
{
48
    public $db;
49
    public $field_name_map;
50
51
    // Stored fields
52
    public $id;
53
    public $date_entered;
54
    public $date_modified;
55
    public $assigned_user_id;
56
    public $assigned_user_name;
57
    public $name;
58
    public $category;
59
    public $contents;
60
    public $deleted;
61
62
    public $object_name = 'UserPreference';
63
    public $table_name = 'user_preferences';
64
65
    public $disable_row_level_security = true;
66
    public $module_dir = 'UserPreferences';
67
    public $field_defs = array();
68
    public $field_defs_map = array();
69
    public $new_schema = true;
70
71
    protected $_userFocus;
72
73
    // Do not actually declare, use the functions statically
74 158
    public function __construct(
75
        User $user = null
76
        )
77
    {
78 158
        parent::__construct();
79
80 158
        $this->_userFocus = $user;
81 158
        $this->tracker_visibility = false;
82 158
    }
83
84
    /**
85
     * Get preference by name and category. Lazy loads preferences from the database per category
86
     *
87
     * @param string $name name of the preference to retreive
88
     * @param string $category name of the category to retreive, defaults to global scope
89
     * @return mixed the value of the preference (string, array, int etc)
90
     */
91 212
    public function getPreference(
92
        $name,
93
        $category = 'global'
94
        )
95
    {
96 212
        global $sugar_config;
97
98 212
        $user = $this->_userFocus;
99
100
        // if the unique key in session doesn't match the app or prefereces are empty
101 212
        if(!isset($_SESSION[$user->user_name.'_PREFERENCES'][$category]) || (!empty($_SESSION['unique_key']) && $_SESSION['unique_key'] != $sugar_config['unique_key'])) {
102 212
            $this->loadPreferences($category);
103
        }
104 212
        if(isset($_SESSION[$user->user_name.'_PREFERENCES'][$category][$name])) {
105 6
            return $_SESSION[$user->user_name.'_PREFERENCES'][$category][$name];
106
        }
107
108
        // check to see if a default preference ( i.e. $sugar_config setting ) exists for this value )
109
        // if so, return it
110 212
        $value = $this->getDefaultPreference($name,$category);
111 212
        if ( !is_null($value) ) {
112 136
            return $value;
113
        }
114 196
        return null;
115
    }
116
117
    /**
118
     * Get preference by name and category from the system settings.
119
     *
120
     * @param string $name name of the preference to retreive
121
     * @param string $category name of the category to retreive, defaults to global scope
122
     * @return mixed the value of the preference (string, array, int etc)
123
     */
124 213
    public function getDefaultPreference(
125
        $name,
126
        $category = 'global'
127
        )
128
    {
129 213
        global $sugar_config;
130
131
        // Doesn't support any prefs but global ones
132 213
        if ( $category != 'global' )
133 34
            return null;
134
135
        // First check for name matching $sugar_config variable
136 205
        if ( isset($sugar_config[$name]) )
137 132
            return $sugar_config[$name];
138
139
        // Next, check to see if it's one of the common problem ones
140 186
        if ( isset($sugar_config['default_'.$name]) )
141 2
            return $sugar_config['default_'.$name];
142 186
        if ( $name == 'datef' )
143
            return $sugar_config['default_date_format'];
144 186
        if ( $name == 'timef' )
145
            return $sugar_config['default_time_format'];
146 186
        if ( $name == 'email_link_type' )
147 13
            return $sugar_config['email_default_client'];
148 179
    }
149
150
    /**
151
     * Set preference by name and category. Saving will be done in utils.php -> sugar_cleanup
152
     *
153
     * @param string $name name of the preference to retreive
154
     * @param mixed $value value of the preference to set
155
     * @param string $category name of the category to retreive, defaults to global scope
156
     */
157 14
    public function setPreference(
158
        $name,
159
        $value,
160
        $category = 'global'
161
        )
162
    {
163 14
        $user = $this->_userFocus;
164
165 14
        if ( empty($user->user_name) )
166 6
            return;
167
168 8
        if(!isset($_SESSION[$user->user_name.'_PREFERENCES'][$category])) {
169 5
            if(!$user->loadPreferences($category))
170 4
                $_SESSION[$user->user_name.'_PREFERENCES'][$category] = array();
171
        }
172
173
        // preferences changed or a new preference, save it to DB
174 8
        if(!isset($_SESSION[$user->user_name.'_PREFERENCES'][$category][$name])
175 8
            || (isset($_SESSION[$user->user_name.'_PREFERENCES'][$category][$name]) && $_SESSION[$user->user_name.'_PREFERENCES'][$category][$name] != $value)) {
176 8
                $GLOBALS['savePreferencesToDB'] = true;
177 8
                if(!isset($GLOBALS['savePreferencesToDBCats'])) $GLOBALS['savePreferencesToDBCats'] = array();
178 8
                $GLOBALS['savePreferencesToDBCats'][$category] = true;
179
        }
180
181 8
        $_SESSION[$user->user_name.'_PREFERENCES'][$category][$name] = $value;
182 8
    }
183
184
    /**
185
     * Loads preference by category from database. Saving will be done in utils.php -> sugar_cleanup
186
     *
187
     * @param string $category name of the category to retreive, defaults to global scope
188
     * @return bool successful?
189
     */
190 212
    public function loadPreferences(
191
        $category = 'global'
192
        )
193
    {
194 212
        global $sugar_config;
195
196 212
        $user = $this->_userFocus;
197
198 212
        if($user->object_name != 'User')
199
            return;
200 212
        if(!empty($user->id) && (!isset($_SESSION[$user->user_name . '_PREFERENCES'][$category]) || (!empty($_SESSION['unique_key']) && $_SESSION['unique_key'] != $sugar_config['unique_key']))) {
201
            // cn: moving this to only log when valid - throwing errors on install
202 19
            return $this->reloadPreferences($category);
203
        }
204 211
        return false;
205
    }
206
207
    /**
208
     * Unconditionally reloads user preferences from the DB and updates the session
209
     * @param string $category name of the category to retreive, defaults to global scope
210
     * @return bool successful?
211
     */
212 21
    public function reloadPreferences($category = 'global')
213
    {
214 21
        $user = $this->_userFocus;
215
216 21
        if($user->object_name != 'User' || empty($user->id) || empty($user->user_name)) {
217 2
            return false;
218
        }
219 20
        $GLOBALS['log']->debug('Loading Preferences DB ' . $user->user_name);
220 20
        if(!isset($_SESSION[$user->user_name . '_PREFERENCES'])) $_SESSION[$user->user_name . '_PREFERENCES'] = array();
221 20
        if(!isset($user->user_preferences) || !is_array($user->user_preferences)) $user->user_preferences = array();
222 20
        $result = $GLOBALS['db']->query("SELECT contents FROM user_preferences WHERE assigned_user_id='$user->id' AND category = '" . $category . "' AND deleted = 0", false, 'Failed to load user preferences');
223 20
        $row = $GLOBALS['db']->fetchByAssoc($result);
224 20
        if ($row) {
225 8
            $_SESSION[$user->user_name . '_PREFERENCES'][$category] = unserialize(base64_decode($row['contents']));
226 8
            $user->user_preferences[$category] = unserialize(base64_decode($row['contents']));
227 8
            return true;
228
        } else {
229 13
            $_SESSION[$user->user_name . '_PREFERENCES'][$category] = array();
230 13
            $user->user_preferences[$category] = array();
231
        }
232 13
        return false;
233
    }
234
235
    /**
236
     * Loads users timedate preferences
237
     *
238
     * @return array 'date' - date format for user ; 'time' - time format for user
239
     */
240 7
    public function getUserDateTimePreferences()
241
    {
242 7
        global $sugar_config, $db, $timedate, $current_user;
243
244 7
        $user = $this->_userFocus;
245
246 7
        $prefDate = array();
247
248 7
        if(!empty($user) && $this->loadPreferences('global')) {
249
            // forced to set this to a variable to compare b/c empty() wasn't working
250 1
            $timeZone = TimeDate::userTimezone($user);
251 1
            $timeFormat = $user->getPreference("timef");
252 1
            $dateFormat = $user->getPreference("datef");
253
254
            // cn: bug xxxx cron.php fails because of missing preference when admin hasn't logged in yet
255 1
            $timeZone = empty($timeZone) ? 'America/Los_Angeles' : $timeZone;
256
257 1
            if(empty($timeFormat)) $timeFormat = $sugar_config['default_time_format'];
258 1
            if(empty($dateFormat)) $dateFormat = $sugar_config['default_date_format'];
259
260 1
            $prefDate['date'] = $dateFormat;
261 1
            $prefDate['time'] = $timeFormat;
262 1
            $prefDate['userGmt'] = TimeDate::tzName($timeZone);
263 1
            $prefDate['userGmtOffset'] = $timedate->getUserUTCOffset($user);
264
265 1
            return $prefDate;
266
        } else {
267 6
            $prefDate['date'] = $timedate->get_date_format();
268 6
            $prefDate['time'] = $timedate->get_time_format();
269
270 6
            if(!empty($user) && $user->object_name == 'User') {
271 6
                $timeZone = TimeDate::userTimezone($user);
272
                // cn: bug 9171 - if user has no time zone, cron.php fails for InboundEmail
273 6
                if(!empty($timeZone)) {
274 6
                    $prefDate['userGmt'] = TimeDate::tzName($timeZone);
275 6
                    $prefDate['userGmtOffset'] = $timedate->getUserUTCOffset($user);
276
                }
277
            } else {
278
                $timeZone = TimeDate::userTimezone($current_user);
279
                if(!empty($timeZone)) {
280
                    $prefDate['userGmt'] = TimeDate::tzName($timeZone);
281
                    $prefDate['userGmtOffset'] = $timedate->getUserUTCOffset($current_user);
282
                }
283
            }
284
285 6
            return $prefDate;
286
        }
287
    }
288
289
    /**
290
     * Saves all preferences into the database that are in the session. Expensive, this is called by default in
291
     * sugar_cleanup if a setPreference has been called during one round trip.
292
     *
293
     * @global user will use current_user if no user specificed in $user param
294
     * @param user $user User object to retrieve, otherwise user current_user
0 ignored issues
show
There is no parameter named $user. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
295
     * @param bool $all save all of the preferences? (Dangerous)
296
     *
297
     */
298 6
    public function savePreferencesToDB(
299
        $all = false
300
        )
301
    {
302 6
        global $sugar_config;
303 6
        $GLOBALS['savePreferencesToDB'] = false;
304
305 6
        $user = $this->_userFocus;
306
307
        // these are not the preferences you are looking for [ hand waving ]
308 6
        if(empty($GLOBALS['installing']) && !empty($_SESSION['unique_key']) && $_SESSION['unique_key'] != $sugar_config['unique_key']) return;
309
310 6
        $GLOBALS['log']->debug('Saving Preferences to DB ' . $user->user_name);
311 6
        if(isset($_SESSION[$user->user_name. '_PREFERENCES']) && is_array($_SESSION[$user->user_name. '_PREFERENCES'])) {
312 3
             $GLOBALS['log']->debug("Saving Preferences to DB: {$user->user_name}");
313
            // only save the categories that have been modified or all?
314 3
            if(!$all && isset($GLOBALS['savePreferencesToDBCats']) && is_array($GLOBALS['savePreferencesToDBCats'])) {
315 3
                $catsToSave = array();
316 3
                foreach($GLOBALS['savePreferencesToDBCats'] as $category => $value) {
317 3
                    if ( isset($_SESSION[$user->user_name. '_PREFERENCES'][$category]) )
318 3
                        $catsToSave[$category] = $_SESSION[$user->user_name. '_PREFERENCES'][$category];
319
                }
320
            }
321
            else {
322
                $catsToSave = $_SESSION[$user->user_name. '_PREFERENCES'];
323
            }
324
325 3
            foreach ($catsToSave as $category => $contents) {
326 3
                $focus = new UserPreference($this->_userFocus);
327 3
                $result = $focus->retrieve_by_string_fields(array(
328 3
                    'assigned_user_id' => $user->id,
329 3
                    'category' => $category,
330
                    ));
331 3
                $focus->assigned_user_id = $user->id; // MFH Bug #13862
332 3
                $focus->deleted = 0;
333 3
                $focus->contents = base64_encode(serialize($contents));
334 3
                $focus->category = $category;
335 3
                $focus->save();
336
            }
337
        }
338 6
    }
339
340
    /**
341
     * Resets preferences for a particular user. If $category is null all user preferences will be reset
342
     *
343
     * @param string $category category to reset
344
     */
345 2
    public function resetPreferences(
346
        $category = null
347
        )
348
    {
349 2
        $user = $this->_userFocus;
350
351 2
        $GLOBALS['log']->debug('Reseting Preferences for user ' . $user->user_name);
352
353 2
        $remove_tabs = $this->getPreference('remove_tabs');
354 2
        $favorite_reports = $this->getPreference('favorites', 'Reports');
355 2
        $home_pages = $this->getPreference('pages', 'home');
356 2
        $home_dashlets = $this->getPreference('dashlets', 'home');
357 2
        $ut = $this->getPreference('ut');
358 2
        $timezone = $this->getPreference('timezone');
359
360 2
        $query = "UPDATE user_preferences SET deleted = 1 WHERE assigned_user_id = '" . $user->id . "'";
361 2
        if($category)
362
            $query .= " AND category = '" . $category . "'";
363 2
        $this->db->query($query);
364
365
366 2
        if($category) {
367
            unset($_SESSION[$user->user_name."_PREFERENCES"][$category]);
368
        }
369
        else {
370 2
        	if(!empty($_COOKIE['sugar_user_theme']) && !headers_sent()){
371
                setcookie('sugar_user_theme', '', time() - 3600,null,null,false,true); // expire the sugar_user_theme cookie
372
            }
373 2
            unset($_SESSION[$user->user_name."_PREFERENCES"]);
374 2
            if($user->id == $GLOBALS['current_user']->id) {
375
                session_destroy();
376
            }
377 2
            $this->setPreference('remove_tabs', $remove_tabs);
378 2
            $this->setPreference('favorites', $favorite_reports, 'Reports');
379 2
            $this->setPreference('pages', $home_pages, 'home');
380 2
            $this->setPreference('dashlets', $home_dashlets, 'home');
381 2
            $this->setPreference('ut', $ut);
382 2
            $this->setPreference('timezone', $timezone);
383 2
            $this->savePreferencesToDB();
384
        }
385 2
    }
386
387
    /**
388
     * Updates every user pref with a new key value supports 2 levels deep, use append to
389
     * array if you want to append the value to an array
390
     */
391
    public static function updateAllUserPrefs(
392
        $key,
393
        $new_value,
394
        $sub_key = '',
395
        $is_value_array = false,
396
        $unset_value = false )
397
    {
398
        global $current_user, $db;
399
400
        // Admin-only function; die if calling as a non-admin
401
        if(!is_admin($current_user)){
402
            sugar_die('only admins may call this function');
403
        }
404
405
        // we can skip this if we've already upgraded to the user_preferences format.
406
        if ( !array_key_exists('user_preferences',$db->getHelper()->get_columns('users')) )
407
            return;
408
409
        $result = $db->query("SELECT id, user_preferences, user_name FROM users");
410
        while ($row = $db->fetchByAssoc($result)) {
411
            $prefs = array();
412
            $newprefs = array();
413
414
            $prefs = unserialize(base64_decode($row['user_preferences']));
415
416
            if(!empty($sub_key)){
417
                if($is_value_array ){
418
                    if(!isset($prefs[$key][$sub_key])){
419
                        continue;
420
                    }
421
422
                    if(empty($prefs[$key][$sub_key])){
423
                        $prefs[$key][$sub_key] = array();
424
                    }
425
                    $already_exists = false;
426
                    foreach($prefs[$key][$sub_key] as $k=>$value){
427
                        if($value == $new_value){
428
429
                            $already_exists = true;
430
                            if($unset_value){
431
                                unset($prefs[$key][$sub_key][$k]);
432
                            }
433
                        }
434
                    }
435
                    if(!$already_exists && !$unset_value){
436
                        $prefs[$key][$sub_key][] = $new_value;
437
                    }
438
                }
439
                else{
440
                    if(!$unset_value)$prefs[$key][$sub_key] = $new_value;
441
                }
442
            }
443
            else{
444
                if($is_value_array ){
445
                    if(!isset($prefs[$key])){
446
                        continue;
447
                    }
448
449
                    if(empty($prefs[$key])){
450
                        $prefs[$key] = array();
451
                    }
452
                    $already_exists = false;
453
                    foreach($prefs[$key] as $k=>$value){
454
                        if($value == $new_value){
455
                            $already_exists = true;
456
457
                            if($unset_value){
458
                                unset($prefs[$key][$k]);
459
                            }
460
                        }
461
                    }
462
                    if(!$already_exists && !$unset_value){
463
464
                        $prefs[$key][] = $new_value;
465
                    }
466
                }else{
467
                    if(!$unset_value)$prefs[$key] = $new_value;
468
                }
469
            }
470
471
            $newstr = $GLOBALS['db']->quote(base64_encode(serialize($prefs)));
472
            $db->query("UPDATE users SET user_preferences = '{$newstr}' WHERE id = '{$row['id']}'");
473
        }
474
475
        unset($prefs);
476
        unset($newprefs);
477
        unset($newstr);
478
    }
479
480
}
481