histogram: Make histograms crash less
[ninja.git] / application / controllers / user.php
blob265a89a52462970374ebaacee6adaaa1d446c062
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3 * User controller
4 * Requires authentication
6 * op5, and the op5 logo are trademarks, servicemarks, registered servicemarks
7 * or registered trademarks of op5 AB.
8 * All other trademarks, servicemarks, registered trademarks, and registered
9 * servicemarks mentioned herein may be the property of their respective owner(s).
10 * The information contained herein is provided AS IS with NO WARRANTY OF ANY
11 * KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A
12 * PARTICULAR PURPOSE.
14 class User_Controller extends Authenticated_Controller {
15 # form field types
16 private static $var_types = array(
17 'pagination.default.items_per_page' => 'int',
18 'pagination.paging_step' => 'int',
19 'keycommands.activated' => 'bool',
20 'keycommands.search' => 'string',
21 'keycommands.pause' => 'string',
22 'keycommands.forward' => 'string',
23 'keycommands.back' => 'string',
24 'checks.show_passive_as_active' => 'bool',
25 'config.current_skin' => 'select',
26 'config.use_popups' => 'bool',
27 'config.popup_delay' => 'int',
28 'config.page_refresh_rate' => 'int',
29 'config.listview_refresh_rate' => 'int',
30 'nagdefault.sticky' => 'bool',
31 'nagdefault.persistent' => 'bool',
32 'nagdefault.comment' => 'string',
33 'nagdefault.services-too' => 'bool',
34 'nagdefault.force' => 'bool',
35 'nagdefault.duration' => 'int',
36 'nagdefault.fixed' => 'bool',
37 'nagdefault.notes_url_target' => 'select',
38 'nagdefault.action_url_target' => 'select'
41 /**
42 * Default method
43 * Enable user to edit some GUI settings
45 public function index()
47 $updated = $this->input->get('updated', false);
48 $title = _('User Settings');
49 $this->template->title = $title;
51 $this->template->disable_refresh = true;
52 $this->template->content = $this->add_view('user/settings');
54 $template = $this->template->content;
56 # check if user is an admin
57 $is_admin = Auth::instance()->authorized_for('access_rights');
58 $template->is_admin = $is_admin;
60 $this->template->content->widgets = $this->widgets;
62 $available_setting_sections = array(
63 _('Pagination') => 'pagination',
64 _('Checks') => 'checks',
65 _('Config') => 'config',
66 _('Columns in list view') => 'listview',
67 _('Keyboard Commands') => 'keycommands',
68 _('URL Targets') => 'url_target',
69 _('Nagios Defaults') => 'nagdefault'
72 $sub_headings = array(
73 'listview' => array("https://kb.op5.com/x/AwE6", _('Read specification online'))
76 $settings['pagination'] = array(
77 _('Pagination Limit') => array('pagination.default.items_per_page', self::$var_types['pagination.default.items_per_page']),
78 _('Pagination Step') => array('pagination.paging_step', self::$var_types['pagination.paging_step']),
81 $settings['keycommands'] = array(
82 _('Keycommands') => array('keycommands.activated', self::$var_types['keycommands.activated']),
83 _('Search') => array('keycommands.search', self::$var_types['keycommands.search']),
84 _('Pause') => array('keycommands.pause', self::$var_types['keycommands.pause']),
85 _('Paging Forward') => array('keycommands.forward', self::$var_types['keycommands.forward']),
86 _('Paging Back') => array('keycommands.back', self::$var_types['keycommands.back'])
88 $settings['checks'] = array(
89 _('Show Passive as Active') => array('checks.show_passive_as_active', self::$var_types['checks.show_passive_as_active'])
92 $settings['url_target'] = array(
93 _('Notes URL Target') => array('nagdefault.notes_url_target', self::$var_types['nagdefault.notes_url_target'], Kohana::config('nagdefault.available_targets')),
94 _('Action URL Target') => array('nagdefault.action_url_target', self::$var_types['nagdefault.action_url_target'], Kohana::config('nagdefault.available_targets')),
97 $settings['nagdefault'] = array(
98 _('Sticky') => array('nagdefault.sticky', self::$var_types['nagdefault.sticky']),
99 _('Persistent') => array('nagdefault.persistent', self::$var_types['nagdefault.persistent']),
100 _('Force action') => array('nagdefault.force', self::$var_types['nagdefault.force']),
101 _('Perform action for services too') => array('nagdefault.services-too', self::$var_types['nagdefault.services-too']),
102 _('Fixed') => array('nagdefault.fixed', self::$var_types['nagdefault.fixed']),
103 _('Duration (hours)') => array('nagdefault.duration', self::$var_types['nagdefault.duration']),
104 _('Comment') => array('nagdefault.comment', self::$var_types['nagdefault.comment']));
107 $listview_settings = array();
108 foreach(Kohana::config('listview.columns') as $table => $value) {
109 $listview_settings[_('Table '.ucwords($table))] = array('listview.columns.'.$table, 'textarea');
111 $settings['listview'] = $listview_settings;
113 $settings['config'] = false;
114 $available_skins = ninja::get_skins();
115 $settings['config'] = array(
116 _('Global page refresh rate') => array('config.page_refresh_rate', self::$var_types['config.page_refresh_rate']),
117 _('List view refresh rate') => array('config.listview_refresh_rate', self::$var_types['config.listview_refresh_rate']),
118 _('Current Skin') => array('config.current_skin', self::$var_types['config.current_skin'], $available_skins)
121 $current_values = false;
122 if (!empty($available_setting_sections)) {
123 foreach ($available_setting_sections as $str => $key) {
124 if (!isset($settings[$key])) {
125 continue;
127 foreach ($settings[$key] as $discard => $cfgkey) {
128 if (is_array($cfgkey[0])) {
129 continue;
131 $current_val = Ninja_setting_Model::fetch_page_setting($cfgkey[0], '*');
132 if (is_object($current_val) && count($current_val)) {
133 $current_values[$cfgkey[0]] = $current_val->setting;
134 } else {
135 $current_values[$cfgkey[0]] = Kohana::config($cfgkey[0]);
141 $template->title = _('User settings');
142 $template->current_values = $current_values;
143 $template->available_setting_sections = $available_setting_sections;
144 $template->sub_headings = $sub_headings;
145 $template->settings = $settings;
146 $updated_str = false;
147 if ($updated !== false) {
148 $updated_str = _('Your settings were successfully saved');
150 $template->updated_str = $updated_str;
154 * Save data from form after some validation
156 public function save()
158 unset($_POST['save_config']);
160 # restore '.' in config keys
161 $restore_string = '_99_';
162 $data = false;
163 foreach ($this->input->post() as $key => $val) {
164 $key = str_replace($restore_string, '.', $key);
165 $data[$key] = $val;
168 # fetch all param type info
169 $type_info = self::$var_types;
171 # Add string to all column types for listview
172 $listview_settings = array();
173 foreach(Kohana::config('listview.columns') as $table => $value) {
174 $type_info['listview.columns.'.$table] = 'string';
177 # make sure we have field type info befor continuing
178 if (empty($type_info)) {
179 die(_('Unable to process user settings since field type info is missing'));
182 # loop through actual settings, validate and save if OK
183 $errors = false;
184 $base_err_str = _('Wrong datatype vaule for field %s. Should be %s - found %s');
185 $empty_str = _('Ignoring %s since no value was found for it.');
186 foreach ($data as $key => $val) {
187 if ($val == '' && $type_info[$key] != 'string') {
188 $errors[$key] = sprintf($empty_str, $key);
190 switch ($type_info[$key]) {
191 case 'int':
192 if (!is_numeric($val)) {
193 $errors[$key] = sprintf($base_err_str, $key, $type_info[$key], $val);
194 } else {
195 $this->_save_value($key, $val);
197 break;
198 case 'bool':
199 if (!is_numeric($val) || ($val != '0' && $val != '1')) {
200 $errors[$key] = sprintf($base_err_str, $key, $type_info[$key], $val);
201 } else {
202 $this->_save_value($key, $val);
204 break;
205 case 'select': case 'string':
206 if (strstr($key, 'keycommand')) {
207 $val = str_replace(' ', '', $val);
209 # no validation for these types yet
210 $this->_save_value($key, $val);
211 break;
212 default:
213 $errors[$key] = sprintf(_('Found no type information for %s so skipping it'), $key);
217 if (!empty($errors)) {
218 $title = _('User Settings');
219 $this->template->title = $title;
221 $this->template->disable_refresh = true;
222 $this->template->content = $this->add_view('user/error');
224 $template = $this->template->content;
226 $this->template->content->widgets = $this->widgets;
227 $template->errors = $errors;
228 } else {
229 return url::redirect('user/index?updated=true');
235 * Save a config key => value pair to db
236 * and session for current user.
238 public function _save_value($key=false, $val=false, $page='*')
240 # save to db
241 Ninja_setting_Model::save_page_setting($key, $page, $val);
243 # save to session
244 $page_val = '';
245 if ($page != '' && !empty($page)) {
246 $page_val = '.'.$page;
248 Session::instance()->set($key.$page_val, $val);
253 * Translated helptexts for this controller
255 public static function _helptexts($id)
257 $keyboard_help = '<br />'._("Possible Modifier keys are Alt, Shift, Ctrl + any key.
258 Modifier keys should be entered in alphabetical order. Add a combination of keys
259 with a + sign between like 'Alt+Shift-f' without any spaces. All keys are case insensitive.");
261 $parts = explode('.',$id);
262 if($parts[0] == 'listview') {
263 return ListView_Controller::_helptexts($id);
265 # Tag unfinished helptexts with @@@HELPTEXT:<key> to make it
266 # easier to find those later
267 $helptexts = array(
268 'pagination.default.items_per_page' => _('Set number of items shown on each page. Defaults to 100.'),
269 'pagination.paging_step' => _('This value is used to generate drop-down for nr of items per page to show. Defaults to 100.'),
270 'checks.show_passive_as_active' => _('This setting affects if to show passive checks as active in the GUI'),
271 'config.page_refresh_rate' => _('Seconds between each automatic page reload (0 disables)'),
272 'config.listview_refresh_rate' => _("Tables including status data ('list views') automatically updates their content. This value indicates seconds between each list view reload (0 disables)"),
273 'config.current_skin' => _('Select the skin to use in the GUI. Affects colors and images.'),
274 'keycommands.activated' => _('Switch keyboard commands ON or OFF. Default is OFF'),
275 'keycommands.search' => _('Keyboard command to set focus to search field. Defaults to Alt+Shift+f.').' '.$keyboard_help,
276 'keycommands.pause' => _('Keyboard command to pause/unpause page refresh. Defaults to Alt+Shift+p.').' '.$keyboard_help,
277 'keycommands.forward' => _('Keyboard command to move forward in a paginated result (except search results). Defaults to Alt+Shift+right.').' '.$keyboard_help,
278 'keycommands.back' => _('Keyboard command to move back in a paginated result (except search results). Defaults to Alt+Shift+left.').' '.$keyboard_help,
279 'edit_menu' => _('Edit menu item visibility for limited users.'),
280 'nagdefault.notes_url_target' => _('This option determines the name of the frame target that notes URLs should be displayed in.'),
281 'nagdefault.action_url_target' => _('This option determines the name of the frame target that action URLs should be displayed in.'),
282 'nagdefault.sticky' => _('Configure the default value for the nagios "sticky" command option'),
283 'nagdefault.persistent' => _('Configure the default value for the nagios "persistent" command option'),
284 'nagdefault.force' => _('Configure the default value for the nagios "force" command option'),
285 'nagdefault.services-too' => _('Configure the default value for the nagios "services-too" command option'),
286 'nagdefault.fixed' => _('Configure the default value for the nagios "fixed" command option'),
287 'nagdefault.duration' => _('Configure the default value for the nagios "duration" command option'),
288 'nagdefault.comment' => _('Configure the default value for the nagios "comment" command option'),
290 if (array_key_exists($id, $helptexts)) {
291 echo $helptexts[$id];
293 else
294 echo sprintf(_("This helptext ('%s') is not translated yet"), $id);
298 * Remove menu item by index
299 * Both section string ['about', 'monitoring', etc]
300 * and item string ['portal', 'manual', 'support', etc] are required.
301 * As a consequence, all menu items has to be explicitly removed before removing the section
303 public function menu_remove(&$menu_links=false, &$menu_items=false, $section_str=false, $group=false, $item_str=false, $save=true)
305 if (empty($menu_links) || empty($menu_items) || empty($section_str)) {
306 return false;
309 if (is_array($section_str)) {
310 if ($save === true) {
311 $config = Op5Config::instance();
312 $ninja_menu = $config->getConfig('ninja_menu');
313 $ninja_menu[$group] = $section_str;
314 $config->setConfig('ninja_menu', $ninja_menu);
317 # we have to make recursive calls
318 foreach ($section_str as $section => $items) {
319 foreach ($items as $item) {
320 $this->menu_remove($menu_links, $menu_items, $section, $item, $group);
323 } else {
324 if (empty($item_str) && isset($menu_links[$menu_items['section_'.$section_str]])
325 && empty($menu_links[$menu_items['section_'.$section_str]])) {
326 # remove the section
327 unset($menu_links[$menu_items['section_'.$section_str]]);
328 } elseif (isset($menu_items[$item_str]) && !empty($item_str) && isset($menu_links[$menu_items['section_'.$section_str]][$menu_items[$item_str]])) {
329 unset($menu_links[$menu_items['section_'.$section_str]][$menu_items[$item_str]]);
336 * Edit menu items
337 * Show form for editing menu items
339 public function menu_edit()
341 if(!Auth::instance()->authorized_for('access_rights')) {
342 // @todo add "you're not authed" flash message
343 //_("You don't have access to this page. Only visible to administrators.");
344 return url::redirect(Router::$controller.'/index');
346 $groups = Auth::get_groups_without_rights(array('access_rights'));
347 $selected_group = $this->input->get('usergroup', false);
348 if($selected_group && !isset($groups[$selected_group])) {
349 return url::redirect(Router::$controller.'/menu_edit');
351 $this->template->disable_refresh = true;
353 $this->template->content = $this->add_view('user/edit_menu');
354 $this->xtra_js[] = $this->add_path('user/js/user.js');
355 $content = $this->template->content;
357 $content->select_user_message = _("Select the user below to edit the menu for.");
358 $content->description = _("Check the menu items that the should not be visible to the selected user.");
360 $content->groups = $groups;
362 $remove_items = false;
363 $all_items = false;
364 if ($selected_group) {
365 include(APPPATH.'views/menu/menu.php');
366 $config = Op5Config::instance()->getConfig('ninja_menu');
367 if(isset($config[$selected_group])) {
368 $remove_items = $config[$selected_group];
371 // disallowing manually giving someone the right to access nacoma,
372 // it's really controlled by system_information (an access right)
373 unset($menu_base['Configuration']['Configure'], $menu_items['configure']);
374 $all_items = $menu_base;
376 $content->menu_base = $menu_base;
377 $content->menu_items = $menu_items;
378 $content->sections = $sections;
379 $content->menu = $menu;
382 $content->selected_group = $selected_group;
384 $content->remove_items = $remove_items;
385 $content->all_items = $all_items;
387 # protected menu items
388 $untouchable_items = array('my_account');
389 $content->untouchable_items = $untouchable_items;
393 * Update menu - save removed items to db
394 * and redirect to menu setup
396 public function menu_update()
398 if(!Auth::instance()->authorized_for('access_rights')) {
399 // @todo add "you're not authed" flash message
400 //_("You don't have access to this page. Only visible to administrators.");
401 return url::redirect(Router::$controller.'/index');
403 $group = $this->input->post('group', false);
404 $remove_items = $this->input->post('remove_items', false);
405 if($_SERVER['REQUEST_METHOD'] != 'POST' || !$group) {
406 return url::redirect(Router::$controller.'/menu_edit');
409 include(APPPATH.'views/menu/menu.php');
411 $all_items = $menu_base;
412 if ($remove_items) {
413 $this->menu_remove($menu_base, $menu_items, $remove_items, $group);
414 } else {
415 $config = Op5Config::instance();
416 $ninja_menu = $config->getConfig('ninja_menu');
417 if(isset($ninja_menu[$group])) {
418 unset($ninja_menu[$group]);
420 $config->setConfig('ninja_menu', $ninja_menu);
423 return url::redirect(Router::$controller."/menu_edit?usergroup=$group");