Example #1
0
    def _delete_tag_group(self) -> ActionResult:
        del_id = request.get_item_input("_delete",
                                        dict(self._tag_config.get_tag_group_choices()))[1]

        if not request.has_var("_repair") and self._is_cleaning_up_user_tag_group_to_builtin(
                del_id):
            message: Union[bool,
                           str] = _("Transformed the user tag group \"%s\" to builtin.") % del_id
        else:
            message = _rename_tags_after_confirmation(self.breadcrumb(),
                                                      OperationRemoveTagGroup(del_id))
            if message is False:
                return FinalizeRequest(code=200)

        if message:
            self._tag_config.remove_tag_group(del_id)
            try:
                self._tag_config.validate_config()
            except MKGeneralException as e:
                raise MKUserError(None, "%s" % e)
            self._save_tags_and_update_hosts(self._tag_config.get_dict_format())
            add_change("edit-tags", _("Removed tag group %s (%s)") % (message, del_id))
            if isinstance(message, str):
                flash(message)
        return redirect(mode_url("tags"))
Example #2
0
    def _move_to_imported_folders(self, host_names_to_move) -> ActionResult:
        c = wato_confirm(
            _("Confirm moving hosts"),
            _('You are going to move the selected hosts to folders '
              'representing their original folder location in the system '
              'you did the import from. Please make sure that you have '
              'done an <b>inventory</b> before moving the hosts.'))
        if c is False:  # not yet confirmed
            return FinalizeRequest(code=200)
        if not c:
            return None  # browser reload

        # Create groups of hosts with the same target folder
        target_folder_names: Dict[str, List[HostName]] = {}
        for host_name in host_names_to_move:
            host = self._folder.host(host_name)
            imported_folder_name = host.attribute('imported_folder')
            if imported_folder_name is None:
                continue
            target_folder_names.setdefault(imported_folder_name, []).append(host_name)

            # Remove target folder information, now that the hosts are
            # at their target position.
            host.remove_attribute('imported_folder')

        # Now handle each target folder
        for imported_folder, host_names in target_folder_names.items():
            # Next problem: The folder path in imported_folder refers
            # to the Alias of the folders, not to the internal file
            # name. And we need to create folders not yet existing.
            target_folder = self._create_target_folder_from_aliaspath(imported_folder)
            self._folder.move_hosts(host_names, target_folder)

        flash(_("Successfully moved hosts to their original folder destinations."))
        return None
Example #3
0
    def action(self) -> ActionResult:
        delname = html.request.var("_delete")
        if delname and html.transaction_valid():
            if delname in watolib.timeperiods.builtin_timeperiods():
                raise MKUserError("_delete",
                                  _("Builtin timeperiods can not be modified"))

            usages = self._find_usages_of_timeperiod(delname)
            if usages:
                message = "<b>%s</b><br>%s:<ul>" % \
                            (_("You cannot delete this timeperiod."),
                             _("It is still in use by"))
                for title, link in usages:
                    message += '<li><a href="%s">%s</a></li>\n' % (link, title)
                message += "</ul>"
                raise MKUserError(None, message)

            c = wato_confirm(
                _("Confirm deletion of time period %s") % delname,
                _("Do you really want to delete the time period '%s'? I've checked it: "
                  "it is not being used by any rule or user profile right now."
                  ) % delname)
            if c:
                del self._timeperiods[delname]
                watolib.timeperiods.save_timeperiods(self._timeperiods)
                watolib.add_change("edit-timeperiods",
                                   _("Deleted timeperiod %s") % delname)
            elif c is False:
                return FinalizeRequest(code=200)
        return None
Example #4
0
    def _action(self) -> None:
        assert user.id is not None

        users = userdb.load_users(lock=True)
        user_spec = users[user.id]

        language = request.get_ascii_input_mandatory("language", "")
        # Set the users language if requested to set it explicitly
        if language != "_default_":
            user_spec["language"] = language
            user.language = language
            set_language_cookie(request, response, language)

        else:
            if "language" in user_spec:
                del user_spec["language"]
            user.reset_language()

        # load the new language
        localize(user.language)

        if user.may("general.edit_notifications") and user_spec.get(
                "notifications_enabled"):
            value = forms.get_input(get_vs_flexible_notifications(),
                                    "notification_method")
            user_spec["notification_method"] = value

        # Custom attributes
        if user.may("general.edit_user_attributes"):
            for name, attr in userdb.get_user_attributes():
                if not attr.user_editable():
                    continue

                perm_name = attr.permission()
                if perm_name and not user.may(perm_name):
                    continue

                vs = attr.valuespec()
                value = vs.from_html_vars("ua_" + name)
                vs.validate_value(value, "ua_" + name)
                # TODO: Dynamically fiddling around with a TypedDict is a bit questionable
                user_spec[name] = value  # type: ignore[literal-required]

        userdb.save_users(users)

        flash(_("Successfully updated user profile."))

        # In distributed setups with remote sites where the user can login, start the
        # user profile replication now which will redirect the user to the destination
        # page after completion. Otherwise directly open up the destination page.
        if user.authorized_login_sites():
            back_url = "user_profile_replicate.py?back=user_profile.py"
        else:
            back_url = "user_profile.py"

        # Ensure theme changes are applied without additional user interaction
        html.reload_whole_page(back_url)
        html.footer()

        raise FinalizeRequest(code=200)
Example #5
0
    def action(self) -> ActionResult:
        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 FinalizeRequest(code=200)

        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())
        return None
Example #6
0
    def action(self) -> ActionResult:
        if transactions.check_transaction():
            keys = self.load()

            try:
                key_id_str = request.var("key")
                if key_id_str is None:
                    raise Exception(
                        "cannot happen")  # is this really the case?
                key_id = int(key_id_str)
            except ValueError:
                raise MKUserError(None,
                                  _("You need to provide a valid key id."))

            if key_id not in keys:
                raise MKUserError(None,
                                  _("You need to provide a valid key id."))

            private_key = keys[key_id]["private_key"]

            value = self._vs_key().from_html_vars("key")
            self._vs_key().validate_value(value, "key")
            decrypt_private_key(private_key, value["passphrase"])

            self._send_download(keys, key_id)
            return FinalizeRequest(code=200)
        return None
Example #7
0
    def _delete_aux_tag(self) -> ActionResult:
        del_id = request.get_item_input("_del_aux",
                                        dict(self._tag_config.aux_tag_list.get_choices()))[1]

        # Make sure that this aux tag is not begin used by any tag group
        for group in self._tag_config.tag_groups:
            for grouped_tag in group.tags:
                if del_id in grouped_tag.aux_tag_ids:
                    raise MKUserError(
                        None,
                        _("You cannot delete this auxiliary tag. "
                          "It is being used in the tag group <b>%s</b>.") % group.title)

        message = _rename_tags_after_confirmation(self.breadcrumb(), OperationRemoveAuxTag(del_id))
        if message is False:
            return FinalizeRequest(code=200)

        if message:
            self._tag_config.aux_tag_list.remove(del_id)
            try:
                self._tag_config.validate_config()
            except MKGeneralException as e:
                raise MKUserError(None, "%s" % e)
            self._save_tags_and_update_hosts(self._tag_config.get_dict_format())
            add_change("edit-tags", _("Removed auxiliary tag %s (%s)") % (message, del_id))
            if isinstance(message, str):
                flash(message)
        return redirect(mode_url("tags"))
Example #8
0
    def action(self) -> ActionResult:
        connections = load_connection_config(lock=True)
        if html.request.has_var("_delete"):
            index = html.request.get_integer_input_mandatory("_delete")
            connection = connections[index]
            c = wato_confirm(
                _("Confirm deletion of LDAP connection"),
                _("Do you really want to delete the LDAP connection <b>%s</b>?"
                  ) % (connection["id"]))
            if c:
                self._add_change(
                    "delete-ldap-connection",
                    _("Deleted LDAP connection %s") % (connection["id"]))
                del connections[index]
                save_connection_config(connections)
            elif c is False:
                return FinalizeRequest(code=200)
            else:
                return None

        elif html.request.has_var("_move"):
            if not html.check_transaction():
                return None

            from_pos = html.request.get_integer_input_mandatory("_move")
            to_pos = html.request.get_integer_input_mandatory("_index")
            connection = connections[from_pos]
            self._add_change(
                "move-ldap-connection",
                _("Changed position of LDAP connection %s to %d") %
                (connection["id"], to_pos))
            del connections[from_pos]  # make to_pos now match!
            connections[to_pos:to_pos] = [connection]
            save_connection_config(connections)
        return None
Example #9
0
    def action(self) -> ActionResult:
        if html.request.has_var("_delete"):
            icon_name = html.request.var("_delete")
            if icon_name in self._load_custom_icons():
                c = wato_confirm(
                    _("Confirm Icon deletion"),
                    _("Do you really want to delete the icon <b>%s</b>?") %
                    icon_name)
                if c:
                    os.remove(
                        "%s/local/share/check_mk/web/htdocs/images/icons/%s.png"
                        % (cmk.utils.paths.omd_root, icon_name))
                elif c is False:
                    return FinalizeRequest(code=200)
                else:
                    return None

        elif html.request.has_var("_do_upload"):
            if not html.check_transaction():
                return None

            vs_upload = self._vs_upload()
            icon_info = vs_upload.from_html_vars('_upload_icon')
            vs_upload.validate_value(icon_info, '_upload_icon')
            self._upload_icon(icon_info)

        return None
Example #10
0
    def action(self) -> ActionResult:
        if self._may_edit_config() and html.request.has_var("_delete"):
            key_id_as_str = html.request.var("_delete")
            if key_id_as_str is None:
                raise Exception("cannot happen")
            key_id = int(key_id_as_str)
            if key_id not in self.keys:
                return None

            key = self.keys[key_id]

            if self._key_in_use(key_id, key):
                raise MKUserError("", _("This key is still used."))

            message = self._delete_confirm_msg()
            if key["owner"] != config.user.id:
                message += _(
                    "<br><b>Note</b>: this key has created by user <b>%s</b>"
                ) % key["owner"]
            c = html.confirm(message, add_header=self.title())
            if c:
                self.delete(key_id)
                self.save(self.keys)

            elif c is False:
                return FinalizeRequest(code=200)
        return None
Example #11
0
    def _export_audit_log(self) -> ActionResult:
        html.set_output_format("csv")

        if self._options["display"] == "daily":
            filename = "wato-auditlog-%s_%s.csv" % (render.date(
                time.time()), render.time_of_day(time.time()))
        else:
            filename = "wato-auditlog-%s_%s_days.csv" % (render.date(
                time.time()), self._options["display"][1])
        html.write(filename)

        html.response.headers[
            "Content-Disposition"] = "attachment; filename=\"%s\"" % filename

        titles = (
            _('Date'),
            _('Time'),
            _('Linkinfo'),
            _('User'),
            _('Action'),
            _('Text'),
        )
        html.write(','.join(titles) + '\n')
        for t, linkinfo, user, action, text in self._parse_audit_log():
            if linkinfo == '-':
                linkinfo = ''

            html.write_text(','.join((render.date(int(t)),
                                      render.time_of_day(int(t)), linkinfo,
                                      user, action, '"' + text + '"')) + '\n')
        return FinalizeRequest(code=200)
Example #12
0
    def action(self) -> ActionResult:
        if watolib.get_pending_changes_info():
            raise MKUserError(
                "newname",
                _("You cannot rename a host while you have pending changes."))

        newname = html.request.var("newname")
        self._check_new_host_name("newname", newname)
        c = wato_confirm(
            _("Confirm renaming of host"),
            _("Are you sure you want to rename the host <b>%s</b> into <b>%s</b>? "
              "This involves a restart of the monitoring core!") %
            (self._host.name(), newname))
        if c:
            # Creating pending entry. That makes the site dirty and that will force a sync of
            # the config to that site before the automation is being done.
            host_renaming_job = RenameHostBackgroundJob(
                self._host,
                title=_("Renaming of %s -> %s") % (self._host.name(), newname))
            renamings = [(watolib.Folder.current(), self._host.name(), newname)
                         ]
            host_renaming_job.set_function(rename_hosts_background_job,
                                           renamings)

            try:
                host_renaming_job.start()
            except background_job.BackgroundJobAlreadyRunning as e:
                raise MKGeneralException(
                    _("Another host renaming job is already running: %s") % e)

            return redirect(host_renaming_job.detail_url())

        if c is False:  # not yet confirmed
            return FinalizeRequest(code=200)
        return None
Example #13
0
    def action(self) -> ActionResult:
        if not transactions.check_transaction():
            return redirect(mode_url("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.from_config(
            self._tag_config_file.load_for_modification())
        changed_tag_group = cmk.utils.tags.TagGroup.from_config(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())
            _changes.add_change(
                "edit-hosttags",
                _("Created new host tag group '%s'") % changed_tag_group.id)
            flash(
                _("Created new host tag group '%s'") % changed_tag_group.title)
            return redirect(mode_url("tags"))

        # 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 = identify_modified_tags(
            changed_tag_group, self._untainted_tag_group)
        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(self.breadcrumb(), operation)
        if message is False:
            return FinalizeRequest(code=200)

        self._save_tags_and_update_hosts(
            changed_hosttags_config.get_dict_format())
        _changes.add_change(
            "edit-hosttags",
            _("Edited host tag group %s (%s)") % (message, self._id))
        if isinstance(message, str):
            flash(message)

        return redirect(mode_url("tags"))
Example #14
0
    def _action(self) -> None:
        assert config.user.id is not None

        users = userdb.load_users(lock=True)
        user = users[config.user.id]

        language = html.request.get_ascii_input_mandatory('language', "")
        # Set the users language if requested to set it explicitly
        if language != "_default_":
            user['language'] = language
            config.user.language = language
            html.set_language_cookie(language)

        else:
            if 'language' in user:
                del user['language']
            config.user.reset_language()

        # load the new language
        cmk.gui.i18n.localize(config.user.language)

        if config.user.may('general.edit_notifications') and user.get(
                "notifications_enabled"):
            value = forms.get_input(watolib.get_vs_flexible_notifications(),
                                    "notification_method")
            user["notification_method"] = value

        # Custom attributes
        if config.user.may('general.edit_user_attributes'):
            for name, attr in userdb.get_user_attributes():
                if not attr.user_editable():
                    continue

                if attr.permission() and not config.user.may(
                        attr.permission()):
                    continue

                vs = attr.valuespec()
                value = vs.from_html_vars('ua_' + name)
                vs.validate_value(value, "ua_" + name)
                user[name] = value

        userdb.save_users(users)

        flash(_("Successfully updated user profile."))

        # In distributed setups with remote sites where the user can login, start the
        # user profile replication now which will redirect the user to the destination
        # page after completion. Otherwise directly open up the destination page.
        if config.user.authorized_login_sites():
            back_url = "user_profile_replicate.py?back=user_profile.py"
        else:
            back_url = "user_profile.py"

        # Ensure theme changes are applied without additional user interaction
        html.reload_whole_page(back_url)
        html.footer()

        raise FinalizeRequest(code=200)
Example #15
0
    def _export_audit_log(self,
                          audit: List[AuditLogStore.Entry]) -> ActionResult:
        response.set_content_type("text/csv")

        if self._options["display"] == "daily":
            filename = "wato-auditlog-%s_%s.csv" % (
                render.date(time.time()),
                render.time_of_day(time.time()),
            )
        else:
            filename = "wato-auditlog-%s_%s_days.csv" % (
                render.date(time.time()),
                self._options["display"][1],
            )

        response.headers[
            "Content-Disposition"] = 'attachment; filename="%s"' % filename

        titles = [
            _("Date"),
            _("Time"),
            _("Object type"),
            _("Object"),
            _("User"),
            _("Action"),
            _("Summary"),
        ]

        if self._show_details:
            titles.append(_("Details"))

        resp = []

        resp.append(",".join(titles) + "\n")
        for entry in audit:
            columns = [
                render.date(int(entry.time)),
                render.time_of_day(int(entry.time)),
                entry.object_ref.object_type.name if entry.object_ref else "",
                entry.object_ref.ident if entry.object_ref else "",
                entry.user_id,
                entry.action,
                '"' + escaping.strip_tags(entry.text).replace('"', "'") + '"',
            ]

            if self._show_details:
                columns.append(
                    '"' +
                    escaping.strip_tags(entry.diff_text).replace('"', "'") +
                    '"')

            resp.append(",".join(columns) + "\n")

        response.set_data("".join(resp))

        return FinalizeRequest(code=200)
Example #16
0
 def _clear_audit_log_after_confirm(self) -> ActionResult:
     c = wato_confirm(_("Confirm deletion of audit log"),
                      _("Do you really want to clear the audit log?"))
     if c:
         self._clear_audit_log()
         flash(_("Cleared audit log."))
         return None
     if c is False:  # not yet confirmed
         return FinalizeRequest(code=200)
     return None  # browser reload
Example #17
0
def delete_host_after_confirm(delname) -> ActionResult:
    c = wato_confirm(_("Confirm host deletion"),
                     _("Do you really want to delete the host <tt>%s</tt>?") % delname)
    if c:
        watolib.Folder.current().delete_hosts([delname])
        # Delete host files
        return redirect(mode_url("folder", folder=watolib.Folder.current().path()))
    if c is False:  # not yet confirmed
        return FinalizeRequest(code=200)
    return None  # browser reload
Example #18
0
    def action(self) -> ActionResult:
        if request.var("_action") != "discard":
            return None

        if not transactions.check_transaction():
            return None

        if not self._may_discard_changes():
            return None

        if not self.has_changes():
            return None

        # Now remove all currently pending changes by simply restoring the last automatically
        # taken snapshot. Then activate the configuration. This should revert all pending changes.
        file_to_restore = self._get_last_wato_snapshot_file()

        if not file_to_restore:
            raise MKUserError(None,
                              _("There is no WATO snapshot to be restored."))

        msg = _("Discarded pending changes (Restored %s)") % file_to_restore

        # All sites and domains can be affected by a restore: Better restart everything.
        _changes.add_change(
            "changes-discarded",
            msg,
            domains=ABCConfigDomain.enabled_domains(),
            need_restart=True,
        )

        self._extract_snapshot(file_to_restore)
        activate_changes.execute_activate_changes([
            d.get_domain_request([])
            for d in ABCConfigDomain.enabled_domains()
        ])

        for site_id in activation_sites():
            self.confirm_site_changes(site_id)

        build_index_background()

        make_header(
            html,
            self.title(),
            breadcrumb=self.breadcrumb(),
            show_body_start=display_options.enabled(display_options.H),
            show_top_heading=display_options.enabled(display_options.T),
        )
        html.open_div(class_="wato")

        html.show_message(_("Successfully discarded all pending changes."))
        html.javascript("hide_changes_buttons();")
        html.footer()
        return FinalizeRequest(code=200)
Example #19
0
 def _delete_hosts_after_confirm(self, host_names) -> ActionResult:
     c = wato_confirm(
         _("Confirm deletion of %d hosts") % len(host_names),
         _("Do you really want to delete the %d selected hosts?") % len(host_names))
     if c:
         self._folder.delete_hosts(host_names)
         flash(_("Successfully deleted %d hosts") % len(host_names))
         return redirect(mode_url("folder", folder=self._folder.path()))
     if c is False:  # not yet confirmed
         return FinalizeRequest(code=200)
     return None  # browser reload
Example #20
0
    def action(self) -> ActionResult:
        renaming_config = self._vs_renaming_config().from_html_vars("")
        self._vs_renaming_config().validate_value(renaming_config, "")
        renamings = self._collect_host_renamings(renaming_config)

        if not renamings:
            flash(_("No matching host names"))
            return None

        warning = self._renaming_collision_error(renamings)
        if warning:
            flash(warning)
            return None

        message = HTMLWriter.render_b(
            _("Do you really want to rename to following hosts?"
              "This involves a restart of the monitoring core!"))

        rows = []
        for _folder, host_name, target_name in renamings:
            rows.append(
                HTMLWriter.render_tr(
                    HTMLWriter.render_td(host_name) +
                    HTMLWriter.render_td(" → %s" % target_name)))
        message += HTMLWriter.render_table(HTML().join(rows))

        nr_rename = len(renamings)
        c = _confirm(
            _("Confirm renaming of %d %s") %
            (nr_rename, ungettext("host", "hosts", nr_rename)),
            message,
        )
        if c:
            title = _("Renaming of %s") % ", ".join("%s → %s" % x[1:]
                                                    for x in renamings)
            host_renaming_job = RenameHostsBackgroundJob(title=title)
            host_renaming_job.set_function(rename_hosts_background_job,
                                           renamings)

            try:
                host_renaming_job.start()
            except background_job.BackgroundJobAlreadyRunning as e:
                raise MKGeneralException(
                    _("Another host renaming job is already running: %s") % e)

            return redirect(host_renaming_job.detail_url())
        if c is False:  # not yet confirmed
            return FinalizeRequest(code=200)
        return None  # browser reload
Example #21
0
    def page(self) -> None:
        _invalidate_auth_session()

        if auth_type == 'cookie':
            raise HTTPRedirect(config.url_prefix() + 'check_mk/login.py')

        # Implement HTTP logout with cookie hack
        if not html.request.has_cookie('logout'):
            html.response.headers['WWW-Authenticate'] = (
                'Basic realm="OMD Monitoring Site %s"' % config.omd_site())
            html.response.set_http_cookie('logout', '1')
            raise FinalizeRequest(http.client.UNAUTHORIZED)

        html.response.delete_cookie('logout')
        raise HTTPRedirect(config.url_prefix() + 'check_mk/')
Example #22
0
    def _export_audit_log(self,
                          audit: List[AuditLogStore.Entry]) -> ActionResult:
        html.set_output_format("csv")

        if self._options["display"] == "daily":
            filename = "wato-auditlog-%s_%s.csv" % (render.date(
                time.time()), render.time_of_day(time.time()))
        else:
            filename = "wato-auditlog-%s_%s_days.csv" % (render.date(
                time.time()), self._options["display"][1])

        html.response.headers[
            "Content-Disposition"] = "attachment; filename=\"%s\"" % filename

        titles = [
            _('Date'),
            _('Time'),
            _('Object type'),
            _('Object'),
            _('User'),
            _('Action'),
            _('Summary'),
        ]

        if self._show_details:
            titles.append(_('Details'))

        html.write(','.join(titles) + '\n')
        for entry in audit:
            columns = [
                render.date(int(entry.time)),
                render.time_of_day(int(entry.time)),
                entry.object_ref.object_type.name if entry.object_ref else "",
                entry.object_ref.ident if entry.object_ref else "",
                entry.user_id,
                entry.action,
                '"' + escaping.strip_tags(entry.text).replace('"', "'") + '"',
            ]

            if self._show_details:
                columns.append(
                    '"' +
                    escaping.strip_tags(entry.diff_text).replace('"', "'") +
                    '"')

            html.write(','.join(columns) + '\n')
        return FinalizeRequest(code=200)
Example #23
0
    def _delete_subfolder_after_confirm(self, subfolder_name) -> ActionResult:
        subfolder = self._folder.subfolder(subfolder_name)
        msg = _("Do you really want to delete the folder %s?") % subfolder.title()
        if not config.wato_hide_filenames:
            msg += _(" Its directory is <tt>%s</tt>.") % subfolder.filesystem_path()
        num_hosts = subfolder.num_hosts_recursively()
        if num_hosts:
            msg += _(
                " The folder contains <b>%d</b> hosts, which will also be deleted!") % num_hosts
        c = wato_confirm(_("Confirm folder deletion"), msg)

        if c:
            self._folder.delete_subfolder(subfolder_name)
            return redirect(mode_url("folder", folder=self._folder.path()))
        if c is False:  # not yet confirmed
            return FinalizeRequest(code=200)
        return None  # browser reload
Example #24
0
    def action(self) -> ActionResult:
        if not html.transaction_valid():
            return None

        action_var = html.request.get_str_input("_action")
        if action_var is None:
            return None

        if action_var != "delete":
            return self._handle_custom_action(action_var)

        confirm = wato_confirm(_("Confirm deletion"),
                               self._delete_confirm_message())
        if confirm is False:
            return FinalizeRequest(code=200)
        if not confirm:
            return None
        html.check_transaction()  # invalidate transid

        entries = self._store.load_for_modification()

        ident = html.request.get_ascii_input("_delete")
        if ident not in entries:
            raise MKUserError(
                "_delete",
                _("This %s does not exist.") % self._mode_type.name_singular())

        if ident not in self._store.filter_editable_entries(entries):
            raise MKUserError(
                "_delete",
                _("You are not allowed to delete this %s.") %
                self._mode_type.name_singular())

        self._validate_deletion(ident, entries[ident])

        entry = entries.pop(ident)
        self._add_change(
            "delete", entry,
            _("Removed the %s '%s'") %
            (self._mode_type.name_singular(), ident))
        self._store.save(entries)

        flash(_("The %s has been deleted.") % self._mode_type.name_singular())
        return redirect(mode_url(self._mode_type.list_mode_name()))
Example #25
0
    def action(self) -> ActionResult:
        renaming_config = self._vs_renaming_config().from_html_vars("")
        self._vs_renaming_config().validate_value(renaming_config, "")
        renamings = self._collect_host_renamings(renaming_config)

        if not renamings:
            flash(_("No matching host names"))
            return None

        warning = self._renaming_collision_error(renamings)
        if warning:
            flash(warning)
            return None

        message = _(
            "<b>Do you really want to rename to following hosts? This involves a restart of the monitoring core!</b>"
        )
        message += "<table>"
        for _folder, host_name, target_name in renamings:
            message += u"<tr><td>%s</td><td> → %s</td></tr>" % (host_name,
                                                                target_name)
        message += "</table>"

        c = wato_confirm(
            _("Confirm renaming of %d hosts") % len(renamings), HTML(message))
        if c:
            title = _("Renaming of %s") % ", ".join(u"%s → %s" % x[1:]
                                                    for x in renamings)
            host_renaming_job = RenameHostsBackgroundJob(title=title)
            host_renaming_job.set_function(rename_hosts_background_job,
                                           renamings)

            try:
                host_renaming_job.start()
            except background_job.BackgroundJobAlreadyRunning as e:
                raise MKGeneralException(
                    _("Another host renaming job is already running: %s") % e)

            return redirect(host_renaming_job.detail_url())
        if c is False:  # not yet confirmed
            return FinalizeRequest(code=200)
        return None  # browser reload
Example #26
0
    def action(self) -> ActionResult:
        varname = html.request.var("_varname")
        if not varname:
            return None

        action = html.request.var("_action")

        config_variable = config_variable_registry[varname]()
        def_value = self._default_values[varname]

        if action == "reset" and not is_a_checkbox(config_variable.valuespec()):
            c = wato_confirm(
                _("Resetting configuration variable"),
                _("Do you really want to reset the configuration variable <b>%s</b> "
                  "back to the default value of <b><tt>%s</tt></b>?") %
                (varname, config_variable.valuespec().value_to_text(def_value)))
        else:
            if not html.check_transaction():
                return None
            c = True  # no confirmation for direct toggle

        if c:
            if varname in self._current_settings:
                self._current_settings[varname] = not self._current_settings[varname]
            else:
                self._current_settings[varname] = not def_value
            msg = _("Changed Configuration variable %s to %s.") % (
                varname, "on" if self._current_settings[varname] else "off")
            watolib.save_global_settings(self._current_settings)

            watolib.add_change("edit-configvar",
                               msg,
                               domains=[config_variable.domain()],
                               need_restart=config_variable.need_restart())

            if action == "_reset":
                flash(msg)
            return redirect(mode_url("globalvars"))
        if c is False:
            return FinalizeRequest(code=200)
        return None
Example #27
0
    def page(self) -> None:
        assert config.user.id is not None

        _invalidate_auth_session()

        session_id = _get_session_id_from_cookie(config.user.id,
                                                 revalidate_cookie=True)
        userdb.on_logout(config.user.id, session_id)

        if auth_type == 'cookie':
            raise HTTPRedirect(config.url_prefix() + 'check_mk/login.py')

        # Implement HTTP logout with cookie hack
        if not request.has_cookie('logout'):
            response.headers['WWW-Authenticate'] = (
                'Basic realm="OMD Monitoring Site %s"' % config.omd_site())
            response.set_http_cookie('logout', '1', secure=request.is_secure)
            raise FinalizeRequest(http.client.UNAUTHORIZED)

        response.delete_cookie('logout')
        raise HTTPRedirect(config.url_prefix() + 'check_mk/')
Example #28
0
    def page(self) -> None:
        assert user.id is not None

        _invalidate_auth_session()

        session_id = _get_session_id_from_cookie(user.id,
                                                 revalidate_cookie=True)
        userdb.on_logout(user.id, session_id)

        if auth_type == "cookie":  # type: ignore[has-type]
            raise HTTPRedirect(url_prefix() + "check_mk/login.py")

        # Implement HTTP logout with cookie hack
        if not request.has_cookie("logout"):
            response.headers["WWW-Authenticate"] = (
                'Basic realm="OMD Monitoring Site %s"' % omd_site())
            response.set_http_cookie("logout", "1", secure=request.is_secure)
            raise FinalizeRequest(http.client.UNAUTHORIZED)

        response.delete_cookie("logout")
        raise HTTPRedirect(url_prefix() + "check_mk/")
Example #29
0
    def action(self) -> ActionResult:
        if html.request.var("_reset"):
            if not is_a_checkbox(self._valuespec):
                c = wato_confirm(
                    _("Resetting configuration variable"),
                    _("Do you really want to reset this configuration variable "
                      "back to its default value?"))
                if c is False:
                    return FinalizeRequest(code=200)
                if c is None:
                    return None
            elif not html.check_transaction():
                return None

            try:
                del self._current_settings[self._varname]
            except KeyError:
                pass

            msg: Union[
                HTML, str] = _("Resetted configuration variable %s to its default.") % self._varname
        else:
            new_value = self._valuespec.from_html_vars("ve")
            self._valuespec.validate_value(new_value, "ve")
            self._current_settings[self._varname] = new_value
            msg = _("Changed global configuration variable %s to %s.") \
                  % (self._varname, self._valuespec.value_to_text(new_value))
            # FIXME: THIS HTML(...) is needed because we do not know what we get from value_to_text!!
            msg = HTML(msg)

        self._save()
        watolib.add_change("edit-configvar",
                           msg,
                           sites=self._affected_sites(),
                           domains=[self._config_variable.domain()],
                           need_restart=self._config_variable.need_restart())

        page_menu = self.parent_mode()
        assert page_menu is not None
        return redirect(mode_url(page_menu.name()))
Example #30
0
    def action(self) -> ActionResult:
        if html.request.var('_delete'):
            delname = html.request.var("_delete")

            # FIXME: Raise an error if the attribute is still used

            confirm_txt = _(
                'Do you really want to delete the custom attribute "%s"?') % (
                    delname)

            c = wato_confirm(
                _("Confirm deletion of attribute \"%s\"") % delname,
                confirm_txt)
            if c:
                for index, attr in enumerate(self._attrs):
                    if attr['name'] == delname:
                        self._attrs.pop(index)
                save_custom_attrs_to_mk_file(self._all_attrs)
                self._update_config()
                add_change("edit-%sattrs" % self._type,
                           _("Deleted attribute %s") % (delname))
            elif c is False:
                return FinalizeRequest(code=200)
        return None