1<?php declare(strict_types = 1);
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * A class designed to perform actions related to check access of roles.
24 */
25class CRoleHelper {
26
27	public const UI_MONITORING_DASHBOARD = 'ui.monitoring.dashboard';
28	public const UI_MONITORING_PROBLEMS = 'ui.monitoring.problems';
29	public const UI_MONITORING_HOSTS = 'ui.monitoring.hosts';
30	public const UI_MONITORING_OVERVIEW = 'ui.monitoring.overview';
31	public const UI_MONITORING_LATEST_DATA = 'ui.monitoring.latest_data';
32	public const UI_MONITORING_MAPS = 'ui.monitoring.maps';
33	public const UI_MONITORING_DISCOVERY = 'ui.monitoring.discovery';
34	public const UI_MONITORING_SERVICES = 'ui.monitoring.services';
35	public const UI_INVENTORY_OVERVIEW = 'ui.inventory.overview';
36	public const UI_INVENTORY_HOSTS = 'ui.inventory.hosts';
37	public const UI_REPORTS_SYSTEM_INFO = 'ui.reports.system_info';
38	public const UI_REPORTS_AVAILABILITY_REPORT = 'ui.reports.availability_report';
39	public const UI_REPORTS_TOP_TRIGGERS = 'ui.reports.top_triggers';
40	public const UI_REPORTS_AUDIT = 'ui.reports.audit';
41	public const UI_REPORTS_ACTION_LOG = 'ui.reports.action_log';
42	public const UI_REPORTS_NOTIFICATIONS = 'ui.reports.notifications';
43	public const UI_REPORTS_SCHEDULED_REPORTS = 'ui.reports.scheduled_reports';
44	public const UI_CONFIGURATION_HOST_GROUPS = 'ui.configuration.host_groups';
45	public const UI_CONFIGURATION_TEMPLATES = 'ui.configuration.templates';
46	public const UI_CONFIGURATION_HOSTS = 'ui.configuration.hosts';
47	public const UI_CONFIGURATION_MAINTENANCE = 'ui.configuration.maintenance';
48	public const UI_CONFIGURATION_ACTIONS = 'ui.configuration.actions';
49	public const UI_CONFIGURATION_EVENT_CORRELATION = 'ui.configuration.event_correlation';
50	public const UI_CONFIGURATION_DISCOVERY = 'ui.configuration.discovery';
51	public const UI_CONFIGURATION_SERVICES = 'ui.configuration.services';
52	public const UI_ADMINISTRATION_GENERAL = 'ui.administration.general';
53	public const UI_ADMINISTRATION_PROXIES = 'ui.administration.proxies';
54	public const UI_ADMINISTRATION_AUTHENTICATION = 'ui.administration.authentication';
55	public const UI_ADMINISTRATION_USER_GROUPS = 'ui.administration.user_groups';
56	public const UI_ADMINISTRATION_USER_ROLES = 'ui.administration.user_roles';
57	public const UI_ADMINISTRATION_USERS = 'ui.administration.users';
58	public const UI_ADMINISTRATION_MEDIA_TYPES = 'ui.administration.media_types';
59	public const UI_ADMINISTRATION_SCRIPTS = 'ui.administration.scripts';
60	public const UI_ADMINISTRATION_QUEUE = 'ui.administration.queue';
61	public const UI_DEFAULT_ACCESS = 'ui.default_access';
62	public const MODULES_MODULE = 'modules.module.';
63	public const MODULES_DEFAULT_ACCESS = 'modules.default_access';
64	public const API_ACCESS = 'api.access';
65	public const API_ACCESS_DISABLED = 0;
66	public const API_ACCESS_ENABLED = 1;
67	public const API_MODE = 'api.mode';
68	public const API_MODE_DENY = 0;
69	public const API_MODE_ALLOW = 1;
70	public const API_METHOD = 'api.method.';
71	public const ACTIONS_EDIT_DASHBOARDS = 'actions.edit_dashboards';
72	public const ACTIONS_EDIT_MAPS = 'actions.edit_maps';
73	public const ACTIONS_EDIT_MAINTENANCE = 'actions.edit_maintenance';
74	public const ACTIONS_ADD_PROBLEM_COMMENTS = 'actions.add_problem_comments';
75	public const ACTIONS_CHANGE_SEVERITY = 'actions.change_severity';
76	public const ACTIONS_ACKNOWLEDGE_PROBLEMS = 'actions.acknowledge_problems';
77	public const ACTIONS_CLOSE_PROBLEMS = 'actions.close_problems';
78	public const ACTIONS_EXECUTE_SCRIPTS = 'actions.execute_scripts';
79	public const ACTIONS_MANAGE_API_TOKENS = 'actions.manage_api_tokens';
80	public const ACTIONS_MANAGE_SCHEDULED_REPORTS = 'actions.manage_scheduled_reports';
81	public const ACTIONS_DEFAULT_ACCESS = 'actions.default_access';
82	public const DEFAULT_ACCESS_DISABLED = 0;
83	public const DEFAULT_ACCESS_ENABLED = 1;
84
85	public const SECTION_UI = 'ui';
86	public const SECTION_MODULES = 'modules';
87	public const SECTION_API = 'api';
88	public const SECTION_ACTIONS = 'actions';
89
90	public const UI_SECTION_MONITORING = 'ui.monitoring';
91	public const UI_SECTION_INVENTORY = 'ui.inventory';
92	public const UI_SECTION_REPORTS = 'ui.reports';
93	public const UI_SECTION_CONFIGURATION = 'ui.configuration';
94	public const UI_SECTION_ADMINISTRATION = 'ui.administration';
95
96	public const API_WILDCARD = '*';
97	public const API_WILDCARD_ALIAS = '*.*';
98	public const API_ANY_METHOD = '.*';
99	public const API_ANY_SERVICE = '*.';
100
101	/**
102	 * Array for storing roles data (including rules) loaded from Role API object and converted to one format. The data
103	 * of specific role can be accessed in following way: self::roles[{role ID}].
104	 *
105	 * @static
106	 *
107	 * @var array
108	 */
109	private static $roles = [];
110
111	/**
112	 * Array for storing all API methods by user type.
113	 *
114	 * @var array
115	 */
116	private static $api_methods = [];
117
118	/**
119	 * Array for storing all API methods with masks by user type.
120	 *
121	 * @var array
122	 */
123	private static $api_method_masks = [];
124
125	/**
126	 * Checks the access of specific role to specific rule.
127	 *
128	 * @static
129	 *
130	 * @param string  $rule_name  Name of the rule to check access for.
131	 * @param integer $roleid     ID of the role where check of access is necessary to perform.
132	 *
133	 * @return bool  Returns true if role have access to specified rule, false - otherwise.
134	 */
135	public static function checkAccess(string $rule_name, $roleid): bool {
136		self::loadRoleRules($roleid);
137
138		if (!array_key_exists($rule_name, self::$roles[$roleid]['rules']) || $rule_name === self::SECTION_API) {
139			return false;
140		}
141
142		return self::$roles[$roleid]['rules'][$rule_name];
143	}
144
145	/**
146	 * Check rule can be defined for specific role type.
147	 *
148	 * @param string $rule_name  Rule full name, with section prefix.
149	 * @param int    $role_type  Role access type.
150	 *
151	 * @return bool
152	 */
153	public static function checkRuleAllowedByType($rule_name, int $role_type): bool {
154		$allowed = [
155			self::UI_DEFAULT_ACCESS, self::API_ACCESS, self::API_MODE, self::MODULES_DEFAULT_ACCESS,
156			self::ACTIONS_DEFAULT_ACCESS
157		];
158
159		if (in_array($rule_name, $allowed)) {
160			return true;
161		}
162
163		switch (self::getRuleSection($rule_name)) {
164			case self::SECTION_UI:
165				$allowed = self::getAllUiElements($role_type);
166				break;
167
168			case self::SECTION_API:
169				$allowed = self::getApiMethods($role_type);
170				break;
171
172			case self::SECTION_MODULES:
173				$allowed = [$rule_name];
174				break;
175
176			case self::SECTION_ACTIONS:
177				$allowed = self::getAllActions($role_type);
178				break;
179		}
180
181		return in_array($rule_name, $allowed);
182	}
183
184	/**
185	 * Gets list of API methods (with wildcards if that exists) that are considered allowed or denied (depending from
186	 * API access mode) for specific role.
187	 *
188	 * @static
189	 *
190	 * @param integer $roleid  Role ID.
191	 *
192	 * @return array  Returns the array of API methods.
193	 */
194	public static function getRoleApiMethods(int $roleid): array {
195		self::loadRoleRules($roleid);
196
197		return self::$roles[$roleid]['rules'][self::SECTION_API];
198	}
199
200	/**
201	 * Loads once all rules of specified Role API object by ID and converts rule data to one format.
202	 *
203	 * @static
204	 *
205	 * @throws Exception
206	 *
207	 * @param integer $roleid  Role ID.
208	 */
209	private static function loadRoleRules($roleid): void {
210		if (array_key_exists($roleid, self::$roles)) {
211			return;
212		}
213
214		$roles = API::Role()->get([
215			'output' => ['roleid', 'name', 'type'],
216			'selectRules' => ['ui', 'ui.default_access', 'modules', 'modules.default_access', 'api.access', 'api.mode',
217				'api', 'actions', 'actions.default_access'
218			],
219			'roleids' => $roleid
220		]);
221
222		if ($roles === false) {
223			throw new Exception(_('Specified role was not found.'));
224		}
225
226		$role = $roles[0];
227
228		$rules = [
229			self::UI_DEFAULT_ACCESS => (bool) $role['rules'][self::UI_DEFAULT_ACCESS],
230			self::MODULES_DEFAULT_ACCESS => (bool) $role['rules'][self::MODULES_DEFAULT_ACCESS],
231			self::API_ACCESS => (bool) $role['rules'][self::API_ACCESS],
232			self::API_MODE => (bool) $role['rules'][self::API_MODE],
233			self::SECTION_API => $role['rules'][self::SECTION_API],
234			self::ACTIONS_DEFAULT_ACCESS => (bool) $role['rules'][self::ACTIONS_DEFAULT_ACCESS]
235		];
236
237		foreach ($role['rules'][self::SECTION_UI] as $rule) {
238			$rules[self::SECTION_UI.'.'.$rule['name']] = (bool) $rule['status'];
239		}
240
241		foreach ($role['rules'][self::SECTION_MODULES] as $module) {
242			$rules[self::MODULES_MODULE.$module['moduleid']] = (bool) $module['status'];
243		}
244
245		foreach ($role['rules'][self::SECTION_ACTIONS] as $rule) {
246			$rules[self::SECTION_ACTIONS.'.'.$rule['name']] = (bool) $rule['status'];
247		}
248
249		$role['type'] = (int) $role['type'];
250		$role['rules'] = $rules;
251
252		self::$roles[$roleid] = $role;
253	}
254
255	/**
256	 * Gets the section name of specific rule name.
257	 *
258	 * @static
259	 *
260	 * @throws Exception
261	 *
262	 * @param string $rule_name  Rule name.
263	 *
264	 * @return array Returns name of rules section.
265	 */
266	public static function getRuleSection(string $rule_name): string {
267		$section = explode('.', $rule_name, 2)[0];
268		if (in_array($section, [self::SECTION_UI, self::SECTION_MODULES, self::SECTION_API, self::SECTION_ACTIONS])) {
269			return $section;
270		}
271
272		throw new Exception(_('Rule section was not found.'));
273	}
274
275	/**
276	 * Gets all available UI elements rules for specific user type.
277	 *
278	 * @static
279	 *
280	 * @param integer $user_type  User type.
281	 *
282	 * @return array  Returns the array of rule names for specified user type.
283	 */
284	public static function getAllUiElements(int $user_type): array {
285		$rules = [
286			self::UI_MONITORING_DASHBOARD, self::UI_MONITORING_PROBLEMS, self::UI_MONITORING_HOSTS,
287			self::UI_MONITORING_OVERVIEW, self::UI_MONITORING_LATEST_DATA, self::UI_MONITORING_MAPS,
288			self::UI_MONITORING_SERVICES, self::UI_INVENTORY_OVERVIEW, self::UI_INVENTORY_HOSTS,
289			self::UI_REPORTS_AVAILABILITY_REPORT, self::UI_REPORTS_TOP_TRIGGERS
290		];
291
292		if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
293			$rules = array_merge($rules, [
294				self::UI_MONITORING_DISCOVERY, self::UI_REPORTS_NOTIFICATIONS, self::UI_REPORTS_SCHEDULED_REPORTS,
295				self::UI_CONFIGURATION_HOST_GROUPS, self::UI_CONFIGURATION_TEMPLATES, self::UI_CONFIGURATION_HOSTS,
296				self::UI_CONFIGURATION_MAINTENANCE, self::UI_CONFIGURATION_ACTIONS, self::UI_CONFIGURATION_DISCOVERY,
297				self::UI_CONFIGURATION_SERVICES
298			]);
299		}
300
301		if ($user_type === USER_TYPE_SUPER_ADMIN) {
302			$rules = array_merge($rules, [
303				self::UI_REPORTS_SYSTEM_INFO, self::UI_REPORTS_AUDIT, self::UI_REPORTS_ACTION_LOG,
304				self::UI_CONFIGURATION_EVENT_CORRELATION, self::UI_ADMINISTRATION_GENERAL, self::UI_ADMINISTRATION_PROXIES,
305				self::UI_ADMINISTRATION_AUTHENTICATION, self::UI_ADMINISTRATION_USER_GROUPS,
306				self::UI_ADMINISTRATION_USER_ROLES, self::UI_ADMINISTRATION_USERS, self::UI_ADMINISTRATION_MEDIA_TYPES,
307				self::UI_ADMINISTRATION_SCRIPTS, self::UI_ADMINISTRATION_QUEUE
308			]);
309		}
310
311		return $rules;
312	}
313
314	/**
315	 * Gets all available actions rules for specific user type.
316	 *
317	 * @static
318	 *
319	 * @param integer $user_type  User type.
320	 *
321	 * @return array  Returns the array of rule names for specified user type.
322	 */
323	public static function getAllActions(int $user_type): array {
324		$rules = [
325			self::ACTIONS_EDIT_DASHBOARDS, self::ACTIONS_EDIT_MAPS, self::ACTIONS_ACKNOWLEDGE_PROBLEMS,
326			self::ACTIONS_CLOSE_PROBLEMS, self::ACTIONS_CHANGE_SEVERITY, self::ACTIONS_ADD_PROBLEM_COMMENTS,
327			self::ACTIONS_EXECUTE_SCRIPTS, self::ACTIONS_MANAGE_API_TOKENS
328		];
329
330		if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
331			$rules[] = self::ACTIONS_EDIT_MAINTENANCE;
332			$rules[] = self::ACTIONS_MANAGE_SCHEDULED_REPORTS;
333		}
334
335		return $rules;
336	}
337
338	/**
339	 * Gets labels of all available UI sections for specific user type in order as it need to display in UI.
340	 *
341	 * @static
342	 *
343	 * @param integer $user_type  User type.
344	 *
345	 * @return array  Returns the array where key of each element is UI section name and value is UI section label.
346	 */
347	public static function getUiSectionsLabels(int $user_type): array {
348		$sections = [
349			self::UI_SECTION_MONITORING => _('Monitoring'),
350			self::UI_SECTION_INVENTORY => _('Inventory'),
351			self::UI_SECTION_REPORTS => _('Reports')
352		];
353
354		if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
355			$sections += [self::UI_SECTION_CONFIGURATION => _('Configuration')];
356		}
357
358		if ($user_type === USER_TYPE_SUPER_ADMIN) {
359			$sections += [self::UI_SECTION_ADMINISTRATION => _('Administration')];
360		}
361
362		return $sections;
363	}
364
365	/**
366	 * Gets labels of all available rules for specific UI section and user type in order as it need to display in UI.
367	 *
368	 * @static
369	 *
370	 * @param string  $ui_section_name  UI section name.
371	 * @param integer $user_type        User type.
372	 *
373	 * @return array  Returns the array where key of each element is rule name and value is rule label.
374	 */
375	public static function getUiSectionRulesLabels(string $ui_section_name, int $user_type): array {
376		switch ($ui_section_name) {
377			case self::UI_SECTION_MONITORING:
378				$labels = [
379					self::UI_MONITORING_DASHBOARD => _('Dashboard'),
380					self::UI_MONITORING_PROBLEMS => _('Problems'),
381					self::UI_MONITORING_HOSTS => _('Hosts'),
382					self::UI_MONITORING_OVERVIEW => _('Overview'),
383					self::UI_MONITORING_LATEST_DATA => _('Latest data'),
384					self::UI_MONITORING_MAPS => _('Maps')
385				];
386
387				if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
388					$labels += [self::UI_MONITORING_DISCOVERY => _('Discovery')];
389				}
390
391				$labels += [self::UI_MONITORING_SERVICES => _('Services')];
392
393				return $labels;
394			case self::UI_SECTION_INVENTORY:
395				return [
396					self::UI_INVENTORY_OVERVIEW => _('Overview'),
397					self::UI_INVENTORY_HOSTS => _('Hosts')
398				];
399			case self::UI_SECTION_REPORTS:
400				$labels = [];
401
402				if ($user_type === USER_TYPE_SUPER_ADMIN) {
403					$labels += [self::UI_REPORTS_SYSTEM_INFO => _('System information')];
404				}
405
406				$labels += [
407					self::UI_REPORTS_AVAILABILITY_REPORT => _('Availability report'),
408					self::UI_REPORTS_TOP_TRIGGERS => _('Triggers top 100')
409				];
410
411				if ($user_type === USER_TYPE_SUPER_ADMIN) {
412					$labels += [
413						self::UI_REPORTS_AUDIT => _('Audit'),
414						self::UI_REPORTS_ACTION_LOG => _('Action log')
415					];
416				}
417
418				if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
419					$labels += [
420						self::UI_REPORTS_NOTIFICATIONS => _('Notifications'),
421						self::UI_REPORTS_SCHEDULED_REPORTS => _('Scheduled reports')
422					];
423				}
424
425				return $labels;
426			case self::UI_SECTION_CONFIGURATION:
427				$labels = [];
428
429				if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
430					$labels = [
431						self::UI_CONFIGURATION_HOST_GROUPS => _('Host groups'),
432						self::UI_CONFIGURATION_TEMPLATES => _('Templates'),
433						self::UI_CONFIGURATION_HOSTS => _('Hosts'),
434						self::UI_CONFIGURATION_MAINTENANCE => _('Maintenance'),
435						self::UI_CONFIGURATION_ACTIONS => _('Actions')
436					];
437				}
438
439				if ($user_type === USER_TYPE_SUPER_ADMIN) {
440					$labels += [self::UI_CONFIGURATION_EVENT_CORRELATION => _('Event correlation')];
441				}
442
443				if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
444					$labels += [
445						self::UI_CONFIGURATION_DISCOVERY => _('Discovery'),
446						self::UI_CONFIGURATION_SERVICES => _('Services')
447					];
448				}
449
450				return $labels;
451			case self::UI_SECTION_ADMINISTRATION:
452				$labels = [];
453
454				if ($user_type === USER_TYPE_SUPER_ADMIN) {
455					$labels = [
456						self::UI_ADMINISTRATION_GENERAL => _('General'),
457						self::UI_ADMINISTRATION_PROXIES => _('Proxies'),
458						self::UI_ADMINISTRATION_AUTHENTICATION => _('Authentication'),
459						self::UI_ADMINISTRATION_USER_GROUPS => _('User groups'),
460						self::UI_ADMINISTRATION_USER_ROLES => _('User roles'),
461						self::UI_ADMINISTRATION_USERS => _('Users'),
462						self::UI_ADMINISTRATION_MEDIA_TYPES => _('Media types'),
463						self::UI_ADMINISTRATION_SCRIPTS => _('Scripts'),
464						self::UI_ADMINISTRATION_QUEUE => _('Queue')
465					];
466				}
467
468				return $labels;
469			default:
470				return [];
471		}
472	}
473
474	/**
475	 * Gets labels of all available actions rules for specific user type in order as it need to display on user roles
476	 * page.
477	 *
478	 * @static
479	 *
480	 * @param integer $user_type  User type.
481	 *
482	 * @return array  Returns the array where key of each element is rule name and value is rule label.
483	 */
484	public static function getActionsLabels(int $user_type): array {
485		$labels = [
486			self::ACTIONS_EDIT_DASHBOARDS => _('Create and edit dashboards'),
487			self::ACTIONS_EDIT_MAPS => _('Create and edit maps')
488		];
489
490		if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
491			$labels += [self::ACTIONS_EDIT_MAINTENANCE => _('Create and edit maintenance')];
492		}
493
494		$labels += [
495			self::ACTIONS_ADD_PROBLEM_COMMENTS => _('Add problem comments'),
496			self::ACTIONS_CHANGE_SEVERITY => _('Change severity'),
497			self::ACTIONS_ACKNOWLEDGE_PROBLEMS => _('Acknowledge problems'),
498			self::ACTIONS_CLOSE_PROBLEMS => _('Close problems'),
499			self::ACTIONS_EXECUTE_SCRIPTS => _('Execute scripts'),
500			self::ACTIONS_MANAGE_API_TOKENS => _('Manage API tokens')
501		];
502
503		if ($user_type === USER_TYPE_ZABBIX_ADMIN || $user_type === USER_TYPE_SUPER_ADMIN) {
504			$labels += [self::ACTIONS_MANAGE_SCHEDULED_REPORTS => _('Manage scheduled reports')];
505		}
506
507		return $labels;
508	}
509
510	/**
511	 * Returns a list of all API methods by user type or API methods available only for the given user type.
512	 *
513	 * @static
514	 *
515	 * @param int|null $user_type
516	 *
517	 * @return array
518	 */
519	public static function getApiMethods(?int $user_type = null): array {
520		if (!self::$api_methods) {
521			self::loadApiMethods();
522		}
523
524		return ($user_type !== null) ? self::$api_methods[$user_type] : self::$api_methods;
525	}
526
527	/**
528	 * Returns a list of API methods with masks for the given user type.
529	 *
530	 * @static
531	 *
532	 * @param int|null $user_type
533	 *
534	 * @return array
535	 */
536	public static function getApiMethodMasks(?int $user_type = null): array {
537		if (!self::$api_method_masks) {
538			self::loadApiMethods();
539		}
540
541		return ($user_type !== null) ? self::$api_method_masks[$user_type] : self::$api_method_masks;
542	}
543
544	/**
545	 * Returns a list of API methods for each method mask for the given user type.
546	 *
547	 * @static
548	 *
549	 * @param int $user_type
550	 *
551	 * @return array
552	 */
553	public static function getApiMaskMethods(int $user_type): array {
554		$api_methods = self::getApiMethods($user_type);
555		$result = [self::API_WILDCARD => $api_methods, self::API_WILDCARD_ALIAS => $api_methods];
556
557		foreach ($api_methods as &$api_method) {
558			[$service, $method] = explode('.', $api_method, 2);
559			$result[$service.self::API_ANY_METHOD][] = $api_method;
560			$result[self::API_ANY_SERVICE.$method][] = $api_method;
561		}
562		unset($api_method);
563
564		return $result;
565	}
566
567	/**
568	 * Collects all API methods for all user types.
569	 *
570	 * @static
571	 */
572	private static function loadApiMethods(): void {
573		$api_methods = [
574			USER_TYPE_ZABBIX_USER => [],
575			USER_TYPE_ZABBIX_ADMIN => [],
576			USER_TYPE_SUPER_ADMIN => []
577		];
578		$api_method_masks = $api_methods;
579
580		foreach (CApiServiceFactory::API_SERVICES as $service => $class_name) {
581			foreach (constant($class_name.'::ACCESS_RULES') as $method => $rules) {
582				if ($method === 'validateoperationsintegrity') {
583					continue;
584				}
585
586				if (array_key_exists('min_user_type', $rules)) {
587					switch ($rules['min_user_type']) {
588						case USER_TYPE_ZABBIX_USER:
589							$api_methods[USER_TYPE_ZABBIX_USER][] = $service.'.'.$method;
590							$api_method_masks[USER_TYPE_ZABBIX_USER][$service.self::API_ANY_METHOD] = true;
591							$api_method_masks[USER_TYPE_ZABBIX_USER][self::API_ANY_SERVICE.$method] = true;
592							// break; is not missing here
593						case USER_TYPE_ZABBIX_ADMIN:
594							$api_methods[USER_TYPE_ZABBIX_ADMIN][] = $service.'.'.$method;
595							$api_method_masks[USER_TYPE_ZABBIX_ADMIN][$service.self::API_ANY_METHOD] = true;
596							$api_method_masks[USER_TYPE_ZABBIX_ADMIN][self::API_ANY_SERVICE.$method] = true;
597							// break; is not missing here
598						case USER_TYPE_SUPER_ADMIN:
599							$api_methods[USER_TYPE_SUPER_ADMIN][] = $service.'.'.$method;
600							$api_method_masks[USER_TYPE_SUPER_ADMIN][$service.self::API_ANY_METHOD] = true;
601							$api_method_masks[USER_TYPE_SUPER_ADMIN][self::API_ANY_SERVICE.$method] = true;
602					}
603				}
604			}
605		}
606
607		foreach ($api_method_masks as $user_type => $masks) {
608			$api_method_masks[$user_type] = array_merge([self::API_WILDCARD, self::API_WILDCARD_ALIAS],
609				array_keys($masks)
610			);
611		}
612
613		self::$api_methods = $api_methods;
614		self::$api_method_masks = $api_method_masks;
615	}
616}
617