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/ACLActions/ACLAction.php (7 issues)

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 1
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
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
/* BEGIN - SECURITY GROUPS */
41 1
if(file_exists("modules/ACLActions/actiondefs.override.php")){
42 1
	require_once("modules/ACLActions/actiondefs.override.php");
43
} else {
44
require_once('modules/ACLActions/actiondefs.php');
45
}
46
/* END - SECURITY GROUPS */
47
class ACLAction  extends SugarBean{
0 ignored issues
show
Expected 1 space after class name; 2 found
Loading history...
Expected 1 space before extends keyword; 2 found
Loading history...
48
    var $module_dir = 'ACLActions';
49
    var $object_name = 'ACLAction';
50
    var $table_name = 'acl_actions';
51
    var $new_schema = true;
52
    var $disable_custom_fields = true;
53
54 97
    public function __construct(){
55 97
        parent::__construct();
56 97
    }
57
58
    /**
59
     * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
60
     */
61
    public function ACLAction(){
62
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
63
        if(isset($GLOBALS['log'])) {
64
            $GLOBALS['log']->deprecated($deprecatedMessage);
65
        }
66
        else {
67
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
68
        }
69
        self::__construct();
70
    }
71
72
73
    /**
74
    * static addActions($category, $type='module')
75
    * Adds all default actions for a category/type
76
    *
77
    * @param STRING $category - the category (e.g module name - Accounts, Contacts)
78
    * @param STRING $type - the type (e.g. 'module', 'field')
79
    */
80 1
    static function addActions($category, $type='module'){
81 1
        global $ACLActions;
82 1
        $db = DBManagerFactory::getInstance();
83 1
        if(isset($ACLActions[$type])){
84 1
            foreach($ACLActions[$type]['actions'] as $action_name =>$action_def){
85
86 1
                $action = new ACLAction();
87 1
                $query = "SELECT * FROM " . $action->table_name . " WHERE name='$action_name' AND category = '$category' AND acltype='$type' AND deleted=0 ";
88 1
                $result = $db->query($query);
89
                //only add if an action with that name and category don't exist
90 1
                $row=$db->fetchByAssoc($result);
91 1
                if ($row == null) {
92 1
                    $action->name = $action_name;
93 1
                    $action->category = $category;
94 1
                    $action->aclaccess = $action_def['default'];
95 1
                    $action->acltype = $type;
96 1
                    $action->modified_user_id = 1;
97 1
                    $action->created_by = 1;
98 1
                    $action->save();
99
100
                }
101
            }
102
103
        }else{
104
            sugar_die("FAILED TO ADD: $category - TYPE $type NOT DEFINED IN modules/ACLActions/actiondefs.php");
105
        }
106
107 1
    }
108
109
    /**
110
    * static removeActions($category, $type='module')
111
    * Removes all default actions for a category/type
112
    *
113
    * @param STRING $category - the category (e.g module name - Accounts, Contacts)
114
    * @param STRING $type - the type (e.g. 'module', 'field')
115
    */
116 1
    public static function removeActions($category, $type='module'){
117 1
        global $ACLActions;
118 1
        $db = DBManagerFactory::getInstance();
119 1
        if(isset($ACLActions[$type])){
120 1
            foreach($ACLActions[$type]['actions'] as $action_name =>$action_def){
121
122 1
                $action = new ACLAction();
123 1
                $query = "SELECT * FROM " . $action->table_name . " WHERE name='$action_name' AND category = '$category' AND acltype='$type' and deleted=0";
124 1
                $result = $db->query($query);
125
                //only add if an action with that name and category don't exist
126 1
                $row=$db->fetchByAssoc($result);
127 1
                if ($row != null) {
128 1
                    $action->mark_deleted($row['id']);
129
                }
130
            }
131
        }else{
132
            sugar_die("FAILED TO REMOVE: $category : $name - TYPE $type NOT DEFINED IN modules/ACLActions/actiondefs.php");
133
        }
134 1
    }
135
136
    /**
137
    * static AccessColor($access)
138
    *
139
    * returns the color associated with an access level
140
    * these colors exist in the definitions in modules/ACLActions/actiondefs.php
141
    * @param INT $access - the access level you want the color for
142
    * @return the color either name or hex representation or false if the level does not exist
143
    */
144 1
    protected static function AccessColor($access){
145 1
        global $ACLActionAccessLevels;
146 1
        if(isset($ACLActionAccessLevels[$access])){
147
148
            return $ACLActionAccessLevels[$access]['color'];
149
        }
150 1
        return false;
151
152
    }
153
154
    /**
155
    * static AccessName($access)
156
    *
157
    * returns the translated name  associated with an access level
158
    * these label definitions  exist in the definitions in modules/ACLActions/actiondefs.php
159
    * @param INT $access - the access level you want the color for
160
    * @return the translated access level name or false if the level does not exist
161
    */
162 2
    static function AccessName($access){
163 2
        global $ACLActionAccessLevels;
164 2
        if(isset($ACLActionAccessLevels[$access])){
165 2
            return translate($ACLActionAccessLevels[$access]['label'], 'ACLActions');
166
        }
167 2
        return false;
168
169
    }
170
171
    /**
172
     * static AccessLabel($access)
173
     *
174
     * returns the label  associated with an access level
175
     * these label definitions  exist in the definitions in modules/ACLActions/actiondefs.php
176
     * @param INT $access - the access level you want the color for
177
     * @return the access level label or false if the level does not exist
178
     */
179 1
    protected static function AccessLabel($access){
180 1
        global $ACLActionAccessLevels;
181 1
        if(isset($ACLActionAccessLevels[$access])){
182
            $label=preg_replace('/(LBL_ACCESS_)(.*)/', '$2', $ACLActionAccessLevels[$access]['label']);
183
            return strtolower($label);
184
185
        }
186 1
        return false;
187
188
    }
189
190
    /**
191
    * static getAccessOptions()
192
    * this is used for building select boxes
193
    * @return array containg access levels (ints) as keys and access names as values
194
    */
195 1
    protected static function getAccessOptions( $action, $type='module'){
196 1
        global $ACLActions;
197 1
        $options = array();
198
199 1
        if(empty($ACLActions[$type]['actions'][$action]['aclaccess']))return $options;
200 1
        foreach($ACLActions[$type]['actions'][$action]['aclaccess'] as $action){
201 1
            $options[$action] = ACLAction::AccessName($action);
202
        }
203 1
        return $options;
204
205
    }
206
207
    /**
208
    * function static getDefaultActions()
209
    * This function will return a list of acl actions with their default access levels
210
    *
211
    *
212
    */
213 3
    public static function getDefaultActions($type='module', $action=''){
214 3
        $query = "SELECT * FROM acl_actions WHERE deleted=0 ";
215 3
        if(!empty($type)){
216 3
            $query .= " AND acltype='$type'";
217
        }
218 3
        if(!empty($action)){
219 1
            $query .= "AND name='$action'";
220
        }
221 3
        $query .= " ORDER BY category";
222
223 3
        $db = DBManagerFactory::getInstance();
224 3
        $result = $db->query($query);
225 3
        $default_actions = array();
226 3
        while($row = $db->fetchByAssoc($result) ){
227 3
            $acl = new ACLAction();
228 3
            $acl->populateFromRow($row);
229 3
            $default_actions[] = $acl;
230
        }
231 3
        return $default_actions;
232
    }
233
234
235
    /**
236
    * static getUserActions($user_id,$refresh=false, $category='', $action='')
237
    * returns a list of user actions
238
    * @param GUID $user_id
239
    * @param BOOLEAN $refresh
240
    * @param STRING $category
241
    * @param STRING $action
242
    * @return ARRAY of ACLActionsArray
243
    */
244
245 89
    static function getUserActions($user_id,$refresh=false, $category='',$type='', $action=''){
246
        //check in the session if we already have it loaded
247 89
        if(!$refresh && !empty($_SESSION['ACL'][$user_id])){
248 4
            if(empty($category) && empty($action)){
249 3
                return $_SESSION['ACL'][$user_id];
250
            }else{
251 1
                if(!empty($category) && isset($_SESSION['ACL'][$user_id][$category])){
252 1
                    if(empty($action)){
253 1
                        if(empty($type)){
254 1
                            return $_SESSION['ACL'][$user_id][$category];
255
                        }
256 1
                        return $_SESSION['ACL'][$user_id][$category][$type];
257
                    }else if(!empty($type) && isset($_SESSION['ACL'][$user_id][$category][$type][$action])){
258
                        return $_SESSION['ACL'][$user_id][$category][$type][$action];
259
                    }
260
                }
261
            }
262
        }
263
        //if we don't have it loaded then lets check against the db
264 89
        $additional_where = '';
265 89
        $db = DBManagerFactory::getInstance();
266 89
        if(!empty($category)){
267
            $additional_where .= " AND acl_actions.category = '$category' ";
268
        }
269 89
        if(!empty($action)){
270
            $additional_where .= " AND acl_actions.name = '$action' ";
271
        }
272 89
        if(!empty($type)){
273
            $additional_where .= " AND acl_actions.acltype = '$type' ";
274
        }
275
		/* BEGIN - SECURITY GROUPS */
276
		/**
277
        $query = "SELECT acl_actions .*, acl_roles_actions.access_override
278
                    FROM acl_actions
279
                    LEFT JOIN acl_roles_users ON acl_roles_users.user_id = '$user_id' AND  acl_roles_users.deleted = 0
280
                    LEFT JOIN acl_roles_actions ON acl_roles_actions.role_id = acl_roles_users.role_id AND acl_roles_actions.action_id = acl_actions.id AND acl_roles_actions.deleted=0
281
                    WHERE acl_actions.deleted=0 $additional_where ORDER BY category,name";
282
		*/
283
		$query = "(SELECT acl_actions .*, acl_roles_actions.access_override, 1 as user_role
284
				FROM acl_actions
285 89
				INNER JOIN acl_roles_users ON acl_roles_users.user_id = '$user_id' AND  acl_roles_users.deleted = 0
286
				LEFT JOIN acl_roles_actions ON acl_roles_actions.role_id = acl_roles_users.role_id AND acl_roles_actions.action_id = acl_actions.id AND acl_roles_actions.deleted=0
287 89
				WHERE acl_actions.deleted=0 $additional_where )
288
289
				UNION
290
291
				(SELECT acl_actions .*, acl_roles_actions.access_override, 0 as user_role
292
				FROM acl_actions
293 89
				INNER JOIN securitygroups_users ON securitygroups_users.user_id = '$user_id' AND  securitygroups_users.deleted = 0
294
				INNER JOIN securitygroups_acl_roles ON securitygroups_users.securitygroup_id = securitygroups_acl_roles.securitygroup_id and securitygroups_acl_roles.deleted = 0
295
				LEFT JOIN acl_roles_actions ON acl_roles_actions.role_id = securitygroups_acl_roles.role_id AND acl_roles_actions.action_id = acl_actions.id AND acl_roles_actions.deleted=0
296 89
				WHERE acl_actions.deleted=0 $additional_where )
297
298
				UNION
299
300
				(SELECT acl_actions.*, 0 as access_override, -1 as user_role
301
				FROM acl_actions
302
				WHERE acl_actions.deleted = 0 )
303
304 89
				ORDER BY user_role desc, category,name,access_override desc"; //want non-null to show first
305
		 /* END - SECURITY GROUPS */
306 89
        $result = $db->query($query);
307 89
        $selected_actions = array();
308
		/* BEGIN - SECURITY GROUPS */
309 89
		global $sugar_config;
310 89
		$has_user_role = false; //used for user_role_precedence
311 89
		$has_role = false; //used to determine if default actions can be ignored. If a user has a defined role don't use the defaults
312
		/* END - SECURITY GROUPS */
313 89
        while($row = $db->fetchByAssoc($result, FALSE) ){
314
			/* BEGIN - SECURITY GROUPS */
315 89
			if($has_user_role == false && $row['user_role'] == 1) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
316
				$has_user_role = true;
317
			}
318 89
			if($has_role == false && ($row['user_role'] == 1 || $row['user_role'] ==0)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
319
				$has_role = true;
320
			}
321
			//if user roles should take precedence over group roles and we have a user role
322
			//break when we get to processing the group roles
323 89
			if($has_user_role == true && $row['user_role'] == 0
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
324 89
					&& isset($sugar_config['securitysuite_user_role_precedence'])
325 89
					&& $sugar_config['securitysuite_user_role_precedence'] == true )
326
			{
327
				break;
328
			}
329 89
			if($row['user_role'] == -1 && $has_role == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
330
				break; //no need for default actions when a role is assigned to the user or user's group already
331
			}
332
			/* END - SECURITY GROUPS */
333 89
            $acl = new ACLAction();
334 89
            $isOverride  = false;
335 89
            $acl->populateFromRow($row);
336 89
            if(!empty($row['access_override'])){
337
                $acl->aclaccess = $row['access_override'];
338
                $isOverride = true;
339
            }
340 89
            if(!isset($selected_actions[$acl->category])){
341 89
                $selected_actions[$acl->category] = array();
342
343
            }
344 89
            if(!isset($selected_actions[$acl->category][$acl->acltype][$acl->name])
345
				|| (
346
					/* BEGIN - SECURITY GROUPS - additive security*/
347
					(
348
						(isset($sugar_config['securitysuite_additive']) && $sugar_config['securitysuite_additive'] == true
349
						&& $selected_actions[$acl->category][$acl->acltype][$acl->name]['aclaccess'] < $acl->aclaccess)
350
					||
351
						((!isset($sugar_config['securitysuite_additive']) || $sugar_config['securitysuite_additive'] == false)
352
						&& $selected_actions[$acl->category][$acl->acltype][$acl->name]['aclaccess'] > $acl->aclaccess)
353
					)
354
					/* END - SECURITY GROUPS */
355
                    && $isOverride
356
                    )
357
                ||
358
                    (!empty($selected_actions[$acl->category][$acl->acltype][$acl->name]['isDefault'])
359 89
                    && $isOverride
360
                    )
361
                )
362
            {
363
364
365 89
                $selected_actions[$acl->category][$acl->acltype][$acl->name] = $acl->toArray();
366 89
                $selected_actions[$acl->category][$acl->acltype][$acl->name]['isDefault'] = !$isOverride;
367
            }
368
369
        }
370
371
        //only set the session variable if it was a full list;
372 89
        if(empty($category) && empty($action)){
373 89
            if(!isset($_SESSION['ACL'])){
374 89
                $_SESSION['ACL'] = array();
375
            }
376 89
            $_SESSION['ACL'][$user_id] = $selected_actions;
377
        }else{
378
            if(empty($action) && !empty($category)){
379
                if(!empty($type)){
380
                    $_SESSION['ACL'][$user_id][$category][$type] = $selected_actions[$category][$type];}
381
                $_SESSION['ACL'][$user_id][$category] = $selected_actions[$category];
382
            }else{
383
                if(!empty($action) && !empty($category) && !empty($type)){
384
                $_SESSION['ACL'][$user_id][$category][$type][$action] = $selected_actions[$category][$action];
385
386
            }
387
            }
388
        }
389
390
        // Sort by translated categories
391 89
        uksort($selected_actions, "ACLAction::langCompare");
392 89
        return $selected_actions;
393
    }
394
395 89
    private static function langCompare($a, $b)
0 ignored issues
show
This method is not used, and could be removed.
Loading history...
396
    {
397 89
        global $app_list_strings;
398
        // Fallback to array key if translation is empty
399 89
        $a = empty($app_list_strings['moduleList'][$a]) ? $a : $app_list_strings['moduleList'][$a];
400 89
        $b = empty($app_list_strings['moduleList'][$b]) ? $b : $app_list_strings['moduleList'][$b];
401 89
        if ($a == $b)
402
            return 0;
403 89
        return ($a < $b) ? -1 : 1;
404
    }
405
406
    /**
407
    * (static/ non-static)function hasAccess($is_owner= false , $access = 0)
408
    * checks if a user has access to this acl if the user is an owner it will check if owners have access
409
    *
410
    * This function may either be used statically or not. If used staticlly a user must pass in an access level not equal to zero
411
    * @param boolean $is_owner
412
    * @param int $access
413
    * @return true or false
414
    */
415
	/* BEGIN - SECURITY GROUPS */
416
	/**
417
    static function hasAccess($is_owner=false, $access = 0){
418
	*/
419 48
	static function hasAccess($is_owner=false, $in_group=false, $access = 0, ACLAction $action = null){
420
		/**
421
        if($access != 0 && $access == ACL_ALLOW_ALL || ($is_owner && $access == ACL_ALLOW_OWNER))return true;
422
       //if this exists, then this function is not static, so check the aclaccess parameter
423
        if(isset($this) && isset($this->aclaccess)){
424
            if($this->aclaccess == ACL_ALLOW_ALL || ($is_owner && $this->aclaccess == ACL_ALLOW_OWNER))
425
            return true;
426
        }
427
		*/
428 48
		if($access != 0 && ($access == ACL_ALLOW_ALL
429 1
			|| ($is_owner && ($access == ACL_ALLOW_OWNER || $access == ACL_ALLOW_GROUP) )  //if owner that's better than in group so count it...better way to clean this up?
430 48
			|| ($in_group && $access == ACL_ALLOW_GROUP) //need to pass if in group with access somehow
431
		)) {
432 48
			return true;
433
		}
434 1
        if(!is_null($action) && isset($action->aclaccess)){
435
			if($action->aclaccess == ACL_ALLOW_ALL
436
				|| ($is_owner && $action->aclaccess == ($access == ACL_ALLOW_OWNER || $access == ACL_ALLOW_GROUP))
437
				|| ($in_group && $access == ACL_ALLOW_GROUP) //need to pass if in group with access somehow
438
			) {
439
            	return true;
440
        	}
441
		}
442 1
        return false;
443
    }
444
	/* END - SECURITY GROUPS */
445
446
	/* BEGIN - SECURITY GROUPS */
447
	/**
448
	 * STATIC function userNeedsSecurityGroup($user_id, $category, $action,$type='module')
449
	 * checks if a user should have ownership to do an action
450
	 *
451
	 * @param GUID $user_id
452
	 * @param STRING $category
453
	 * @param STRING $action
454
	 * @param STRING $type
455
	 * @return boolean
456
	 */
457 39
	static function userNeedsSecurityGroup($user_id, $category, $action,$type='module'){
458
		//check if we don't have it set in the cache if not lets reload the cache
459
460 39
		if(empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
461 2
			ACLAction::getUserActions($user_id, false);
462
463
		}
464
465 39
		if(!empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
466 39
			return $_SESSION['ACL'][$user_id][$category][$type][$action]['aclaccess'] == ACL_ALLOW_GROUP;
467
		}
468 1
        return false;
469
    }
470
	/* END - SECURITY GROUPS */
471
472
473
474
475
476
477
478
479
    /**
480
    * static function userHasAccess($user_id, $category, $action, $is_owner = false)
481
    *
482
    * @param GUID $user_id the user id who you want to check access for
483
    * @param STRING $category the category you would like to check access for
484
    * @param STRING $action the action of that category you would like to check access for
485
    * @param BOOLEAN OPTIONAL $is_owner if the object is owned by the user you are checking access for
486
    */
487
	/* BEGIN - SECURITY GROUPS - added $in_group */
488
	/**
489
    public static function userHasAccess($user_id, $category, $action,$type='module', $is_owner = false){
490
	*/
491 47
	public static function userHasAccess($user_id, $category, $action,$type='module', $is_owner = false, $in_group = false){
492 47
       global $current_user;
493 47
       if($current_user->isAdminForModule($category)&& !isset($_SESSION['ACL'][$user_id][$category][$type][$action]['aclaccess'])){
494
        return true;
495
        }
496
        //check if we don't have it set in the cache if not lets reload the cache
497 47
        if(ACLAction::getUserAccessLevel($user_id, $category, 'access', $type) < ACL_ALLOW_ENABLED) return false;
498 47
        if(empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
499
            ACLAction::getUserActions($user_id, false);
500
501
        }
502
503 47
        if(!empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
504
/**
505
            return ACLAction::hasAccess($is_owner, $_SESSION['ACL'][$user_id][$category][$type][$action]['aclaccess']);
506
*/
507 47
			return ACLAction::hasAccess($is_owner, $in_group, $_SESSION['ACL'][$user_id][$category][$type][$action]['aclaccess']);
508
        }
509
        return false;
510
511
    }
512
	/* END - SECURITY GROUPS */
513
    /**
514
    * function getUserAccessLevel($user_id, $category, $action,$type='module')
515
    * returns the access level for a given category and action
516
    *
517
    * @param GUID  $user_id
518
    * @param STRING $category
519
    * @param STRING $action
520
    * @param STRING $type
521
    * @return INT (ACCESS LEVEL)
522
    */
523 48
    public static function getUserAccessLevel($user_id, $category, $action,$type='module'){
524 48
        if(empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
525 43
            ACLAction::getUserActions($user_id, false);
526
527
        }
528 48
        if(!empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
529 48
            if (!empty($_SESSION['ACL'][$user_id][$category][$type]['admin']) && $_SESSION['ACL'][$user_id][$category][$type]['admin']['aclaccess'] >= ACL_ALLOW_ADMIN)
530
            {
531
                // If you have admin access for a module, all ACL's are allowed
532
                return $_SESSION['ACL'][$user_id][$category][$type]['admin']['aclaccess'];
533
            }
534 48
            return  $_SESSION['ACL'][$user_id][$category][$type][$action]['aclaccess'];
535
        }
536 1
    }
537
538
    /**
539
    * STATIC function userNeedsOwnership($user_id, $category, $action,$type='module')
540
    * checks if a user should have ownership to do an action
541
    *
542
    * @param GUID $user_id
543
    * @param STRING $category
544
    * @param STRING $action
545
    * @param STRING $type
546
    * @return boolean
547
    */
548 39
    public static function userNeedsOwnership($user_id, $category, $action,$type='module'){
549
        //check if we don't have it set in the cache if not lets reload the cache
550
551 39
        if(empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
552 30
            ACLAction::getUserActions($user_id, false);
553
554
        }
555
556
557 39
        if(!empty($_SESSION['ACL'][$user_id][$category][$type][$action])){
558 39
            return $_SESSION['ACL'][$user_id][$category][$type][$action]['aclaccess'] == ACL_ALLOW_OWNER;
559
        }
560 1
        return false;
561
562
    }
563
    /**
564
    *
565
    * static pass by ref setupCategoriesMatrix(&$categories)
566
    * takes in an array of categories and modifes them adding display information
567
    *
568
    * @param unknown_type $categories
569
    */
570 1
    public static function setupCategoriesMatrix(&$categories){
571 1
        global $ACLActions, $current_user;
572 1
        $names = array();
573 1
        $disabled = array();
574 1
        foreach($categories as $cat_name=>$category){
575 1
            foreach($category as $type_name=>$type){
576 1
                foreach($type as $act_name=>$action){
577 1
                    $names[$act_name] = translate($ACLActions[$type_name]['actions'][$act_name]['label'], 'ACLActions');
578 1
                    $categories[$cat_name][$type_name][$act_name]['accessColor'] = ACLAction::AccessColor($action['aclaccess']);
579 1
                    if($type_name== 'module'){
580
581 1
                        if($act_name != 'aclaccess' && $categories[$cat_name]['module']['access']['aclaccess'] == ACL_ALLOW_DISABLED){
582
                            $categories[$cat_name][$type_name][$act_name]['accessColor'] = 'darkgray';
583
                            $disabled[] = $cat_name;
584
                        }
585
586
                    }
587 1
                    $categories[$cat_name][$type_name][$act_name]['accessName'] = ACLAction::AccessName($action['aclaccess']);
588 1
                    $categories[$cat_name][$type_name][$act_name]['accessLabel'] = ACLAction::AccessLabel($action['aclaccess']);
589
590 1
                    if($cat_name=='Users'&& $act_name=='admin'){
591
                        $categories[$cat_name][$type_name][$act_name]['accessOptions'][ACL_ALLOW_DEFAULT]=ACLAction::AccessName(ACL_ALLOW_DEFAULT);;
592
                        $categories[$cat_name][$type_name][$act_name]['accessOptions'][ACL_ALLOW_DEV]=ACLAction::AccessName(ACL_ALLOW_DEV);;
593
                    }
594
                    else{
595 1
                    $categories[$cat_name][$type_name][$act_name]['accessOptions'] =  ACLAction::getAccessOptions($act_name, $type_name);
596
                    }
597
                }
598
            }
599
        }
600
601 1
        if(!is_admin($current_user)){
602 1
            foreach($disabled as $cat_name){
603
                unset($categories[$cat_name]);
604
            }
605
        }
606 1
        return $names;
607
    }
608
609
610
611
    /**
612
    * function toArray()
613
    * returns this acl as an array
614
    *
615
    * @return array of fields with id, name, access and category
616
    */
617 91
    function toArray($dbOnly = false, $stringOnly = false, $upperKeys = false){
618 91
        $array_fields = array('id', 'aclaccess');
619 91
        $arr = array();
620 91
        foreach($array_fields as $field){
621 91
            $arr[$field] = $this->$field;
622
        }
623 91
        return $arr;
624
    }
625
626
    /**
627
    * function fromArray($arr)
628
    * converts an array into an acl mapping name value pairs into files
629
    *
630
    * @param Array $arr
631
    */
632 1
    function fromArray($arr){
633 1
        foreach($arr as $name=>$value){
634 1
            $this->$name = $value;
635
        }
636 1
    }
637
638
    /**
639
    * function clearSessionCache()
640
    * clears the session variable storing the cache information for acls
641
    *
642
    */
643 1
    function clearSessionCache(){
644 1
        unset($_SESSION['ACL']);
645 1
    }
646
647
648
649
650
651
652
653
654
655
656
657
658
659
}
660