Example #1
0
    def page(self) -> None:
        is_configured = self._is_configured()
        is_configured_globally = self._varname in self._global_settings

        default_values = ABCConfigDomain.get_all_default_globals()

        defvalue = default_values[self._varname]
        value = self._current_settings.get(
            self._varname, self._global_settings.get(self._varname, defvalue))

        hint = self._config_variable.hint()
        if hint:
            html.show_warning(hint)

        html.begin_form("value_editor", method="POST")
        title = self._valuespec.title()
        assert isinstance(title, str)
        forms.header(title)
        if not active_config.wato_hide_varnames:
            forms.section(_("Configuration variable:"))
            html.tt(self._varname)

        forms.section(_("Current setting"))
        self._valuespec.render_input("ve", value)
        self._valuespec.set_focus("ve")
        html.help(self._valuespec.help())

        if is_configured_globally:
            self._show_global_setting()

        forms.section(_("Factory setting"))
        html.write_text(self._valuespec.value_to_html(defvalue))

        forms.section(_("Current state"))
        if is_configured_globally:
            html.write_text(
                _('This variable is configured in <a href="%s">global settings</a>.'
                  ) %
                ("wato.py?mode=edit_configvar&varname=%s" % self._varname))
        elif not is_configured:
            html.write_text(_("This variable is at factory settings."))
        else:
            curvalue = self._current_settings[self._varname]
            if is_configured_globally and curvalue == self._global_settings[
                    self._varname]:
                html.write_text(
                    _("Site setting and global setting are identical."))
            elif curvalue == defvalue:
                html.write_text(
                    _("Your setting and factory settings are identical."))
            else:
                html.write_text(self._valuespec.value_to_html(curvalue))

        forms.end()
        html.hidden_fields()
        html.end_form()
Example #2
0
    def _show_form(self) -> None:
        assert config.user.id is not None

        users = userdb.load_users()

        user = users.get(config.user.id)
        if user is None:
            html.show_warning(_("Sorry, your user account does not exist."))
            html.footer()
            return

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")
        forms.header(_("Personal settings"))

        forms.section(_("Name"), simple=True)
        html.write_text(user.get("alias", config.user.id))

        select_language(user)

        # Let the user configure how he wants to be notified
        rulebased_notifications = rulebased_notifications_enabled()
        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'):
            custom_user_attr_topics = get_user_attributes_by_topic()
            _show_custom_user_attr(user,
                                   custom_user_attr_topics.get("personal", []))
            forms.header(_("User interface settings"))
            _show_custom_user_attr(
                user, custom_user_attr_topics.get("interface", []))

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
Example #3
0
    def page(self):
        html.begin_form("random")
        forms.header(_("Add random hosts"))
        forms.section(_("Number to create"))
        html.write_text("%s: " % _("Hosts to create in each folder"))
        html.text_input("count", default_value="10", cssclass="number")
        html.set_focus("count")
        html.br()
        html.write_text("%s: " % _("Number of folders to create in each level"))
        html.text_input("folders", default_value="10", cssclass="number")
        html.br()
        html.write_text("%s: " % _("Levels of folders to create"))
        html.text_input("levels", default_value="1", cssclass="number")

        forms.end()
        html.hidden_fields()
        html.end_form()
Example #4
0
    def page(self):
        html.help(
            _("The renaming of hosts is a complex operation since a host's name is being "
              "used as a unique key in various places. It also involves stopping and starting "
              "of the monitoring core. You cannot rename a host while you have pending changes."
              ))

        html.begin_form("rename_host", method="POST")
        forms.header(_("Rename host %s") % self._host.name())
        forms.section(_("Current name"))
        html.write_text(self._host.name())
        forms.section(_("New name"))
        html.text_input("newname", "")
        forms.end()
        html.set_focus("newname")
        html.hidden_fields()
        html.end_form()
Example #5
0
    def page(self):
        new = self._folder.name() is None

        watolib.Folder.current().show_breadcrump()
        watolib.Folder.current().need_permission("read")

        if new and watolib.Folder.current().locked():
            watolib.Folder.current().show_locking_information()

        html.begin_form("edit_host", method="POST")

        # title
        forms.header(_("Title"))
        forms.section(_("Title"))
        TextUnicode().render_input("title", self._folder.title())
        html.set_focus("title")

        # folder name (omit this for root folder)
        if new or not watolib.Folder.current().is_root():
            if not config.wato_hide_filenames:
                forms.section(_("Internal directory name"))
                if new:
                    html.text_input("name")
                else:
                    html.write_text(self._folder.name())
                html.help(
                    _("This is the name of subdirectory where the files and "
                      "other folders will be created. You cannot change this later."
                      ))

        # Attributes inherited to hosts
        if new:
            parent = watolib.Folder.current()
            myself = None
        else:
            parent = watolib.Folder.current().parent()
            myself = watolib.Folder.current()

        configure_attributes(new, {"folder": myself}, "folder", parent, myself)

        forms.end()
        if new or not watolib.Folder.current().locked():
            html.button("save", _("Save & Finish"), "submit")
        html.hidden_fields()
        html.end_form()
Example #6
0
    def page(self):
        html.begin_form("random")
        forms.header(_("Create Random Hosts"))
        forms.section(_("Number to create"))
        html.write_text("%s: " % _("Hosts to create in each folder"))
        html.number_input("count", 10)
        html.set_focus("count")
        html.br()
        html.write_text("%s: " % _("Number of folders to create in each level"))
        html.number_input("folders", 10)
        html.br()
        html.write_text("%s: " % _("Levels of folders to create"))
        html.number_input("levels", 1)

        forms.end()
        html.button("start", _("Start!"), "submit")
        html.hidden_fields()
        html.end_form()
Example #7
0
    def _render_rule_reason(self, title, title_url, reason, reason_url, is_default, setting):
        if title_url:
            title = html.render_a(title, href=title_url)
        forms.section(title)

        if reason:
            reason = html.render_a(reason, href=reason_url)

        html.open_table(class_="setting")
        html.open_tr()
        if is_default:
            html.td(html.render_i(reason), class_="reason")
            html.td(setting, class_=["settingvalue", "unused"])
        else:
            html.td(reason, class_="reason")
            html.td(setting, class_=["settingvalue", "used"])
        html.close_tr()
        html.close_table()
Example #8
0
    def _show_labels(self, labels, object_type, label_sources):
        forms.section(_("Effective labels"))
        html.open_table(class_="setting")
        html.open_tr()

        html.open_td(class_="reason")
        html.i(_("Explicit, ruleset, discovered"))
        html.close_td()
        html.open_td(class_=["settingvalue", "used"])
        html.write(
            cmk.gui.view_utils.render_labels(labels,
                                             object_type,
                                             with_links=False,
                                             label_sources=label_sources))
        html.close_td()

        html.close_tr()
        html.close_table()
Example #9
0
    def _show_custom_user_attributes(self, topic):
        for name, attr in userdb.get_user_attributes():
            if topic is not None and topic != attr.topic():
                continue  # skip attrs of other topics

            vs = attr.valuespec()
            forms.section(_u(vs.title()))
            if not self._is_locked(name):
                vs.render_input("ua_" + name,
                                self._user.get(name, vs.default_value()))
            else:
                html.write(
                    vs.value_to_text(self._user.get(name, vs.default_value())))
                # Render hidden to have the values kept after saving
                html.open_div(style="display:none")
                vs.render_input("ua_" + name,
                                self._user.get(name, vs.default_value()))
                html.close_div()
            html.help(_u(vs.help()))
Example #10
0
def select_language(user):
    languages: Choices = [
        l for l in get_languages() if not config.hide_language(l[0])
    ]
    if not languages:
        return

    current_language = user.get("language")
    if current_language is None:
        current_language = "_default_"

    languages.insert(0, ("_default_", _("Use the default language (%s)") %
                         get_language_alias(config.default_language)))

    forms.section(_("Language"))
    html.dropdown("language", languages, deflt=current_language)
    html.help(
        _('Configure the language to be used by the user in the user interface here.'
          ))
Example #11
0
    def _select_attributes_for_bulk_cleanup(self, hosts):
        num_shown = 0
        for attr in host_attribute_registry.get_sorted_host_attributes():
            attrname = attr.name()

            if not attr.show_in_host_cleanup():
                continue

            # only show attributes that at least on host have set
            num_haveit = 0
            for host in hosts:
                if host.has_explicit_attribute(attrname):
                    num_haveit += 1

            if num_haveit == 0:
                continue

            # If the attribute is mandatory and no value is inherited
            # by file or folder, the attribute cannot be cleaned.
            container = self._folder
            is_inherited = False
            while container:
                if container.has_explicit_attribute(attrname):
                    is_inherited = True
                    break
                container = container.parent()

            num_shown += 1

            # Legend and Help
            forms.section(attr.title())

            if attr.is_mandatory() and not is_inherited:
                html.write_text(
                    _("This attribute is mandatory and there is no value "
                      "defined in the host list or any parent folder."))
            else:
                label = "clean this attribute on <b>%s</b> hosts" % \
                    (num_haveit == len(hosts) and "all selected" or str(num_haveit))
                html.checkbox("_clean_%s" % attrname, False, label=label)
            html.help(attr.help())

        return num_shown > 0
Example #12
0
    def page(self):
        is_configured = self._varname in self._current_settings
        is_configured_globally = self._varname in self._global_settings

        default_values = watolib.ABCConfigDomain.get_all_default_globals()

        defvalue = default_values[self._varname]
        value = self._current_settings.get(self._varname,
                                           self._global_settings.get(self._varname, defvalue))

        html.begin_form("value_editor", method="POST")
        forms.header(self._valuespec.title())
        if not config.wato_hide_varnames:
            forms.section(_("Configuration variable:"))
            html.tt(self._varname)

        forms.section(_("Current setting"))
        self._valuespec.render_input("ve", value)
        self._valuespec.set_focus("ve")
        html.help(self._valuespec.help())

        if is_configured_globally:
            self._show_global_setting()

        forms.section(_("Factory setting"))
        html.write_html(self._valuespec.value_to_text(defvalue))

        forms.section(_("Current state"))
        if is_configured_globally:
            html.write_text(
                _("This variable is configured in <a href=\"%s\">global settings</a>.") %
                ("wato.py?mode=edit_configvar&varname=%s" % self._varname))
        elif not is_configured:
            html.write_text(_("This variable is at factory settings."))
        else:
            curvalue = self._current_settings[self._varname]
            if is_configured_globally and curvalue == self._global_settings[self._varname]:
                html.write_text(_("Site setting and global setting are identical."))
            elif curvalue == defvalue:
                html.write_text(_("Your setting and factory settings are identical."))
            else:
                html.write(self._valuespec.value_to_text(curvalue))

        forms.end()
        html.button("save", _("Save"))
        if self._config_variable.allow_reset() and is_configured:
            curvalue = self._current_settings[self._varname]
            html.button(
                "_reset",
                _("Remove explicit setting") if curvalue == defvalue else _("Reset to default"))
        html.hidden_fields()
        html.end_form()
Example #13
0
    def page(self):
        self._folder.show_breadcrump()

        # Show search form
        html.begin_form("edit_host", method="GET")
        html.prevent_password_auto_completion()
        forms.header(_("General Properties"))
        forms.section(_("Hostname"))
        html.text_input("host_search_host")
        html.set_focus("host_search_host")

        # Attributes
        configure_attributes(False, {}, "host_search", parent=None, varprefix="host_search_")

        # Button
        forms.end()
        html.button("_local", _("Search in %s") % self._folder.title(), "submit")
        html.hidden_field("host_search", "1")
        html.hidden_fields()
        html.end_form()
Example #14
0
    def _select_attributes_for_bulk_cleanup(self, hosts):
        attributes = self._get_attributes_for_bulk_cleanup(hosts)

        for attr, is_inherited, num_haveit in attributes:
            # Legend and Help
            forms.section(attr.title())

            if attr.is_mandatory() and not is_inherited:
                html.write_text(
                    _("This attribute is mandatory and there is no value "
                      "defined in the host list or any parent folder."))
            else:
                label = "clean this attribute on <b>%s</b> hosts" % \
                    (num_haveit == len(hosts) and "all selected" or str(num_haveit))
                html.checkbox("_clean_%s" % attr.name(), False, label=label)
            html.help(attr.help())

        forms.end()

        if not attributes:
            html.write_text(_("The selected hosts have no explicit attributes"))
Example #15
0
    def _show_form(self, profile_changed: bool) -> None:
        assert config.user.id is not None

        users = userdb.load_users()

        if profile_changed:
            html.reload_sidebar()
            html.show_message(_("Successfully updated user profile."))
            # Ensure theme changes are applied without additional user interaction
            html.immediate_browser_redirect(0.5, makeuri(global_request, []))

        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

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")
        forms.header(self._page_title())

        forms.section(_("Name"), simple=True)
        html.write_text(user.get("alias", config.user.id))

        select_language(user)

        # Let the user configure how he wants to be notified
        rulebased_notifications = rulebased_notifications_enabled()
        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))

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
Example #16
0
def select_language(user):
    languages = [
        l for l in cmk.gui.i18n.get_languages()
        if not config.hide_language(l[0])
    ]
    if languages:
        active = 'language' in user
        forms.section(_("Language"),
                      checkbox=('_set_lang', active, 'language'))
        default_label = _('Default: %s') % cmk.gui.i18n.get_language_alias(
            config.default_language)
        html.div(default_label,
                 class_="inherited",
                 id_="attr_default_language",
                 style="display: none" if active else "")
        html.open_div(id_="attr_entry_language",
                      style="display: none" if not active else "")

        language = user.get('language') if user.get(
            'language') is not None else ''

        # Transform 'en' configured language to empty string for compatibility reasons
        if language == "en":
            language = ""

        html.dropdown("language", languages, deflt=language)
        html.close_div()
        html.help(
            _('Configure the default language '
              'to be used by the user in the user interface here. If you do not check '
              'the checkbox, then the system default will be used.<br><br>'
              'Note: currently Multisite is internationalized '
              'but comes without any actual localisations (translations). If you want to '
              'create you own translation, you find <a href="%(url)s">documentation online</a>.'
              ) %
            {
                "url":
                "https://mathias-kettner.com/checkmk_multisite_cmk.gui.i18n.html"
            })
Example #17
0
    def _show_form(self) -> None:
        assert user.id is not None

        credentials = load_two_factor_credentials(user.id)
        webauthn_credentials = credentials["webauthn_credentials"]
        backup_codes = credentials["backup_codes"]

        html.begin_form("two_factor", method="POST")
        html.div("", id_="webauthn_message")
        forms.header(_("Credentials"))

        forms.section(_("Registered credentials"), simple=True)
        if webauthn_credentials:
            self._show_credentials(webauthn_credentials)
        else:
            html.i(_("No credentials registered"))

        forms.section(_("Backup codes"), simple=True)
        if backup_codes:
            html.p(
                _(
                    "You have %d unused backup codes left. You can use them as one-time password "
                    "if your key is not available."
                )
                % len(backup_codes)
            )
            html.i(
                _(
                    "If you regenerate backup codes, you automatically invalidate the existing codes."
                )
            )
        else:
            html.i(_("No backup codes created yet."))

        forms.end()

        html.hidden_fields()
        html.end_form()
        html.footer()
Example #18
0
    def _show_form(self, profile_changed: bool) -> None:
        assert config.user.id is not None

        users = userdb.load_users()

        change_reason = html.request.get_ascii_input('reason')

        if change_reason == 'expired':
            html.p(
                _('Your password is too old, you need to choose a new password.'
                  ))
        elif change_reason == 'enforced':
            html.p(
                _('You are required to change your password before proceeding.'
                  ))

        if profile_changed:
            html.show_message(_("Your password has been changed."))
            if change_reason:
                raise HTTPRedirect(
                    html.request.get_str_input_mandatory(
                        '_origtarget', 'index.py'))

        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

        locked_attributes = userdb.locked_attributes(user.get('connector'))
        if "password" in locked_attributes:
            raise MKUserError(
                "cur_password",
                _("You can not change your password, because it is "
                  "managed by another system."))

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")
        forms.header(self._page_title())

        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")

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
Example #19
0
    def page(self) -> None:
        html.begin_form("group")
        forms.header(_("Properties"))
        forms.section(_("Name"), simple=not self._new, is_required=True)
        html.help(
            _("The name of the group is used as an internal key. It cannot be "
              "changed later. It is also visible in the status GUI."))
        if self._new:
            html.text_input("name")
            html.set_focus("name")
        else:
            html.write_text(self._name)
            html.set_focus("alias")

        forms.section(_("Alias"), is_required=True)
        html.help(_("An alias or description of this group."))
        html.text_input("alias", self.group["alias"])

        self._show_extra_page_elements()

        forms.end()
        html.hidden_fields()
        html.end_form()
Example #20
0
    def _show_form(self) -> None:
        assert user.id is not None

        users = userdb.load_users()

        change_reason = request.get_ascii_input("reason")

        if change_reason == "expired":
            html.p(
                _("Your password is too old, you need to choose a new password."
                  ))
        elif change_reason == "enforced":
            html.p(
                _("You are required to change your password before proceeding."
                  ))

        user_spec = users.get(user.id)
        if user_spec is None:
            html.show_warning(_("Sorry, your user account does not exist."))
            html.footer()
            return

        locked_attributes = userdb.locked_attributes(
            user_spec.get("connector"))
        if "password" in locked_attributes:
            raise MKUserError(
                "cur_password",
                _("You can not change your password, because it is "
                  "managed by another system."),
            )

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")
        forms.header(self._page_title())

        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")

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
Example #21
0
 def _show_try_form(self):
     html.begin_form('try')
     forms.header(_('Try Pattern Match'))
     forms.section(_('Hostname'))
     self._vs_host().render_input("host", self._hostname)
     forms.section(_('Logfile'))
     html.text_input('file')
     forms.section(_('Text to match'))
     html.help(
         _('You can insert some text (e.g. a line of the logfile) to test the patterns defined '
           'for this logfile. All patterns for this logfile are listed below. Matching patterns '
           'will be highlighted after clicking the "Try out" button.'))
     html.text_input('match', cssclass='match', size=100)
     forms.end()
     html.button('_try', _('Try out'))
     html.request.del_var('folder')  # Never hand over the folder here
     html.hidden_fields()
     html.end_form()
Example #22
0
 def _show_try_form(self):
     html.begin_form("try")
     forms.header(_("Try Pattern Match"))
     forms.section(_("Hostname"))
     self._vs_host().render_input("host", self._hostname)
     forms.section(_("Logfile"))
     html.help(_("Here you need to insert the original file or pathname"))
     html.text_input("file", size=80)
     forms.section(_("Text to match"))
     html.help(
         _("You can insert some text (e.g. a line of the logfile) to test the patterns defined "
           "for this logfile. All patterns for this logfile are listed below. Matching patterns "
           'will be highlighted after clicking the "Try out" button.'))
     html.text_input("match", cssclass="match", size=100)
     forms.end()
     html.button("_try", _("Try out"))
     request.del_var("folder")  # Never hand over the folder here
     html.hidden_fields()
     html.end_form()
Example #23
0
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.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.reset_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) is 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.show_message(_("Your password has been changed."))
            raise HTTPRedirect(html.request.var('_origtarget', 'index.py'))
        else:
            html.show_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()
Example #24
0
    def _output_analysed_ruleset(self,
                                 all_rulesets,
                                 rulespec,
                                 svc_desc_or_item,
                                 svc_desc,
                                 known_settings=None):
        if known_settings is None:
            known_settings = self._PARAMETERS_UNKNOWN

        def rule_url(rule):
            return watolib.folder_preserving_link([
                ('mode', 'edit_rule'),
                ('varname', varname),
                ('rule_folder', rule.folder.path()),
                ('rulenr', rule.index()),
                ('host', self._hostname),
                ('item', watolib.mk_repr(svc_desc_or_item)
                 if svc_desc_or_item else ''),
                ('service', watolib.mk_repr(svc_desc) if svc_desc else ''),
            ])

        varname = rulespec.name
        valuespec = rulespec.valuespec

        url = watolib.folder_preserving_link([
            ('mode', 'edit_ruleset'),
            ('varname', varname),
            ('host', self._hostname),
            ('item', watolib.mk_repr(svc_desc_or_item)),
            ('service', watolib.mk_repr(svc_desc)),
        ])

        forms.section(html.render_a(rulespec.title, url))

        ruleset = all_rulesets.get(varname)
        setting, rules = ruleset.analyse_ruleset(self._hostname,
                                                 svc_desc_or_item, svc_desc)

        html.open_table(class_="setting")
        html.open_tr()
        html.open_td(class_="reason")

        # Show reason for the determined value
        if len(rules) == 1:
            rule_folder, rule_index, rule = rules[0]
            url = rule_url(rule)
            html.a(_("Rule %d in %s") % (rule_index + 1, rule_folder.title()),
                   href=rule_url(rule))

        elif len(rules) > 1:
            html.a("%d %s" % (len(rules), _("Rules")), href=url)

        else:
            html.i(_("Default Value"))
        html.close_td()

        # Show the resulting value or factory setting
        html.open_td(
            class_=["settingvalue", "used" if len(rules) > 0 else "unused"])

        if isinstance(known_settings,
                      dict) and "tp_computed_params" in known_settings:
            computed_at = known_settings["tp_computed_params"]["computed_at"]
            html.write_text(
                _("Timespecific parameters computed at %s") %
                cmk.utils.render.date_and_time(computed_at))
            html.br()
            known_settings = known_settings["tp_computed_params"]["params"]

        # In some cases we now the settings from a check_mk automation
        if known_settings is self._PARAMETERS_OMIT:
            return

        # Special handling for logwatch: The check parameter is always None. The actual
        # patterns are configured in logwatch_rules. We do not have access to the actual
        # patterns here but just to the useless "None". In order not to complicate things
        # we simply display nothing here.
        if varname == "logwatch_rules":
            pass

        elif known_settings is not self._PARAMETERS_UNKNOWN:
            try:
                html.write(valuespec.value_to_text(known_settings))
            except Exception as e:
                if config.debug:
                    raise
                html.write_text(
                    _("Invalid parameter %r: %s") % (known_settings, e))

        else:
            # For match type "dict" it can be the case the rule define some of the keys
            # while other keys are taken from the factory defaults. We need to show the
            # complete outcoming value here.
            if rules and ruleset.match_type() == "dict":
                if rulespec.factory_default is not watolib.Rulespec.NO_FACTORY_DEFAULT \
                    and rulespec.factory_default is not watolib.Rulespec.FACTORY_DEFAULT_UNUSED:
                    fd = rulespec.factory_default.copy()
                    fd.update(setting)
                    setting = fd

            if valuespec and not rules:  # show the default value
                if rulespec.factory_default is watolib.Rulespec.FACTORY_DEFAULT_UNUSED:
                    # Some rulesets are ineffective if they are empty
                    html.write_text(_("(unused)"))

                elif rulespec.factory_default is not watolib.Rulespec.NO_FACTORY_DEFAULT:
                    # If there is a factory default then show that one
                    setting = rulespec.factory_default
                    html.write(valuespec.value_to_text(setting))

                elif ruleset.match_type() in ("all", "list"):
                    # Rulesets that build lists are empty if no rule matches
                    html.write_text(_("(no entry)"))

                else:
                    # Else we use the default value of the valuespec
                    html.write(
                        valuespec.value_to_text(valuespec.default_value()))

            # We have a setting
            elif valuespec:
                if ruleset.match_type() == "all":
                    html.write(", ".join(
                        [valuespec.value_to_text(e) for e in setting]))
                else:
                    html.write(valuespec.value_to_text(setting))

            # Binary rule, no valuespec, outcome is True or False
            else:
                icon_name = "rule_%s%s" % ("yes" if setting else "no",
                                           "_off" if not rules else '')
                html.icon(title=_("yes") if setting else _("no"),
                          icon=icon_name)
        html.close_td()
        html.close_tr()
        html.close_table()
Example #25
0
    def _show_start_form(self):
        html.begin_form("parentscan", method="POST")
        html.hidden_fields()

        # Mode of action
        html.open_p()
        if not self._complete_folder:
            num_selected = len(get_hosts_from_checkboxes())
            html.write_text(_("You have selected <b>%d</b> hosts for parent scan. ") % num_selected)
        html.p(
            _(
                "The parent scan will try to detect the last gateway "
                "on layer 3 (IP) before a host. This will be done by "
                "calling <tt>traceroute</tt>. If a gateway is found by "
                "that way and its IP address belongs to one of your "
                "monitored hosts, that host will be used as the hosts "
                "parent. If no such host exists, an artifical ping-only "
                "gateway host will be created if you have not disabled "
                "this feature."
            )
        )

        forms.header(_("Settings for Parent Scan"))

        self._settings = ParentScanSettings(
            **user.load_file(
                "parentscan",
                {
                    "where": "subfolder",
                    "alias": _("Created by parent scan"),
                    "recurse": True,
                    "select": "noexplicit",
                    "timeout": 8,
                    "probes": 2,
                    "ping_probes": 5,
                    "max_ttl": 10,
                    "force_explicit": False,
                },
            )
        )

        # Selection
        forms.section(_("Selection"))
        if self._complete_folder:
            html.checkbox("recurse", self._settings.recurse, label=_("Include all subfolders"))
            html.br()
        html.radiobutton(
            "select",
            "noexplicit",
            self._settings.select == "noexplicit",
            _("Skip hosts with explicit parent definitions (even if empty)") + "<br>",
        )
        html.radiobutton(
            "select",
            "no",
            self._settings.select == "no",
            _("Skip hosts hosts with non-empty parents (also if inherited)") + "<br>",
        )
        html.radiobutton(
            "select", "ignore", self._settings.select == "ignore", _("Scan all hosts") + "<br>"
        )

        # Performance
        forms.section(_("Performance"))
        html.open_table()
        html.open_tr()
        html.open_td()
        html.write_text(_("Timeout for responses") + ":")
        html.close_td()
        html.open_td()
        html.text_input("timeout", str(self._settings.timeout), size=2, cssclass="number")
        html.write_text(_("sec"))
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.open_td()
        html.write_text(_("Number of probes per hop") + ":")
        html.close_td()
        html.open_td()
        html.text_input("probes", str(self._settings.probes), size=2, cssclass="number")
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.open_td()
        html.write_text(_("Maximum distance (TTL) to gateway") + ":")
        html.close_td()
        html.open_td()
        html.text_input("max_ttl", str(self._settings.max_ttl), size=2, cssclass="number")
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.open_td()
        html.write_text(_("Number of PING probes") + ":")
        html.help(
            _(
                "After a gateway has been found, Check_MK checks if it is reachable "
                "via PING. If not, it is skipped and the next gateway nearer to the "
                "monitoring core is being tried. You can disable this check by setting "
                "the number of PING probes to 0."
            )
        )
        html.close_td()
        html.open_td()
        html.text_input("ping_probes", str(self._settings.ping_probes), size=2, cssclass="number")
        html.close_td()
        html.close_tr()
        html.close_table()

        # Configuring parent
        forms.section(_("Configuration"))
        html.checkbox(
            "force_explicit",
            deflt=self._settings.force_explicit,
            label=_(
                "Force explicit setting for parents even if setting matches that of the folder"
            ),
        )

        # Gateway creation
        forms.section(_("Creation of gateway hosts"))
        html.write_text(_("Create gateway hosts in"))
        html.open_ul()

        html.radiobutton(
            "where",
            "subfolder",
            self._settings.where == "subfolder",
            _("in the subfolder <b>%s/Parents</b>") % Folder.current_disk_folder().title(),
        )

        html.br()
        html.radiobutton(
            "where",
            "here",
            self._settings.where == "here",
            _("directly in the folder <b>%s</b>") % Folder.current_disk_folder().title(),
        )
        html.br()
        html.radiobutton(
            "where", "there", self._settings.where == "there", _("in the same folder as the host")
        )
        html.br()
        html.radiobutton(
            "where", "nowhere", self._settings.where == "nowhere", _("do not create gateway hosts")
        )
        html.close_ul()
        html.write_text(_("Alias for created gateway hosts") + ": ")
        html.text_input("alias", default_value=self._settings.alias)

        forms.end()

        # Start button
        html.button("_start", _("Start"))
        html.hidden_fields()
        html.end_form()
Example #26
0
    def _show_service_info(self, all_rulesets):
        serviceinfo = watolib.check_mk_automation(
            self._host.site_id(), "analyse-service",
            [self._hostname, self._service])
        if not serviceinfo:
            return

        forms.header(_("Check origin and parameters"),
                     isopen=True,
                     narrow=True,
                     css="rulesettings")
        origin = serviceinfo["origin"]
        origin_txt = {
            "active": _("Active check"),
            "static": _("Manual check"),
            "auto": _("Inventorized check"),
            "classic": _("Classical check"),
        }[origin]
        self._render_rule_reason(_("Type of check"), None, "", "", False,
                                 origin_txt)

        # First case: discovered checks. They come from var/check_mk/autochecks/HOST.
        if origin == "auto":
            checkgroup = serviceinfo["checkgroup"]
            checktype = serviceinfo["checktype"]
            if not checkgroup:
                self._render_rule_reason(
                    _("Parameters"), None, "", "", True,
                    _("This check is not configurable via WATO"))

            # Logwatch needs a special handling, since it is not configured
            # via checkgroup_parameters but via "logwatch_rules" in a special
            # WATO module.
            elif checkgroup == "logwatch":
                rulespec = rulespec_registry["logwatch_rules"]
                self._output_analysed_ruleset(
                    all_rulesets,
                    rulespec,
                    svc_desc_or_item=serviceinfo["item"],
                    svc_desc=self._service,
                    known_settings=serviceinfo["parameters"])

            else:
                # Note: some discovered checks have a check group but
                # *no* ruleset for discovered checks. One example is "ps".
                # That can be configured as a manual check or created by
                # inventory. But in the later case all parameters are set
                # by the inventory. This will be changed in a later version,
                # but we need to address it anyway.
                grouprule = "checkgroup_parameters:" + checkgroup
                if grouprule not in rulespec_registry:
                    try:
                        rulespec = rulespec_registry["static_checks:" +
                                                     checkgroup]
                    except KeyError:
                        rulespec = None

                    if rulespec:
                        url = watolib.folder_preserving_link([
                            ('mode', 'edit_ruleset'),
                            ('varname', "static_checks:" + checkgroup),
                            ('host', self._hostname)
                        ])
                        self._render_rule_reason(
                            _("Parameters"), url, _("Determined by discovery"),
                            None, False,
                            rulespec.valuespec._elements[2].value_to_text(
                                serviceinfo["parameters"]))
                    else:
                        self._render_rule_reason(
                            _("Parameters"), None, "", "", True,
                            _("This check is not configurable via WATO"))

                else:
                    rulespec = rulespec_registry[grouprule]
                    self._output_analysed_ruleset(
                        all_rulesets,
                        rulespec,
                        svc_desc_or_item=serviceinfo["item"],
                        svc_desc=self._service,
                        known_settings=serviceinfo["parameters"])

        elif origin == "static":
            checkgroup = serviceinfo["checkgroup"]
            checktype = serviceinfo["checktype"]
            if not checkgroup:
                html.write_text(_("This check is not configurable via WATO"))
            else:
                rulespec = rulespec_registry["static_checks:" + checkgroup]
                itemspec = rulespec.item_spec
                if itemspec:
                    item_text = itemspec.value_to_text(serviceinfo["item"])
                    title = rulespec.item_spec.title()
                else:
                    item_text = serviceinfo["item"]
                    title = _("Item")
                self._render_rule_reason(title, None, "", "", False, item_text)
                self._output_analysed_ruleset(
                    all_rulesets,
                    rulespec,
                    svc_desc_or_item=serviceinfo["item"],
                    svc_desc=self._service,
                    known_settings=self._PARAMETERS_OMIT)
                html.write(rulespec.valuespec._elements[2].value_to_text(
                    serviceinfo["parameters"]))
                html.close_td()
                html.close_tr()
                html.close_table()

        elif origin == "active":
            checktype = serviceinfo["checktype"]
            rulespec = rulespec_registry["active_checks:" + checktype]
            self._output_analysed_ruleset(
                all_rulesets,
                rulespec,
                svc_desc_or_item=None,
                svc_desc=None,
                known_settings=serviceinfo["parameters"])

        elif origin == "classic":
            ruleset = all_rulesets.get("custom_checks")
            origin_rule_result = self._get_custom_check_origin_rule(
                ruleset, self._hostname, self._service)
            if origin_rule_result is None:
                raise MKUserError(
                    None,
                    _("Failed to determine origin rule of %s / %s") %
                    (self._hostname, self._service))
            rule_folder, rule_index, _rule = origin_rule_result

            url = watolib.folder_preserving_link([('mode', 'edit_ruleset'),
                                                  ('varname', "custom_checks"),
                                                  ('host', self._hostname)])
            forms.section(html.render_a(_("Command Line"), href=url))
            url = watolib.folder_preserving_link([('mode', 'edit_rule'),
                                                  ('varname', "custom_checks"),
                                                  ('rule_folder',
                                                   rule_folder.path()),
                                                  ('rulenr', rule_index),
                                                  ('host', self._hostname)])

            html.open_table(class_="setting")
            html.open_tr()

            html.open_td(class_="reason")
            html.a("%s %d %s %s" %
                   (_("Rule"), rule_index + 1, _("in"), rule_folder.title()),
                   href=url)
            html.close_td()
            html.open_td(class_=["settingvalue", "used"])
            if "command_line" in serviceinfo:
                html.tt(serviceinfo["command_line"])
            else:
                html.write_text(_("(no command line, passive check)"))
            html.close_td()

            html.close_tr()
            html.close_table()

        self._show_labels(serviceinfo.get("labels", {}), "service",
                          serviceinfo.get("label_sources", {}))
Example #27
0
    def page(self):
        search = get_search_expression()

        html.begin_form("role", method="POST")

        # ID
        forms.header(_("Basic properties"), css="wide")
        forms.section(_("Internal ID"),
                      simple="builtin" in self._role,
                      is_required=True)
        if self._role.get("builtin"):
            html.write_text("%s (%s)" % (self._role_id, _("builtin role")))
            html.hidden_field("id", self._role_id)
        else:
            html.text_input("id", self._role_id)
            html.set_focus("id")

        # Alias
        forms.section(_("Alias"))
        html.help(_("An alias or description of the role"))
        html.text_input("alias", self._role.get("alias", ""), size=50)

        # Based on
        if not self._role.get("builtin"):
            forms.section(_("Based on role"))
            html.help(
                _("Each user defined role is based on one of the builtin roles. "
                  "When created it will start with all permissions of that role. When due to a software "
                  "update or installation of an addons new permissions appear, the user role will get or "
                  "not get those new permissions based on the default settings of the builtin role it's "
                  "based on."))
            role_choices: Choices = [(i, r["alias"])
                                     for i, r in self._roles.items()
                                     if r.get("builtin")]
            html.dropdown("basedon",
                          role_choices,
                          deflt=self._role.get("basedon", "user"),
                          ordered=True)

        forms.end()

        html.h2(_("Permissions"))

        # Permissions
        base_role_id = self._role.get("basedon", self._role_id)

        html.help(
            _("When you leave the permissions at &quot;default&quot; then they get their "
              "settings from the factory defaults (for builtin roles) or from the "
              "factory default of their base role (for user define roles). Factory defaults "
              "may change due to software updates. When choosing another base role, all "
              "permissions that are on default will reflect the new base role."
              ))

        for section in permission_section_registry.get_sorted_sections():
            # Now filter by the optional search term
            filtered_perms = []
            for perm in permission_registry.get_sorted_permissions(section):
                if search and (search not in perm.title.lower()
                               and search not in perm.name.lower()):
                    continue

                filtered_perms.append(perm)

            if not filtered_perms:
                continue

            forms.header(section.title, isopen=search is not None, css="wide")
            for perm in filtered_perms:
                forms.section(perm.title)

                pvalue = self._role["permissions"].get(perm.name)
                def_value = base_role_id in perm.defaults

                choices: Choices = [
                    ("yes", _("yes")),
                    ("no", _("no")),
                    ("default",
                     _("default (%s)") % (def_value and _("yes") or _("no"))),
                ]
                deflt = {True: "yes", False: "no"}.get(pvalue, "default")

                html.dropdown("perm_" + perm.name,
                              choices,
                              deflt=deflt,
                              style="width: 130px;")
                html.help(perm.description)

        forms.end()
        html.hidden_fields()
        html.end_form()
Example #28
0
    def page(self):
        # TODO: remove subclass specific things specifict things (everything with _type == 'user')
        html.begin_form("attr")
        forms.header(_("Properties"))
        forms.section(_("Name"), simple=not self._new, is_required=True)
        html.help(
            _("The name of the attribute is used as an internal key. It cannot be "
              "changed later."))
        if self._new:
            html.text_input("name", self._attr.get('name', ''))
            html.set_focus("name")
        else:
            html.write_text(self._name)
            html.set_focus("title")

        forms.section(_("Title") + "<sup>*</sup>", is_required=True)
        html.help(_("The title is used to label this attribute."))
        html.text_input("title", self._attr.get('title', ''))

        forms.section(_('Topic'))
        html.help(
            _('The attribute is added to this section in the edit dialog.'))
        html.dropdown('topic',
                      self._topics,
                      deflt=self._attr.get('topic', self._default_topic))

        forms.section(_('Help Text') + "<sup>*</sup>")
        html.help(
            _('You might want to add some helpful description for the attribute.'
              ))
        html.text_area('help', self._attr.get('help', ''))

        forms.section(_('Data type'))
        html.help(_('The type of information to be stored in this attribute.'))
        if self._new:
            html.dropdown('type',
                          custom_attr_types(),
                          deflt=self._attr.get('type', ''))
        else:
            html.write(dict(custom_attr_types())[self._attr.get('type')])

        self._add_extra_form_sections()
        self._show_in_table_option()

        forms.section(_('Add to monitoring configuration'))
        html.help(self._macro_help)
        html.checkbox('add_custom_macro',
                      self._attr.get('add_custom_macro', False),
                      label=self._macro_label)

        forms.end()
        html.show_localization_hint()
        html.hidden_fields()
        html.end_form()
Example #29
0
    def _show_configuration_variables(self, groups):
        search = self._search

        at_least_one_painted = False
        html.open_div(class_="globalvars")
        for group in sorted(groups, key=lambda g: g.sort_index()):
            header_is_painted = False  # needed for omitting empty groups

            for config_variable_class in group.config_variables():
                config_variable = config_variable_class()
                varname = config_variable.ident()
                valuespec = config_variable.valuespec()

                if not config_variable.domain().enabled():
                    continue

                if config_variable.domain(
                ) == watolib.ConfigDomainCore and varname not in self._default_values:
                    if config.debug:
                        raise MKGeneralException(
                            "The configuration variable <tt>%s</tt> is unknown to "
                            "your local Check_MK installation" % varname)
                    continue

                if not config_variable.in_global_settings():
                    continue

                if self._show_only_modified and varname not in self._current_settings:
                    continue

                help_text = valuespec.help() or ''
                title_text = valuespec.title()

                if search and search not in group.title().lower() \
                        and search not in config_variable.domain().ident.lower() \
                          and search not in varname \
                          and search not in help_text.lower() \
                          and search not in title_text.lower():
                    continue  # skip variable when search is performed and nothing matches
                at_least_one_painted = True

                if not header_is_painted:
                    # always open headers when searching
                    forms.header(group.title(), isopen=search or self._show_only_modified)
                    header_is_painted = True

                default_value = self._default_values[varname]

                edit_url = watolib.folder_preserving_link([("mode", self._edit_mode()),
                                                           ("varname", varname),
                                                           ("site", html.request.var("site", ""))])
                title = html.render_a(
                    title_text,
                    href=edit_url,
                    class_="modified" if varname in self._current_settings else None,
                    title=escaping.strip_tags(help_text))

                if varname in self._current_settings:
                    value = self._current_settings[varname]
                elif varname in self._global_settings:
                    value = self._global_settings[varname]
                else:
                    value = default_value

                try:
                    to_text = valuespec.value_to_text(value)
                except Exception:
                    logger.exception("error converting %r to text", value)
                    to_text = html.render_error(_("Failed to render value: %r") % value)

                # Is this a simple (single) value or not? change styling in these cases...
                simple = True
                if '\n' in to_text or '<td>' in to_text:
                    simple = False
                forms.section(title, simple=simple)

                if varname in self._current_settings:
                    modified_cls: Optional[str] = "modified"
                    value_title: Optional[str] = _("This option has been modified.")
                elif varname in self._global_settings:
                    modified_cls = "modified globally"
                    value_title = _("This option has been modified in global settings.")
                else:
                    modified_cls = None
                    value_title = None

                if is_a_checkbox(valuespec):
                    html.open_div(class_=["toggle_switch_container", modified_cls])
                    html.toggle_switch(
                        enabled=value,
                        help_txt=_("Immediately toggle this setting"),
                        href=html.makeactionuri([("_action", "toggle"), ("_varname", varname)]),
                        class_=modified_cls,
                        title=value_title,
                    )
                    html.close_div()

                else:
                    html.a(HTML(to_text), href=edit_url, class_=modified_cls, title=value_title)

            if header_is_painted:
                forms.end()
        if not at_least_one_painted and search:
            html.show_message(_('Did not find any global setting matching your search.'))
        html.close_div()
Example #30
0
 def _show_global_setting(self):
     forms.section(_("Global setting"))
     html.write_html(HTML(self._valuespec.value_to_text(self._global_settings[self._varname])))