def action(self): if not html.check_transaction(): return "users" if self._user_id is None: # same as self._is_new_user self._user_id = UserID(allow_empty=False).from_html_vars("user_id") user_attrs = {} else: self._user_id = html.request.get_unicode_input_mandatory("edit").strip() user_attrs = self._users[UserId(self._user_id)] # Full name user_attrs["alias"] = html.request.get_unicode_input_mandatory("alias").strip() # Locking user_attrs["locked"] = html.get_checkbox("locked") increase_serial = False if (UserId(self._user_id) in self._users and self._users[UserId(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.get_str_input_mandatory("_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.get_str_input_mandatory("_password_" + self._pw_suffix(), '').strip() password2 = html.request.get_str_input_mandatory("_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"] = EmailAddress().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.get_str_input_mandatory("pager", '').strip() if cmk_version.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 language = html.request.get_ascii_input_mandatory("language", "") if language != "_default_": user_attrs["language"] = language elif "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"
def edit_annotation(): site_id = html.request.var("anno_site") or "" hostname = html.request.var("anno_host") service = html.request.var("anno_service") or None fromtime = float(html.request.var("anno_from")) untiltime = float(html.request.var("anno_until")) site_host_svc = (site_id, hostname, service) # Find existing annotation with this specification annotations = availability.load_annotations() annotation = availability.find_annotation(annotations, site_host_svc, fromtime, untiltime) if not annotation: value = { "from": fromtime, "until": untiltime, "text": "", } else: value = annotation.copy() value["host"] = hostname value["service"] = service value["site"] = site_id if html.check_transaction(): try: vs = _vs_annotation() value = vs.from_html_vars("_editanno") vs.validate_value(value, "_editanno") site_host_svc = value["site"], value["host"], value["service"] del value["site"] del value["host"] value["date"] = time.time() value["author"] = config.user.id availability.update_annotations(site_host_svc, value, replace_existing=annotation) html.request.del_var("filled_in") return False except MKUserError as e: html.user_error(e) title = _("Edit annotation of ") + hostname if service: title += "/" + service html.body_start(title) html.top_heading(title) html.begin_context_buttons() html.context_button(_("Abort"), html.makeuri([("anno_host", "")]), "abort") html.end_context_buttons() html.begin_form("editanno", method="GET") _vs_annotation().render_input_as_form("_editanno", value) html.button("save", _("Save")) html.hidden_fields() html.end_form() html.bottom_footer() html.body_end() return True
def action(self) -> ActionResult: # TODO: remove subclass specific things specifict things (everything with _type == 'user') if not html.check_transaction(): return None title = html.request.get_unicode_input_mandatory("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.get_unicode_input_mandatory('topic', '').strip() help_txt = html.request.get_unicode_input_mandatory('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.get_ascii_input_mandatory("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.get_ascii_input_mandatory('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 redirect(mode_url(self._type + "_attrs"))
def action(self): if not html.check_transaction(): return "tags" vs = self._valuespec() tag_group_spec = vs.from_html_vars("tag_group") vs.validate_value(tag_group_spec, "tag_group") # Create new object with existing host tags changed_hosttags_config = cmk.utils.tags.TagConfig() changed_hosttags_config.parse_config(self._tag_config_file.load_for_modification()) changed_tag_group = cmk.utils.tags.TagGroup(tag_group_spec) self._tag_group = changed_tag_group if self._new: # Inserts and verifies changed tag group changed_hosttags_config.insert_tag_group(changed_tag_group) try: changed_hosttags_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) self._save_tags_and_update_hosts(changed_hosttags_config.get_dict_format()) add_change("edit-hosttags", _("Created new host tag group '%s'") % changed_tag_group.id) return "tags", _("Created new host tag group '%s'") % changed_tag_group.title # Updates and verifies changed tag group changed_hosttags_config.update_tag_group(changed_tag_group) try: changed_hosttags_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) remove_tag_ids, replace_tag_ids = [], {} new_by_title = {tag.title: tag.id for tag in changed_tag_group.tags} for former_tag in self._untainted_tag_group.tags: # Detect renaming if former_tag.title in new_by_title: new_id = new_by_title[former_tag.title] if new_id != former_tag.id: # new_id may be None replace_tag_ids[former_tag.id] = new_id continue # Detect removal if former_tag.id is not None \ and former_tag.id not in [ tmp_tag.id for tmp_tag in changed_tag_group.tags ]: # remove explicit tag (hosts/folders) or remove it from tag specs (rules) remove_tag_ids.append(former_tag.id) tg_id = self._tag_group.id if tg_id is None: raise Exception("tag group ID not set") operation = OperationReplaceGroupedTags(tg_id, remove_tag_ids, replace_tag_ids) # Now check, if any folders, hosts or rules are affected message = _rename_tags_after_confirmation(operation) if message: self._save_tags_and_update_hosts(changed_hosttags_config.get_dict_format()) add_change("edit-hosttags", _("Edited host tag group %s (%s)") % (message, self._id)) return "tags", message is not True and message or None return "tags"
def action(self) -> ActionResult: if html.request.var("_search"): # just commit to search form return None # Operations on SUBFOLDERS if html.request.var("_delete_folder"): if html.check_transaction(): self._folder.delete_subfolder( html.request.var("_delete_folder")) return redirect(mode_url("folder", folder=self._folder.path())) if html.request.has_var("_move_folder_to"): if html.check_transaction(): what_folder = watolib.Folder.folder(html.request.var("_ident")) target_folder = watolib.Folder.folder( html.request.var("_move_folder_to")) watolib.Folder.current().move_subfolder_to( what_folder, target_folder) return redirect(mode_url("folder", folder=self._folder.path())) # Operations on HOSTS # Deletion of single hosts delname = html.request.var("_delete_host") if delname and watolib.Folder.current().has_host(delname): watolib.Folder.current().delete_hosts([delname]) return redirect(mode_url("folder", folder=self._folder.path())) # Move single hosts to other folders if html.request.has_var("_move_host_to"): hostname = html.request.var("_ident") if hostname: target_folder = watolib.Folder.folder( html.request.var("_move_host_to")) watolib.Folder.current().move_hosts([hostname], target_folder) return None # bulk operation on hosts if not html.transaction_valid(): return None # Host table: No error message on search filter reset if html.request.var("_hosts_reset_sorting") or html.request.var( "_hosts_sort"): return None selected_host_names = get_hostnames_from_checkboxes() if not selected_host_names: raise MKUserError( None, _("Please select some hosts before doing bulk operations on hosts." )) # Move if html.request.var("_bulk_move"): target_folder_path = html.request.var( "_bulk_moveto", html.request.var("_top_bulk_moveto")) if target_folder_path == "@": raise MKUserError("_bulk_moveto", _("Please select the destination folder")) target_folder = watolib.Folder.folder(target_folder_path) watolib.Folder.current().move_hosts(selected_host_names, target_folder) flash( _("Moved %d hosts to %s") % (len(selected_host_names), target_folder.title())) return None # Move to target folder (from import) if html.request.var("_bulk_movetotarget"): self._move_to_imported_folders(selected_host_names) return None # Deletion if html.request.var("_bulk_delete"): return self._delete_hosts(selected_host_names) search_text = html.request.get_unicode_input_mandatory("search", "") for request_var, mode_name in [ ("_bulk_inventory", "bulkinventory"), ("_parentscan", "parentscan"), ("_bulk_edit", "bulkedit"), ("_bulk_cleanup", "bulkcleanup"), ]: if html.request.var(request_var): return redirect( mode_url(mode_name, folder=watolib.Folder.current().path(), search=search_text, selection=weblib.selection_id())) return None
def action(self): if html.request.var("_search"): # just commit to search form return # Operations on SUBFOLDERS if html.request.var("_delete_folder"): if html.transaction_valid(): return self._delete_subfolder_after_confirm(html.request.var("_delete_folder")) return if html.request.has_var("_move_folder_to"): if html.check_transaction(): what_folder = watolib.Folder.folder(html.request.var("_ident")) target_folder = watolib.Folder.folder(html.request.var("_move_folder_to")) watolib.Folder.current().move_subfolder_to(what_folder, target_folder) return # Operations on HOSTS # Deletion of single hosts delname = html.request.var("_delete_host") if delname and watolib.Folder.current().has_host(delname): return delete_host_after_confirm(delname) # Move single hosts to other folders if html.request.has_var("_move_host_to"): hostname = html.request.var("_ident") if hostname: target_folder = watolib.Folder.folder(html.request.var("_move_host_to")) watolib.Folder.current().move_hosts([hostname], target_folder) return # bulk operation on hosts if not html.transaction_valid(): return # Host table: No error message on search filter reset if html.request.var("_hosts_reset_sorting") or html.request.var("_hosts_sort"): return selected_host_names = get_hostnames_from_checkboxes() if not selected_host_names: raise MKUserError(None, _("Please select some hosts before doing bulk operations on hosts.")) if html.request.var("_bulk_inventory"): return "bulkinventory" if html.request.var("_parentscan"): return "parentscan" # Deletion if html.request.var("_bulk_delete"): return self._delete_hosts_after_confirm(selected_host_names) # Move if html.request.var("_bulk_move"): target_folder_path = html.request.var("_bulk_moveto", html.request.var("_top_bulk_moveto")) if target_folder_path == "@": raise MKUserError("_bulk_moveto", _("Please select the destination folder")) target_folder = watolib.Folder.folder(target_folder_path) watolib.Folder.current().move_hosts(selected_host_names, target_folder) return None, _("Moved %d hosts to %s") % (len(selected_host_names), target_folder.title()) # Move to target folder (from import) if html.request.var("_bulk_movetotarget"): return self._move_to_imported_folders(selected_host_names) if html.request.var("_bulk_edit"): return "bulkedit" if html.request.var("_bulk_cleanup"): return "bulkcleanup"
def _show_page_user_profile(change_pw): start_async_replication = False if not config.user.id: raise MKUserError(None, _('Not logged in.')) if not config.user.may('general.edit_profile') and not config.user.may( 'general.change_password'): raise MKAuthException(_("You are not allowed to edit your user profile.")) if not config.wato_enabled: raise MKAuthException(_('User profiles can not be edited (WATO is disabled).')) success = None if html.request.has_var('_save') and html.check_transaction(): users = userdb.load_users(lock=True) try: # Profile edit (user options like language etc.) if config.user.may('general.edit_profile'): if not change_pw: set_lang = html.get_checkbox('_set_lang') language = html.request.var('language') # Set the users language if requested if set_lang: if language == '': language = None # Set custom language users[config.user.id]['language'] = language config.user.set_attribute("language", language) html.set_language_cookie(language) else: # Remove the customized language if 'language' in users[config.user.id]: del users[config.user.id]['language'] config.user.unset_attribute("language") # load the new language cmk.gui.i18n.localize(config.user.language()) user = users.get(config.user.id) if config.user.may('general.edit_notifications') and user.get( "notifications_enabled"): value = forms.get_input(watolib.get_vs_flexible_notifications(), "notification_method") users[config.user.id]["notification_method"] = value # Custom attributes if config.user.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr.user_editable(): if not attr.permission() or config.user.may(attr.permission()): vs = attr.valuespec() value = vs.from_html_vars('ua_' + name) vs.validate_value(value, "ua_" + name) users[config.user.id][name] = value # Change the password if requested password_changed = False if config.user.may('general.change_password'): cur_password = html.request.var('cur_password') password = html.request.var('password') password2 = html.request.var('password2', '') if change_pw: # Force change pw mode if not cur_password: raise MKUserError("cur_password", _("You need to provide your current password.")) if not password: raise MKUserError("password", _("You need to change your password.")) if cur_password == password: raise MKUserError("password", _("The new password must differ from your current one.")) if cur_password and password: if userdb.hook_login(config.user.id, cur_password) in [None, False]: raise MKUserError("cur_password", _("Your old password is wrong.")) if password2 and password != password2: raise MKUserError("password2", _("The both new passwords do not match.")) watolib.verify_password_policy(password) users[config.user.id]['password'] = hash_password(password) users[config.user.id]['last_pw_change'] = int(time.time()) if change_pw: # Has been changed, remove enforcement flag del users[config.user.id]['enforce_pw_change'] # Increase serial to invalidate old cookies if 'serial' not in users[config.user.id]: users[config.user.id]['serial'] = 1 else: users[config.user.id]['serial'] += 1 password_changed = True # Now, if in distributed environment where users can login to remote sites, # set the trigger for pushing the new auth information to the slave sites # asynchronous if config.user.authorized_login_sites(): start_async_replication = True userdb.save_users(users) if password_changed: # Set the new cookie to prevent logout for the current user login.set_auth_cookie(config.user.id) success = True except MKUserError as e: html.add_user_error(e.varname, e) else: users = userdb.load_users() watolib.init_wato_datastructures(with_wato_lock=True) # When in distributed setup, display the replication dialog instead of the normal # profile edit dialog after changing the password. if start_async_replication: user_profile_async_replication_page() return if change_pw: title = _("Change Password") else: title = _("Edit User Profile") html.header(title) # Rule based notifications: The user currently cannot simply call the according # WATO module due to WATO permission issues. So we cannot show this button # right now. if not change_pw: rulebased_notifications = watolib.load_configuration_settings().get( "enable_rulebased_notifications") if rulebased_notifications and config.user.may('general.edit_notifications'): html.begin_context_buttons() url = "wato.py?mode=user_notifications_p" html.context_button(_("Notifications"), url, "notifications") html.end_context_buttons() else: reason = html.request.var('reason') if reason == 'expired': html.p(_('Your password is too old, you need to choose a new password.')) else: html.p(_('You are required to change your password before proceeding.')) if success: html.reload_sidebar() if change_pw: html.message(_("Your password has been changed.")) raise HTTPRedirect(html.request.var('_origtarget', 'index.py')) else: html.message(_("Successfully updated user profile.")) # Ensure theme changes are applied without additional user interaction html.immediate_browser_redirect(0.5, html.makeuri([])) if html.has_user_errors(): html.show_user_errors() user = users.get(config.user.id) if user is None: html.show_warning(_("Sorry, your user account does not exist.")) html.footer() return # Returns true if an attribute is locked and should be read only. Is only # checked when modifying an existing user locked_attributes = userdb.locked_attributes(user.get('connector')) def is_locked(attr): return attr in locked_attributes html.begin_form("profile", method="POST") html.prevent_password_auto_completion() html.open_div(class_="wato") forms.header(_("Personal Settings")) if not change_pw: forms.section(_("Name"), simple=True) html.write_text(user.get("alias", config.user.id)) if config.user.may('general.change_password') and not is_locked('password'): forms.section(_("Current Password")) html.password_input('cur_password', autocomplete="new-password") forms.section(_("New Password")) html.password_input('password', autocomplete="new-password") forms.section(_("New Password Confirmation")) html.password_input('password2', autocomplete="new-password") if not change_pw and config.user.may('general.edit_profile'): select_language(user) # Let the user configure how he wants to be notified if not rulebased_notifications \ and config.user.may('general.edit_notifications') \ and user.get("notifications_enabled"): forms.section(_("Notifications")) html.help( _("Here you can configure how you want to be notified about host and service problems and " "other monitoring events.")) watolib.get_vs_flexible_notifications().render_input("notification_method", user.get("notification_method")) if config.user.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr.user_editable(): vs = attr.valuespec() forms.section(_u(vs.title())) value = user.get(name, vs.default_value()) if not attr.permission() or config.user.may(attr.permission()): vs.render_input("ua_" + name, value) html.help(_u(vs.help())) else: html.write(vs.value_to_text(value)) # Save button forms.end() html.button("_save", _("Save")) html.close_div() html.hidden_fields() html.end_form() html.footer()
def edit_dictionaries( dictionaries, # type: List[Tuple[str, Union[Transform, Dictionary]]] value, # type: Dict[str, Any] focus=None, # type: Optional[str] hover_help=True, # type: bool validate=None, # type: Optional[Callable[[Any], None]] buttontext=None, # type: Optional[str] title=None, # type: Optional[str] buttons=None, # type: List[Tuple[str, str, str]] method="GET", # type: str preview=False, # type: bool varprefix="", # type: str formname="form", # type: str consume_transid=True # type: bool ): if html.request.get_ascii_input("filled_in") == formname and html.transaction_valid(): if not preview and consume_transid: html.check_transaction() messages = [] # type: List[str] new_value = {} # type: Dict[str, Dict[str, Any]] for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname new_value[keyname] = {} try: edited_value = vs_dict.from_html_vars(dict_varprefix) vs_dict.validate_value(edited_value, dict_varprefix) new_value[keyname].update(edited_value) except MKUserError as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(e.varname, e) except Exception as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(None, e) if validate and not html.has_user_errors(): try: validate(new_value[keyname]) except MKUserError as e: messages.append("%s" % e) html.add_user_error(e.varname, e) if messages: messages_joined = "".join(["%s<br>\n" % m for m in messages]) if not preview: html.show_error(messages_joined) else: raise MKUserError(None, messages_joined) else: return new_value html.begin_form(formname, method=method) for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname subvalue = value.get(keyname, {}) vs_dict.render_input_as_form(dict_varprefix, subvalue) end() if buttons: for name, button_title, _icon in buttons: html.button(name, button_title) else: if buttontext is None: buttontext = _("Save") html.button("save", buttontext) # Should be ignored be hidden_fields, but I do not dare to change it there html.request.del_var("filled_in") html.hidden_fields() html.end_form()
def edit_dictionaries(dictionaries, value, focus=None, hover_help=True, validate=None, buttontext=None, title=None, buttons=None, method="GET", preview=False, varprefix="", formname="form", consume_transid=True): # Convert list of entries/dictionaries sections = [] for keyname, d in dictionaries: if isinstance(d, list): sections.append((keyname, title or _("Properties"), d)) else: sections.append((keyname, None, d)) # valuespec Dictionary, title used from dict if html.request.var("filled_in") == formname and html.transaction_valid(): if not preview and consume_transid: html.check_transaction() messages = [] new_value = {} for keyname, _section_title, entries in sections: if isinstance(entries, list): new_value[keyname] = value.get(keyname, {}).copy() for name, vs in entries: if len(sections) == 1: vp = varprefix else: vp = keyname + "_" + varprefix try: v = vs.from_html_vars(vp + name) vs.validate_value(v, vp + name) new_value[keyname][name] = v except MKUserError as e: messages.append("%s: %s" % (vs.title(), e)) html.add_user_error(e.varname, e) else: new_value[keyname] = {} try: edited_value = entries.from_html_vars(keyname) entries.validate_value(edited_value, keyname) new_value[keyname].update(edited_value) except MKUserError as e: messages.append("%s: %s" % (entries.title() or _("Properties"), e)) html.add_user_error(e.varname, e) except Exception as e: messages.append("%s: %s" % (entries.title() or _("Properties"), e)) html.add_user_error(None, e) if validate and not html.has_user_errors(): try: validate(new_value[keyname]) except MKUserError as e: messages.append(e) html.add_user_error(e.varname, e) if messages: messages_joined = "".join(["%s<br>\n" % m for m in messages]) if not preview: html.show_error(messages_joined) else: raise MKUserError(None, messages_joined) else: return new_value html.begin_form(formname, method=method) for keyname, title1, entries in sections: subvalue = value.get(keyname, {}) if isinstance(entries, list): header(title1) first = True for name, vs in entries: section(vs.title()) html.help(vs.help()) if name in subvalue: v = subvalue[name] else: v = vs.default_value() if len(sections) == 1: vp = varprefix else: vp = keyname + "_" + varprefix vs.render_input(vp + name, v) if (not focus and first) or (name == focus): vs.set_focus(vp + name) first = False else: entries.render_input_as_form(keyname, subvalue) end() if buttons: for name, button_title, _icon in buttons: html.button(name, button_title) else: if buttontext is None: buttontext = _("Save") html.button("save", buttontext) # Should be ignored be hidden_fields, but I do not dare to change it there html.request.del_var("filled_in") html.hidden_fields() html.end_form()
def action(self): if html.request.var("_delete"): delid = html.request.get_ascii_input_mandatory("_delete") if delid not in self._roles: raise MKUserError(None, _("This role does not exist.")) if html.transaction_valid() and self._roles[delid].get('builtin'): raise MKUserError(None, _("You cannot delete the builtin roles!")) users = userdb.load_users() for user in users.values(): if delid in user["roles"]: raise MKUserError( None, _("You cannot delete roles, that are still in use (%s)!" % delid)) c = wato_confirm( _("Confirm deletion of role %s") % delid, _("Do you really want to delete the role %s?") % delid) if c: self._rename_user_role(delid, None) # Remove from existing users del self._roles[delid] self._save_roles() watolib.add_change("edit-roles", _("Deleted role '%s'") % delid, sites=config.get_login_sites()) elif c is False: return "" elif html.request.var("_clone"): if html.check_transaction(): cloneid = html.request.get_ascii_input_mandatory("_clone") try: cloned_role = self._roles[cloneid] except KeyError: raise MKUserError(None, _("This role does not exist.")) newid = cloneid while newid in self._roles: newid += "x" new_role = {} new_role.update(cloned_role) new_alias = new_role["alias"] while not watolib.is_alias_used("roles", newid, new_alias)[0]: new_alias += _(" (copy)") new_role["alias"] = new_alias if cloned_role.get("builtin"): new_role["builtin"] = False new_role["basedon"] = cloneid self._roles[newid] = new_role self._save_roles() watolib.add_change("edit-roles", _("Created new role '%s'") % newid, sites=config.get_login_sites())
def edit_dictionaries( dictionaries: 'Sequence[Tuple[str, Union[Transform, Dictionary]]]', value: Dict[str, Any], focus: Optional[str] = None, hover_help: bool = True, validate: Optional[Callable[[Any], None]] = None, title: Optional[str] = None, method: str = "GET", preview: bool = False, varprefix: str = "", formname: str = "form", consume_transid: bool = True): if html.request.get_ascii_input( "filled_in") == formname and html.transaction_valid(): if not preview and consume_transid: html.check_transaction() messages: List[str] = [] new_value: Dict[str, Dict[str, Any]] = {} for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname new_value[keyname] = {} try: edited_value = vs_dict.from_html_vars(dict_varprefix) vs_dict.validate_value(edited_value, dict_varprefix) new_value[keyname].update(edited_value) except MKUserError as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(e.varname, e) except Exception as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(None, e) if validate and not html.has_user_errors(): try: validate(new_value[keyname]) except MKUserError as e: messages.append("%s" % e) html.add_user_error(e.varname, e) if messages: messages_joined = "".join(["%s<br>\n" % m for m in messages]) if not preview: html.show_error(messages_joined) else: raise MKUserError(None, messages_joined) else: return new_value html.begin_form(formname, method=method) for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname subvalue = value.get(keyname, {}) vs_dict.render_input_as_form(dict_varprefix, subvalue) end() # Should be ignored be hidden_fields, but I do not dare to change it there html.request.del_var("filled_in") html.hidden_fields() html.end_form()
def page_crashed(what): # Do not reveal crash context information to unauthenticated users or not permitted # users to prevent disclosure of internal information if not config.user.may("general.see_crash_reports"): html.header(_("Internal error")) html.show_error("<b>%s:</b> %s" % (_("Internal error"), sys.exc_info()[1])) html.p( _("An internal error occurred while processing your request. " "You can report this issue to your Check_MK administrator. " "Detailed information can be found in <tt>var/log/web.log</tt>.")) html.footer() return if what == "check": site = html.request.var("site") host = html.request.var("host") service = html.request.var("service") tardata = get_crash_report_archive_as_string(site, host, service) else: tardata = create_gui_crash_report(what) info = get_crash_info(tardata) if what == "check": title = _("Crashed Check Reporting") else: title = _("Internal error") html.header(title) show_context_buttons(what, tardata) if html.request.has_var("_report") and html.check_transaction(): details = handle_report_form(tardata, what) else: details = {} if what == "gui": # Unify different string types from exception messages to a unicode string exc_value = sys.exc_info()[1] try: exc_txt = six.text_type(exc_value) except UnicodeDecodeError: exc_txt = str(exc_value).decode("utf-8") html.show_error("<b>%s:</b> %s" % (_("Internal error"), exc_txt)) html.p( _("An internal error occured while processing your request. " "You can report this issue to the Check_MK team to help " "fixing this issue. Please use the form below for reporting.")) if info: warn_about_local_files(info) show_report_form(what, details) show_crash_report(info) show_crash_report_details(info) else: report_url = html.makeuri([("subject", "Check_MK Crash Report - " + get_version(what))], filename="mailto:" + get_crash_report_target(what)) html.message( _("This crash report is in a legacy format and can not be submitted " "automatically. Please download it manually and send it to <a href=\"%s\">%s</a>") % (report_url, get_crash_report_target(what))) show_old_dump_trace(tardata) show_agent_output(tardata) html.footer()
def page(self): watolib.init_wato_datastructures(with_wato_lock=True) if not config.user.may('wato.diag_host'): raise MKAuthException(_('You are not permitted to perform this action.')) if not html.check_transaction(): raise MKAuthException(_("Invalid transaction")) request = self.webapi_request() hostname = request.get("host") if not hostname: raise MKGeneralException(_('The hostname is missing.')) host = watolib.Host.host(hostname) if not host: raise MKGeneralException(_('The given host does not exist.')) if host.is_cluster(): raise MKGeneralException(_('This view does not support cluster hosts.')) host.need_permission("read") _test = request.get('_test') if not _test: raise MKGeneralException(_('The test is missing.')) # Execute a specific test if _test not in dict(ModeDiagHost.diag_host_tests()).keys(): raise MKGeneralException(_('Invalid test.')) # TODO: Use ModeDiagHost._vs_rules() for processing/validation? args = [""] * 13 for idx, what in enumerate([ 'ipaddress', 'snmp_community', 'agent_port', 'snmp_timeout', 'snmp_retries', 'tcp_connect_timeout', ]): args[idx] = request.get(what, "") if config.user.may('wato.add_or_modify_executables'): args[6] = request.get("datasource_program", "") if request.get("snmpv3_use"): snmpv3_use = { "0": "noAuthNoPriv", "1": "authNoPriv", "2": "authPriv", }.get(request.get("snmpv3_use")) args[7] = snmpv3_use if snmpv3_use != "noAuthNoPriv": snmpv3_auth_proto = { DropdownChoice.option_id("md5"): "md5", DropdownChoice.option_id("sha"): "sha" }.get(request.get("snmpv3_auth_proto")) args[8] = snmpv3_auth_proto args[9] = request.get("snmpv3_security_name") args[10] = request.get("snmpv3_security_password") if snmpv3_use == "authPriv": snmpv3_privacy_proto = { DropdownChoice.option_id("DES"): "DES", DropdownChoice.option_id("AES"): "AES" }.get(request.get("snmpv3_privacy_proto")) args[11] = snmpv3_privacy_proto args[12] = request.get("snmpv3_privacy_password") else: args[9] = request.get("snmpv3_security_name") result = watolib.check_mk_automation(host.site_id(), "diag-host", [hostname, _test] + args) return { "next_transid": html.transaction_manager.fresh_transid(), "status_code": result[0], "output": result[1], }