def test_request_processing(register_builtin_html): html.request.set_var("varname", "1a") html.request.set_var("varname2", "1") html.get_unicode_input("varname", deflt="lol") html.get_integer_input("varname2") html.get_request(exclude_vars=["varname2"])
def __init__(self): super(ABCCrashReportPage, self).__init__() self._crash_id = html.get_unicode_input("crash_id") if not self._crash_id: raise MKUserError( "crash_id", _("The parameter \"%s\" is missing.") % "crash_id") self._site_id = html.get_unicode_input("site") if not self._site_id: raise MKUserError("site", _("The parameter \"%s\" is missing.") % "site")
def page_show(): site = html.request.var("site") # optional site hint host_name = html.request.var("host", "") file_name = html.get_unicode_input("file", "") # Fix problem when URL is missing certain illegal characters try: file_name = form_file_to_ext( find_matching_logfile(site, host_name, form_file_to_int(file_name))) except livestatus.MKLivestatusNotFoundError: pass # host_name log dir does not exist # Acknowledging logs is supported on # a) all logs on all hosts # b) all logs on one host_name # c) one log on one host_name if html.request.has_var('_ack') and not html.request.var("_do_actions") == _("No"): sites.live().set_auth_domain('action') do_log_ack(site, host_name, file_name) return if not host_name: show_log_list() return if file_name: show_file(site, host_name, file_name) else: show_host_log_list(site, host_name)
def _from_vars(self): self._user_id = html.get_unicode_input("edit") # missing -> new user self._cloneid = html.get_unicode_input("clone") # Only needed in 'new' mode self._is_new_user = self._user_id is None self._users = userdb.load_users(lock=html.is_transaction()) if self._is_new_user: if self._cloneid: self._user = self._users.get(self._cloneid, userdb.new_user_template('htpasswd')) else: self._user = userdb.new_user_template('htpasswd') else: self._user = self._users.get(self._user_id, userdb.new_user_template('htpasswd')) self._locked_attributes = userdb.locked_attributes(self._user.get('connector'))
def filter_table(self, rows): name = html.get_unicode_input(self._varprefix + "name") if not name: return rows from_version = html.request.var(self._varprefix + "from_version") to_version = html.request.var(self._varprefix + "to_version") negate = html.get_checkbox(self._varprefix + "negate") match = html.request.var(self._varprefix + "match") if match == "regex": try: name = re.compile(name) except re.error: raise MKUserError( self._varprefix + "name", _('You search statement is not valid. You need to provide a regular ' 'expression (regex). For example you need to use <tt>\\\\</tt> instead of <tt>\\</tt> ' 'if you like to search for a single backslash.')) new_rows = [] for row in rows: packages_numeration = row["host_inventory"].get_sub_numeration(["software", "packages"]) if packages_numeration is None: continue packages = packages_numeration.get_child_data() is_in = self.find_package(packages, name, from_version, to_version) if is_in != negate: new_rows.append(row) return new_rows
def _from_vars(self): self._hostname = html.get_ascii_input("host") # may be empty in new/clone mode self._host = watolib.Folder.current().host(self._hostname) if self._host is None: raise MKUserError("host", _('The given host does not exist.')) self._host.need_permission("read") # TODO: Validate? self._service = html.get_unicode_input("service")
def action(self): if html.form_submitted("search"): return alias = html.get_unicode_input("alias") unique, info = watolib.is_alias_used("roles", self._role_id, alias) if not unique: raise MKUserError("alias", info) new_id = html.request.var("id") if len(new_id) == 0: raise MKUserError("id", _("Please specify an ID for the new role.")) if not re.match("^[-a-z0-9A-Z_]*$", new_id): raise MKUserError( "id", _("Invalid role ID. Only the characters a-z, A-Z, 0-9, _ and - are allowed.")) if new_id != self._role_id: if new_id in self._roles: raise MKUserError("id", _("The ID is already used by another role")) self._role["alias"] = alias # based on if not self._role.get("builtin"): basedon = html.request.var("basedon") if basedon not in config.builtin_role_ids: raise MKUserError("basedon", _("Invalid valid for based on. Must be id of builtin rule.")) self._role["basedon"] = basedon # Permissions permissions = self._role["permissions"] for var_name, value in html.request.itervars(prefix="perm_"): try: perm = permission_registry[var_name[5:]]() except KeyError: continue if value == "yes": permissions[perm.name] = True elif value == "no": permissions[perm.name] = False elif value == "default": try: del permissions[perm.name] except KeyError: pass # Already at defaults if self._role_id != new_id: self._roles[new_id] = self._role del self._roles[self._role_id] self._rename_user_role(self._role_id, new_id) self._save_roles() watolib.add_change( "edit-roles", _("Modified user role '%s'") % new_id, sites=config.get_login_sites()) return "roles"
def action(self, cmdtag, spec, row, row_index, num_rows): if html.request.var("_add_comment"): comment = html.get_unicode_input("_comment") if not comment: raise MKUserError("_comment", _("You need to supply a comment.")) command = "ADD_" + cmdtag + "_COMMENT;%s;1;%s" % \ (spec, config.user.id) + (";%s" % livestatus.lqencode(comment)) title = _("<b>add a comment to</b>") return command, title
def ajax_tree_openclose(): tree = html.request.var("tree") name = html.get_unicode_input("name") if not tree or not name: raise MKUserError(None, _('tree or name parameter missing')) config.user.set_tree_state(tree, name, html.request.var("state")) config.user.save_tree_states() html.write('OK') # Write out something to make debugging easier
def action(self, cmdtag, spec, row, row_index, num_rows): if "aggr_tree" in row: # BI mode specs = [] for site, host, service in bi.find_all_leaves(row["aggr_tree"]): if service: spec = "%s;%s" % (host, service) cmdtag = "SVC" else: spec = host cmdtag = "HOST" specs.append((site, spec, cmdtag)) if html.request.var("_acknowledge"): comment = html.get_unicode_input("_ack_comment") if not comment: raise MKUserError("_ack_comment", _("You need to supply a comment.")) if ";" in comment: raise MKUserError("_ack_comment", _("The comment must not contain semicolons.")) sticky = 2 if html.request.var("_ack_sticky") else 0 sendnot = 1 if html.request.var("_ack_notify") else 0 perscomm = 1 if html.request.var("_ack_persistent") else 0 expire_secs = self._vs_expire().from_html_vars("_ack_expire") if expire_secs: expire = int(time.time()) + expire_secs expire_text = ";%d" % expire else: expire_text = "" def make_command(spec, cmdtag): return "ACKNOWLEDGE_" + cmdtag + "_PROBLEM;%s;%d;%d;%d;%s" % ( spec, sticky, sendnot, perscomm, config.user.id) + ( ";%s" % livestatus.lqencode(comment)) + expire_text if "aggr_tree" in row: # BI mode commands = [(site, make_command(spec, cmdtag)) for (site, spec, cmdtag) in specs] else: commands = [make_command(spec, cmdtag)] title = _("<b>acknowledge the problems%s</b> of") % ( expire_text and (_(" for a period of %s") % Age().value_to_text(expire_secs)) or "") return commands, title elif html.request.var("_remove_ack"): def make_command(spec, cmdtag): return "REMOVE_" + cmdtag + "_ACKNOWLEDGEMENT;%s" % spec if "aggr_tree" in row: # BI mode commands = [(site, make_command(spec, cmdtag)) for (site, spec, cmdtag) in specs] else: commands = [make_command(spec, cmdtag)] title = _("<b>remove acknowledgements</b> from") return commands, title
def _evaluate_user_opts(self): table_id = self.id rows = self.rows search_term = None actions_enabled = (self.options["searchable"] or self.options["sortable"]) if not actions_enabled: return rows, False, False, None, None else: user_opts = config.user.load_file("tableoptions", {}) user_opts.setdefault(table_id, {}) table_opts = user_opts[table_id] # Handle the initial visibility of the actions actions_visible = user_opts[table_id].get('actions_visible', False) if html.request.var('_%s_actions' % table_id): actions_visible = html.request.var('_%s_actions' % table_id) == '1' user_opts[table_id]['actions_visible'] = actions_visible if html.request.var('_%s_reset' % table_id): html.request.del_var('_%s_search' % table_id) if 'search' in table_opts: del table_opts['search'] # persist if self.options["searchable"]: # Search is always lower case -> case insensitive search_term = html.get_unicode_input( '_%s_search' % table_id, table_opts.get('search', '')).lower() if search_term: html.request.set_var('_%s_search' % table_id, search_term) table_opts['search'] = search_term # persist rows = _filter_rows(rows, search_term) if html.request.var('_%s_reset_sorting' % table_id): html.request.del_var('_%s_sort' % table_id) if 'sort' in table_opts: del table_opts['sort'] # persist if self.options["sortable"]: # Now apply eventual sorting settings sort = html.request.var('_%s_sort' % table_id, table_opts.get('sort')) if sort is not None: html.request.set_var('_%s_sort' % table_id, sort) table_opts['sort'] = sort # persist sort_col, sort_reverse = map(int, sort.split(',', 1)) rows = _sort_rows(rows, sort_col, sort_reverse) return rows, actions_enabled, actions_visible, search_term, user_opts
def check_auth_automation(): secret = html.request.var("_secret", "").strip() user_id = html.get_unicode_input("_username", "").strip() html.del_var_from_env('_username') html.del_var_from_env('_secret') if verify_automation_secret(user_id, secret): # Auth with automation secret succeeded - mark transid as unneeded in this case html.transaction_manager.ignore() set_auth_type("automation") return user_id raise MKAuthException(_("Invalid automation secret for user %s") % user_id)
def page_host_service_graph_popup(): site_id = html.request.var('site') host_name = html.request.var('host_name') service_description = html.get_unicode_input('service') # TODO: Refactor this to some OO based approach if cmk_graphs_possible(site_id): import cmk.gui.cee.plugins.metrics.html_render as graphs # pylint: disable=no-name-in-module graphs.host_service_graph_popup_cmk(site_id, host_name, service_description) else: host_service_graph_popup_pnp(site_id, host_name, service_description)
def check_auth_automation(): secret = html.request.var("_secret", "").strip() user_id = html.get_unicode_input("_username", "").strip() html.request.del_var('_username') html.request.del_var('_secret') if secret and user_id and "/" not in user_id: path = cmk.utils.paths.var_dir + "/web/" + user_id.encode("utf-8") + "/automation.secret" if os.path.isfile(path) and file(path).read().strip() == secret: # Auth with automation secret succeeded - mark transid as unneeded in this case html.transaction_manager.ignore() set_auth_type("automation") return user_id raise MKAuthException(_("Invalid automation secret for user %s") % user_id)
def _ajax_search(self): q = _maybe_strip(html.get_unicode_input('q')) if not q: return try: generate_results(q) except MKException as e: html.show_error(e) except Exception as e: logger.exception("error generating quicksearch results") if config.debug: raise html.show_error(traceback.format_exc())
def action(self, cmdtag, spec, row, row_index, num_rows): if html.request.var("_customnotification"): comment = html.get_unicode_input("_cusnot_comment") broadcast = 1 if html.get_checkbox("_cusnot_broadcast") else 0 forced = 2 if html.get_checkbox("_cusnot_forced") else 0 command = "SEND_CUSTOM_%s_NOTIFICATION;%s;%s;%s;%s" % ( cmdtag, spec, broadcast + forced, config.user.id, livestatus.lqencode(comment), ) title = _("<b>send a custom notification</b> regarding") return command, title
def action(self, cmdtag, spec, row, row_index, num_rows): for s in [0, 1, 2, 3]: statename = html.request.var("_fake_%d" % s) if statename: pluginoutput = html.get_unicode_input("_fake_output").strip() if not pluginoutput: pluginoutput = _("Manually set to %s by %s") % ( html.attrencode(statename), config.user.id) perfdata = html.request.var("_fake_perfdata") if perfdata: pluginoutput += "|" + perfdata if cmdtag == "SVC": cmdtag = "SERVICE" command = "PROCESS_%s_CHECK_RESULT;%s;%s;%s" % ( cmdtag, spec, s, livestatus.lqencode(pluginoutput)) title = _("<b>manually set check results to %s</b> for" ) % html.attrencode(statename) return command, title
def action(self): if html.request.var('_delete'): delid = html.get_unicode_input("_delete") c = wato_confirm( _("Confirm deletion of user %s") % delid, _("Do you really want to delete the user %s?") % delid) if c: delete_users([delid]) elif c is False: return "" elif html.request.var('_sync') and html.check_transaction(): try: job = userdb.UserSyncBackgroundJob() job.set_function(job.do_sync, add_to_changelog=True, enforce_sync=True) try: job.start() except background_job.BackgroundJobAlreadyRunning as e: raise MKUserError( None, _("Another synchronization job is already running: %s") % e) self._job_snapshot = job.get_status_snapshot() except Exception: logger.exception("error syncing users") raise MKUserError( None, traceback.format_exc().replace('\n', '<br>\n')) elif html.request.var("_bulk_delete_users"): return self._bulk_delete_users_after_confirm() elif html.check_transaction(): action_handler = gui_background_job.ActionHandler() action_handler.handle_actions() if action_handler.did_acknowledge_job(): self._job_snapshot = userdb.UserSyncBackgroundJob( ).get_status_snapshot() return None, _("Synchronization job acknowledged")
def action(self): if not html.check_transaction(): return "%s_groups" % self.type_name alias = html.get_unicode_input("alias").strip() if not alias: raise MKUserError("alias", _("Please specify an alias name.")) self.group = {"alias": alias} self._determine_additional_group_data() if self._new: self._name = html.request.var("name").strip() watolib.add_group(self._name, self.type_name, self.group) else: watolib.edit_group(self._name, self.type_name, self.group) return "%s_groups" % self.type_name
def _from_vars(self): self._start = bool(html.request.var("_start")) # 'all' not set -> only scan checked hosts in current folder, no recursion # otherwise: all host in this folder, maybe recursively self._all = bool(html.request.var("all")) self._complete_folder = self._all # Ignored during initial form display # TODO: Make dedicated class or class members self._settings = { "where": html.request.var("where"), "alias": html.get_unicode_input("alias", "").strip() or None, "recurse": html.get_checkbox("recurse"), "select": html.request.var("select"), "timeout": utils.saveint(html.request.var("timeout")) or 8, "probes": utils.saveint(html.request.var("probes")) or 2, "max_ttl": utils.saveint(html.request.var("max_ttl")) or 10, "force_explicit": html.get_checkbox("force_explicit"), "ping_probes": utils.saveint(html.request.var("ping_probes")) or 0, } self._job = ParentScanBackgroundJob()
def do_login(): # handle the sent login form if html.request.var('_login'): try: username = html.get_unicode_input('_username', '').rstrip() if username == '': raise MKUserError('_username', _('No username given.')) password = html.request.var('_password', '') if password == '': raise MKUserError('_password', _('No password given.')) default_origtarget = config.url_prefix() + "check_mk/" origtarget = html.get_url_input("_origtarget", default_origtarget) # Disallow redirections to: # - logout.py: Happens after login # - side.py: Happens when invalid login is detected during sidebar refresh if "logout.py" in origtarget or 'side.py' in origtarget: origtarget = default_origtarget # None -> User unknown, means continue with other connectors # '<user_id>' -> success # False -> failed result = userdb.hook_login(username, password) if result: # use the username provided by the successful login function, this function # might have transformed the username provided by the user. e.g. switched # from mixed case to lower case. username = result # When single user session mode is enabled, check that there is not another # active session userdb.ensure_user_can_init_session(username) # reset failed login counts userdb.on_succeeded_login(username) # The login succeeded! Now: # a) Set the auth cookie # b) Unset the login vars in further processing # c) Redirect to really requested page create_auth_session(username) # Never use inplace redirect handling anymore as used in the past. This results # in some unexpected situations. We simpy use 302 redirects now. So we have a # clear situation. # userdb.need_to_change_pw returns either False or the reason description why the # password needs to be changed result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect('user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(origtarget), result)) else: raise HTTPRedirect(origtarget) else: userdb.on_failed_login(username) raise MKUserError(None, _('Invalid credentials.')) except MKUserError as e: html.add_user_error(e.varname, e) return "%s" % e
def filtername(self): return html.get_unicode_input(self._varprefix + "name")
def action(self): # TODO: remove subclass specific things specifict things (everything with _type == 'user') if not html.check_transaction(): return title = html.get_unicode_input("title").strip() if not title: raise MKUserError("title", _("Please specify a title.")) for this_attr in self._attrs: if title == this_attr['title'] and self._name != this_attr['name']: raise MKUserError( "alias", _("This alias is already used by the attribute %s.") % this_attr['name']) topic = html.request.var('topic', '').strip() help_txt = html.get_unicode_input('help').strip() show_in_table = html.get_checkbox('show_in_table') add_custom_macro = html.get_checkbox('add_custom_macro') if self._new: self._name = html.request.var("name", '').strip() if not self._name: raise MKUserError( "name", _("Please specify a name for the new attribute.")) if ' ' in self._name: raise MKUserError( "name", _("Sorry, spaces are not allowed in attribute names.")) if not re.match("^[-a-z0-9A-Z_]*$", self._name): raise MKUserError( "name", _("Invalid attribute name. Only the characters a-z, A-Z, 0-9, _ and - are allowed." )) if [a for a in self._attrs if a['name'] == self._name]: raise MKUserError( "name", _("Sorry, there is already an attribute with that name.")) ty = html.request.var('type', '').strip() if ty not in [t[0] for t in custom_attr_types()]: raise MKUserError('type', _('The choosen attribute type is invalid.')) self._attr = { 'name': self._name, 'type': ty, } self._attrs.append(self._attr) add_change( "edit-%sattr" % self._type, _("Create new %s attribute %s") % (self._type, self._name)) else: add_change( "edit-%sattr" % self._type, _("Modified %s attribute %s") % (self._type, self._name)) self._attr.update({ 'title': title, 'topic': topic, 'help': help_txt, 'show_in_table': show_in_table, 'add_custom_macro': add_custom_macro, }) self._add_extra_attrs_from_html_vars() save_custom_attrs_to_mk_file(self._all_attrs) self._update_config() return self._type + "_attrs"
def value(self): val = {} for varname in self.htmlvars: val[varname] = html.get_unicode_input(varname, '') return val
def action(self, cmdtag, spec, row, row_index, num_rows): down_from = int(time.time()) down_to = None if self._has_recurring_downtimes() and html.get_checkbox( "_down_do_recur"): from cmk.gui.cee.plugins.wato.cmc import recurring_downtimes_types recurring_type = int(html.request.var("_down_recurring")) title_start = _("schedule a periodic downtime every %s" ) % recurring_downtimes_types()[recurring_type] else: title_start = _("schedule an immediate downtime") rangebtns = (varname for varname, _value in html.request.itervars( prefix="_downrange")) def resolve_end(name): now = time.localtime(down_from) if name == "next_day": return time.mktime((now.tm_year, now.tm_mon, now.tm_mday, 23, 59, 59, 0, 0, now.tm_isdst)) + 1, \ _("<b>%s until 24:00:00</b> on") % title_start elif name == "next_week": wday = now.tm_wday days_plus = 6 - wday res = time.mktime((now.tm_year, now.tm_mon, now.tm_mday, 23, 59, 59, 0, 0, now.tm_isdst)) + 1 res += days_plus * 24 * 3600 return res, _("<b>%s until sunday night</b> on") % title_start elif name == "next_month": new_month = now.tm_mon + 1 if new_month == 13: new_year = now.tm_year + 1 new_month = 1 else: new_year = now.tm_year return time.mktime((new_year, new_month, 1, 0, 0, 0, 0, 0, now.tm_isdst)), \ _("<b>%s until end of month</b> on") % title_start elif name == "next_year": return time.mktime((now.tm_year, 12, 31, 23, 59, 59, 0, 0, now.tm_isdst)) + 1, \ _("<b>%s until end of %d</b> on") % (title_start, now.tm_year) else: duration = int(name) return down_from + duration, \ _("<b>%s of %s length</b> on") %\ (title_start, self._get_duration_human_readable(duration)) try: rangebtn = next(rangebtns) except StopIteration: rangebtn = None if rangebtn: _btnname, end = rangebtn.split("__", 1) down_to, title = resolve_end(end) elif html.request.var("_down_from_now"): try: minutes = int(html.request.var("_down_minutes", "")) except ValueError: minutes = 0 if minutes <= 0: raise MKUserError( "_down_minutes", _("Please enter a positive number of minutes.")) down_to = time.time() + minutes * 60 title = _("<b>%s for the next %d minutes</b> on") % (title_start, minutes) elif html.request.var("_down_adhoc"): minutes = config.adhoc_downtime.get("duration", 0) down_to = time.time() + minutes * 60 title = _("<b>%s for the next %d minutes</b> on") % (title_start, minutes) elif html.request.var("_down_custom"): down_from = html.get_datetime_input("_down_from") down_to = html.get_datetime_input("_down_to") if down_to < time.time(): raise MKUserError( "_down_to", _("You cannot set a downtime that ends in the past. " "This incident will be reported.")) if down_to < down_from: raise MKUserError( "_down_to", _("Your end date is before your start date.")) title = _("<b>schedule a downtime from %s to %s</b> on ") % ( time.asctime(time.localtime(down_from)), time.asctime(time.localtime(down_to))) elif html.request.var("_down_remove") and config.user.may( "action.remove_all_downtimes"): if html.request.var("_on_hosts"): raise MKUserError( "_on_hosts", _("The checkbox for setting host downtimes does not work when removing downtimes." )) downtime_ids = [] if cmdtag == "HOST": prefix = "host_" else: prefix = "service_" for id_ in row[prefix + "downtimes"]: if id_ != "": downtime_ids.append(int(id_)) commands = [] for dtid in downtime_ids: commands.append("DEL_%s_DOWNTIME;%d\n" % (cmdtag, dtid)) title = _("<b>remove all scheduled downtimes</b> of ") return commands, title if down_to: if html.request.var("_down_adhoc"): comment = config.adhoc_downtime.get("comment", "") else: comment = html.get_unicode_input("_down_comment") if not comment: raise MKUserError( "_down_comment", _("You need to supply a comment for your downtime.")) if html.request.var("_down_flexible"): fixed = 0 duration = html.get_time_input("_down_duration", _("the duration")) else: fixed = 1 duration = 0 if html.get_checkbox("_down_do_recur"): fixed_and_recurring = recurring_type * 2 + fixed else: fixed_and_recurring = fixed def make_command(spec, cmdtag): return ("SCHEDULE_" + cmdtag + "_DOWNTIME;%s;" % spec) + ("%d;%d;%d;0;%d;%s;" % ( down_from, down_to, fixed_and_recurring, duration, config.user.id, )) + livestatus.lqencode(comment) if "aggr_tree" in row: # BI mode commands = [] for site, host, service in bi.find_all_leaves( row["aggr_tree"]): if service: spec = "%s;%s" % (host, service) cmdtag = "SVC" else: spec = host cmdtag = "HOST" commands.append((site, make_command(spec, cmdtag))) else: if html.request.var("_include_childs"): # only for hosts specs = [spec] + self._get_child_hosts( row["site"], [spec], recurse=bool( html.request.var("_include_childs_recurse"))) elif html.request.var( "_on_hosts"): # set on hosts instead of services specs = [spec.split(";")[0]] title += " the hosts of" cmdtag = "HOST" else: specs = [spec] commands = [make_command(spec, cmdtag) for spec in specs] return commands, title
def from_html_vars(self, varprefix): value = html.get_unicode_input(varprefix + "attr_" + self.name()) if value is None: value = "" return value.strip()
def page_edit(cls): back_url = html.get_url_input("back", cls.list_url()) cls.load() cls.need_overriding_permission("edit") # Three possible modes: # "create" -> create completely new page # "clone" -> like new, but prefill form with values from existing page # "edit" -> edit existing page mode = html.request.var('mode', 'edit') if mode == "create": title = cls.phrase("create") page_dict = { "name": cls.default_name(), "topic": cls.default_topic(), } else: # Load existing page. visual from disk - and create a copy if 'load_user' is set page_name = html.request.var("load_name") if mode == "edit": title = cls.phrase("edit") owner_user_id = html.request.var("owner", config.user.id) if owner_user_id == config.user.id: page = cls.find_my_page(page_name) else: page = cls.find_foreign_page(owner_user_id, page_name) if page is None: raise MKUserError(None, _("The requested %s does not exist") % cls.phrase("title")) # TODO FIXME: Looks like a hack cls.remove_instance((owner_user_id, page_name)) # will be added later again else: # clone title = cls.phrase("clone") load_user = html.get_unicode_input("load_user") # FIXME: Change varname to "owner" try: page = cls.instance((load_user, page_name)) except KeyError: raise MKUserError(None, _("The requested %s does not exist") % cls.phrase("title")) page_dict = page.internal_representation() html.header(title) html.begin_context_buttons() html.context_button(_("Back"), back_url, "back") html.end_context_buttons() parameters, keys_by_topic = cls._collect_parameters(mode) vs = Dictionary( title=_("General Properties"), render='form', optional_keys=None, elements=parameters, headers=keys_by_topic, ) def validate(page_dict): owner_user_id = html.request.var("owner", config.user.id) page_name = page_dict["name"] if owner_user_id == config.user.id: page = cls.find_my_page(page_name) else: page = cls.find_foreign_page(owner_user_id, page_name) if page: raise MKUserError( "_p_name", _("You already have an element with the ID <b>%s</b>") % page_dict["name"]) new_page_dict = forms.edit_valuespec( vs, page_dict, validate=validate, focus="_p_title", method="POST") if new_page_dict is not None: # Take over keys from previous value that are specific to the page type # and not edited here. if mode in ("edit", "clone"): for key, value in page_dict.items(): new_page_dict.setdefault(key, value) owner = html.request.var("owner", config.user.id) new_page_dict["owner"] = owner new_page = cls(new_page_dict) cls.add_page(new_page) cls.save_user_instances(owner) if mode == "create": redirect_url = new_page.after_create_url() or back_url else: redirect_url = back_url html.immediate_browser_redirect(0.5, redirect_url) html.message(_('Your changes haven been saved.')) # Reload sidebar.TODO: This code logically belongs to PageRenderer. How # can we simply move it there? # TODO: This is not true for all cases. e.g. the BookmarkList is not # of type PageRenderer but has a dedicated sidebar snapin. Maybe # the best option would be to make a dedicated method to decide whether # or not to reload the sidebar. if new_page_dict.get("hidden") in [ None, False ] \ or new_page_dict.get("hidden") != page_dict.get("hidden"): html.reload_sidebar() else: html.show_localization_hint() html.footer() return
def action(self): if not html.check_transaction(): return "users" if self._is_new_user: self._user_id = UserID(allow_empty=False).from_html_vars("user_id") user_attrs = {} else: self._user_id = html.get_unicode_input("edit").strip() user_attrs = self._users[self._user_id] # Full name user_attrs["alias"] = html.get_unicode_input("alias").strip() # Locking user_attrs["locked"] = html.get_checkbox("locked") increase_serial = False if self._user_id in self._users and self._users[ self._user_id]["locked"] != user_attrs["locked"] and user_attrs["locked"]: increase_serial = True # when user is being locked now, increase the auth serial # Authentication: Password or Secret auth_method = html.request.var("authmethod") if auth_method == "secret": secret = html.request.var("_auth_secret", "").strip() user_attrs["automation_secret"] = secret user_attrs["password"] = hash_password(secret) increase_serial = True # password changed, reflect in auth serial else: password = html.request.var("_password_" + self._pw_suffix(), '').strip() password2 = html.request.var("_password2_" + self._pw_suffix(), '').strip() # We compare both passwords only, if the user has supplied # the repeation! We are so nice to our power users... # Note: this validation is done before the main-validiation later on # It doesn't make any sense to put this block into the main validation function if password2 and password != password2: raise MKUserError("_password2", _("The both passwords do not match.")) # Detect switch back from automation to password if "automation_secret" in user_attrs: del user_attrs["automation_secret"] if "password" in user_attrs: del user_attrs["password"] # which was the encrypted automation password! if password: user_attrs["password"] = hash_password(password) user_attrs["last_pw_change"] = int(time.time()) increase_serial = True # password changed, reflect in auth serial # PW change enforcement user_attrs["enforce_pw_change"] = html.get_checkbox("enforce_pw_change") if user_attrs["enforce_pw_change"]: increase_serial = True # invalidate all existing user sessions, enforce relogon # Increase serial (if needed) if increase_serial: user_attrs["serial"] = user_attrs.get("serial", 0) + 1 # Email address user_attrs["email"] = EmailAddressUnicode().from_html_vars("email") idle_timeout = watolib.get_vs_user_idle_timeout().from_html_vars("idle_timeout") user_attrs["idle_timeout"] = idle_timeout if idle_timeout is not None: user_attrs["idle_timeout"] = idle_timeout elif idle_timeout is None and "idle_timeout" in user_attrs: del user_attrs["idle_timeout"] # Pager user_attrs["pager"] = html.request.var("pager", '').strip() if cmk.is_managed_edition(): customer = self._vs_customer.from_html_vars("customer") self._vs_customer.validate_value(customer, "customer") if customer != managed.default_customer_id(): user_attrs["customer"] = customer elif "customer" in user_attrs: del user_attrs["customer"] vs_sites = self._vs_sites() authorized_sites = vs_sites.from_html_vars("authorized_sites") vs_sites.validate_value(authorized_sites, "authorized_sites") if authorized_sites is not None: user_attrs["authorized_sites"] = authorized_sites elif "authorized_sites" in user_attrs: del user_attrs["authorized_sites"] # Roles user_attrs["roles"] = [ role for role in self._roles.keys() if html.get_checkbox("role_" + role) ] # Language configuration set_lang = html.get_checkbox("_set_lang") language = html.request.var("language") if set_lang: if language == "": language = None user_attrs["language"] = language elif not set_lang and "language" in user_attrs: del user_attrs["language"] # Contact groups cgs = [] for c in self._contact_groups: if html.get_checkbox("cg_" + c): cgs.append(c) user_attrs["contactgroups"] = cgs # Notification settings are only active if we do *not* have # rule based notifications! if not self._rbn_enabled(): # Notifications user_attrs["notifications_enabled"] = html.get_checkbox("notifications_enabled") ntp = html.request.var("notification_period") if ntp not in self._timeperiods: ntp = "24X7" user_attrs["notification_period"] = ntp for what, opts in [("host", "durfs"), ("service", "wucrfs")]: user_attrs[what + "_notification_options"] = "".join( [opt for opt in opts if html.get_checkbox(what + "_" + opt)]) value = watolib.get_vs_flexible_notifications().from_html_vars("notification_method") user_attrs["notification_method"] = value else: user_attrs["fallback_contact"] = html.get_checkbox("fallback_contact") # Custom user attributes for name, attr in userdb.get_user_attributes(): value = attr.valuespec().from_html_vars('ua_' + name) user_attrs[name] = value # Generate user "object" to update user_object = {self._user_id: {"attributes": user_attrs, "is_new_user": self._is_new_user}} # The following call validates and updated the users edit_users(user_object) return "users"