示例#1
0
文件: forms.py 项目: KNGP14/checkmk
def edit_valuespec(vs,
                   value,
                   buttontext=None,
                   method="GET",
                   varprefix="",
                   validate=None,
                   formname="form",
                   consume_transid=True,
                   focus=None):

    if html.request.var("filled_in") == formname and html.transaction_valid():
        if consume_transid:
            html.check_transaction()

        messages = []
        try:
            new_value = vs.from_html_vars(varprefix)
            vs.validate_value(new_value, varprefix)

        except MKUserError as e:
            messages.append("%s: %s" % (vs.title(), e.message))
            html.add_user_error(e.varname, e.message)

        if validate and not html.has_user_errors():
            try:
                validate(new_value)
            except MKUserError as e:
                messages.append(e.message)
                html.add_user_error(e.varname, e.message)

        if messages:
            html.show_error("".join(["%s<br>\n" % m for m in messages]))
        else:
            return new_value

    html.begin_form(formname, method=method)
    html.help(vs.help())
    vs.render_input(varprefix, value)
    if buttontext is None:
        buttontext = _("Save")
    html.button("save", buttontext)
    # Should be ignored be hidden_fields, but I do not dare to change it there
    html.request.del_var("filled_in")
    html.hidden_fields()
    if focus:
        html.set_focus(focus)
    else:
        vs.set_focus(varprefix)
    html.end_form()
示例#2
0
def handle_report_form(tardata, what):
    details = {}
    try:
        vs = vs_crash_report()
        details = vs.from_html_vars("_report")
        vs.validate_value(details, "_report")

        # Make the resulting page execute the crash report post request
        url_encoded_params = html.urlencode_vars(details.items() + [
            ("crashdump", base64.b64encode(tardata)),
        ])
        html.open_div(id_="pending_msg", style="display:none")
        html.message(_("Submitting crash report..."))
        html.close_div()
        html.open_div(id_="success_msg", style="display:none")
        html.message(
            _("Your crash report has been submitted (ID: ###ID###). Thanks for your participation, "
              "it is very important for the quality of Check_MK.<br><br>"
              "Please note:"
              "<ul>"
              "<li>In general we do <i>not</i> respond to crash reports, "
              "except we need further information from you.</li>"
              "<li>We read every feedback thoroughly, but this might happen "
              "not before a couple of weeks or even months have passed and is "
              "often aligned with our release cycle.</li>"
              "<li>If you are in need of a quick solution for your problem, then "
              "we can help you within the scope of professional support. If you "
              "already have a support contract, then please use your personal "
              "support email address to send us a mail refering to your crash "
              "report.<br>If you are interested in the details about support, "
              "you find details on <a href=\"https://checkmk.com/"
              "checkmk_support_contract.html\" target=_blank>our website</a>."))
        html.close_div()
        html.open_div(id_="fail_msg", style="display:none")
        report_url = html.makeuri([
            ("subject", "Check_MK Crash Report - " + get_version(what)),
        ],
                                  filename="mailto:" + get_crash_report_target(what))
        html.show_error(
            _("Failed to send the crash report. Please download it manually and send it "
              "to <a href=\"%s\">%s</a>") % (report_url, get_crash_report_target(what)))
        html.close_div()
        html.javascript("cmk.crash_reporting.submit('https://checkmk.com/crash_report.php', " \
                                            "'%s');" % url_encoded_params)
    except MKUserError as e:
        action_message = "%s" % e
        html.add_user_error(e.varname, action_message)

    return details
示例#3
0
    def page(self) -> None:
        watolib.init_wato_datastructures(with_wato_lock=True)

        profile_changed = False
        if html.request.has_var('_save') and html.check_transaction():
            try:
                profile_changed = self._action()
            except MKUserError as e:
                html.add_user_error(e.varname, e)

        # Now, if in distributed environment where users can login to remote sites, set the trigger for
        # pushing the new user profile to the remote sites asynchronously
        if profile_changed and config.user.authorized_login_sites():
            user_profile_async_replication_page()
            return

        self._show_form(profile_changed)
示例#4
0
    def page(self) -> None:
        watolib.init_wato_datastructures(with_wato_lock=True)

        title = self._page_title()
        breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_user(), title)
        html.header(title, breadcrumb, self._page_menu(breadcrumb))

        if html.request.has_var('_save') and html.check_transaction():
            try:
                self._action()
            except MKUserError as e:
                html.add_user_error(e.varname, e)

        for message in get_flashed_messages():
            html.show_message(message)

        if html.has_user_errors():
            html.show_user_errors()

        self._show_form()
示例#5
0
    def action(self):
        # type: () -> ActionResult
        if not html.check_transaction():
            return None

        if html.request.var('_try'):
            try:
                self._validate_diag_html_vars()
            except MKUserError as e:
                html.add_user_error(e.varname, e)
            return None

        if html.request.var('_save'):
            # Save the ipaddress and/or community
            vs_host = self._vs_host()
            new = vs_host.from_html_vars('vs_host')
            vs_host.validate_value(new, 'vs_host')

            # If both snmp types have credentials set - snmpv3 takes precedence
            return_message = []
            if "ipaddress" in new:
                return_message.append(_("IP address"))
            if "snmp_v3_credentials" in new:
                if "snmp_community" in new:
                    return_message.append(
                        _("SNMPv3 credentials (SNMPv2 community was discarded)"
                          ))
                else:
                    return_message.append(_("SNMPv3 credentials"))
                new["snmp_community"] = new["snmp_v3_credentials"]
            elif "snmp_community" in new:
                return_message.append(_("SNMP credentials"))

            msg = _("Updated attributes: ") + ", ".join(return_message)

            self._host.update_attributes(new)
            html.request.del_vars()
            html.request.set_var("host", self._hostname)
            html.request.set_var("folder", watolib.Folder.current().path())
            return "edit_host", msg
        return None
示例#6
0
    def _get_time_range_of(self, what):
        varprefix = self.ident + "_" + what

        rangename = html.request.var(varprefix + "_range")
        if rangename == "abs":
            try:
                return time.mktime(time.strptime(html.request.var(varprefix), "%Y-%m-%d"))
            except Exception:
                html.add_user_error(varprefix, _("Please enter the date in the format YYYY-MM-DD."))
                return None

        elif rangename == "unix":
            return html.request.get_integer_input_mandatory(varprefix)

        try:
            count = html.request.get_integer_input_mandatory(varprefix)
            secs = count * int(rangename)
            return int(time.time()) - secs
        except Exception:
            html.request.set_var(varprefix, "")
            return None
示例#7
0
文件: forms.py 项目: majma24/checkmk
def edit_dictionaries(dictionaries: 'Sequence[Tuple[str, Union[Transform, Dictionary]]]',
                      value: Dict[str, Any],
                      focus: Optional[str] = None,
                      hover_help: bool = True,
                      validate: Optional[Callable[[Any], None]] = None,
                      title: Optional[str] = None,
                      method: str = "GET",
                      preview: bool = False,
                      varprefix: str = "",
                      formname: str = "form",
                      consume_transid: bool = True):

    if html.request.get_ascii_input("filled_in") == formname and html.transaction_valid():
        if not preview and consume_transid:
            html.check_transaction()

        messages: List[str] = []
        new_value: Dict[str, Dict[str, Any]] = {}
        for keyname, vs_dict in dictionaries:
            dict_varprefix = varprefix + keyname
            new_value[keyname] = {}
            try:
                edited_value = vs_dict.from_html_vars(dict_varprefix)
                vs_dict.validate_value(edited_value, dict_varprefix)
                new_value[keyname].update(edited_value)
            except MKUserError as e:
                messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e))
                html.add_user_error(e.varname, e)
            except Exception as e:
                messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e))
                html.add_user_error(None, e)

            if validate and not html.has_user_errors():
                try:
                    validate(new_value[keyname])
                except MKUserError as e:
                    messages.append("%s" % e)
                    html.add_user_error(e.varname, e)

        if messages:
            messages_joined = "".join(["%s<br>\n" % m for m in messages])
            if not preview:
                html.show_error(messages_joined)
            else:
                raise MKUserError(None, messages_joined)
        else:
            return new_value

    html.begin_form(formname, method=method)
    for keyname, vs_dict in dictionaries:
        dict_varprefix = varprefix + keyname
        subvalue = value.get(keyname, {})
        vs_dict.render_input_as_form(dict_varprefix, subvalue)

    end()
    # Should be ignored be hidden_fields, but I do not dare to change it there
    html.request.del_var("filled_in")
    html.hidden_fields()
    html.end_form()
示例#8
0
    def render(
        self,
        rows: Rows,
        show_checkboxes: bool,
        num_columns: int,
        show_filters: List[Filter],
        unfiltered_amount_of_rows: int,
    ) -> None:
        view_spec = self.view.spec
        home = ("mobile.py", "Home", "home")

        page = html.request.var("page")
        if not page:
            if view_spec.get("mustsearch"):
                page = "filter"
            else:
                page = "data"

        title = views.view_title(self.view.spec, self.view.context)
        navbar = [("data", _("Results"), "grid", 'results_button'),
                  ("filter", _("Filter"), "search", '')]
        if config.user.may("general.act"):
            navbar.append(("commands", _("Commands"), "gear", ''))

        # Should we show a page with context links?
        context_links = list(
            views.collect_context_links(self.view,
                                        rows,
                                        mobile=True,
                                        only_types=['views']))

        if context_links:
            navbar.append(("context", _("Context"), "arrow-r", ''))
        page_id = "view_" + view_spec["name"]

        if page == "filter":
            jqm_page_header(_("Filter / Search"),
                            left_button=home,
                            id_="filter")
            _show_filter_form(show_filters)
            jqm_page_navfooter(navbar, 'filter', page_id)

        elif page == "commands":
            # Page: Commands
            if config.user.may("general.act"):
                jqm_page_header(_("Commands"),
                                left_button=home,
                                id_="commands")
                show_commands = True
                if html.request.has_var("_do_actions"):
                    try:
                        show_commands = do_commands(
                            self.view.datasource.infos[0], rows)
                    except MKUserError as e:
                        html.show_error("%s" % e)
                        html.add_user_error(e.varname, e)
                        show_commands = True
                if show_commands:
                    _show_command_form(self.view.datasource, rows)
                jqm_page_navfooter(navbar, 'commands', page_id)

        elif page == "data":
            # Page: data rows of view
            jqm_page_header(
                title,
                left_button=home,
                right_button=("javascript:document.location.reload();",
                              _("Reload"), "refresh"),
                id_="data")
            html.open_div(id_="view_results")
            if len(rows) == 0:
                html.write(_("No hosts/services found."))
            else:
                try:
                    if cmk.gui.view_utils.row_limit_exceeded(
                            unfiltered_amount_of_rows, self.view.row_limit):
                        cmk.gui.view_utils.query_limit_exceeded_warn(
                            self.view.row_limit, config.user)
                        del rows[self.view.row_limit:]
                    self.view.layout.render(
                        rows,
                        view_spec,
                        self.view.group_cells,
                        self.view.row_cells,
                        num_columns,
                        show_checkboxes and not html.do_actions(),
                    )
                except Exception as e:
                    logger.exception("error rendering mobile view")
                    html.write(_("Error showing view: %s") % e)
            html.close_div()
            jqm_page_navfooter(navbar, 'data', page_id)

        # Page: Context buttons
        elif page == "context":
            jqm_page_header(_("Context"), left_button=home, id_="context")
            _show_context_links(context_links)
            jqm_page_navfooter(navbar, 'context', page_id)
示例#9
0
文件: login.py 项目: selten/checkmk
    def _do_login(self) -> None:
        """handle the sent login form"""
        if not html.request.var('_login'):
            return

        try:
            username_var = html.request.get_unicode_input('_username', '')
            assert username_var is not None
            username = UserId(username_var.rstrip())
            if not username:
                raise MKUserError('_username', _('No username given.'))

            password = html.request.var('_password', '')
            if not password:
                raise MKUserError('_password', _('No password given.'))

            default_origtarget = config.url_prefix() + "check_mk/"
            origtarget = html.get_url_input("_origtarget", default_origtarget)

            # Disallow redirections to:
            #  - logout.py: Happens after login
            #  - side.py: Happens when invalid login is detected during sidebar refresh
            if "logout.py" in origtarget or 'side.py' in origtarget:
                origtarget = default_origtarget

            # '<user_id>' -> success
            # False       -> failed
            result = userdb.hook_login(username, password)
            if result:
                assert isinstance(result, str)
                # use the username provided by the successful login function, this function
                # might have transformed the username provided by the user. e.g. switched
                # from mixed case to lower case.
                username = result

                # When single user session mode is enabled, check that there is not another
                # active session
                userdb.ensure_user_can_init_session(username)

                # reset failed login counts
                userdb.on_succeeded_login(username)

                # The login succeeded! Now:
                # a) Set the auth cookie
                # b) Unset the login vars in further processing
                # c) Redirect to really requested page
                _create_auth_session(username)

                # Never use inplace redirect handling anymore as used in the past. This results
                # in some unexpected situations. We simpy use 302 redirects now. So we have a
                # clear situation.
                # userdb.need_to_change_pw returns either False or the reason description why the
                # password needs to be changed
                change_pw_result = userdb.need_to_change_pw(username)
                if change_pw_result:
                    raise HTTPRedirect(
                        'user_change_pw.py?_origtarget=%s&reason=%s' %
                        (html.urlencode(origtarget), change_pw_result))
                raise HTTPRedirect(origtarget)

            userdb.on_failed_login(username)
            raise MKUserError(None, _('Invalid credentials.'))
        except MKUserError as e:
            html.add_user_error(e.varname, e)
示例#10
0
def edit_dictionaries(
        dictionaries,  # type: List[Tuple[str, Union[Transform, Dictionary]]]
        value,  # type: Dict[str, Any]
        focus=None,  # type: Optional[str]
        hover_help=True,  # type: bool
        validate=None,  # type: Optional[Callable[[Any], None]]
        buttontext=None,  # type: Optional[Text]
        title=None,  # type: Optional[Text]
        buttons=None,  # type: List[Tuple[str, Text, str]]
        method="GET",  # type: str
        preview=False,  # type: bool
        varprefix="",  # type: str
        formname="form",  # type: str
        consume_transid=True  # type: bool
):

    if html.request.get_ascii_input(
            "filled_in") == formname and html.transaction_valid():
        if not preview and consume_transid:
            html.check_transaction()

        messages = []  # type: List[Text]
        new_value = {}  # type: Dict[str, Dict[str, Any]]
        for keyname, vs_dict in dictionaries:
            dict_varprefix = varprefix + keyname
            new_value[keyname] = {}
            try:
                edited_value = vs_dict.from_html_vars(dict_varprefix)
                vs_dict.validate_value(edited_value, dict_varprefix)
                new_value[keyname].update(edited_value)
            except MKUserError as e:
                messages.append("%s: %s" %
                                (vs_dict.title() or _("Properties"), e))
                html.add_user_error(e.varname, e)
            except Exception as e:
                messages.append("%s: %s" %
                                (vs_dict.title() or _("Properties"), e))
                html.add_user_error(None, e)

            if validate and not html.has_user_errors():
                try:
                    validate(new_value[keyname])
                except MKUserError as e:
                    messages.append("%s" % e)
                    html.add_user_error(e.varname, e)

        if messages:
            messages_joined = "".join(["%s<br>\n" % m for m in messages])
            if not preview:
                html.show_error(messages_joined)
            else:
                raise MKUserError(None, messages_joined)
        else:
            return new_value

    html.begin_form(formname, method=method)
    for keyname, vs_dict in dictionaries:
        dict_varprefix = varprefix + keyname
        subvalue = value.get(keyname, {})
        vs_dict.render_input_as_form(dict_varprefix, subvalue)

    end()
    if buttons:
        for name, button_title, _icon in buttons:
            html.button(name, button_title)
    else:
        if buttontext is None:
            buttontext = _("Save")
        html.button("save", buttontext)
    # Should be ignored be hidden_fields, but I do not dare to change it there
    html.request.del_var("filled_in")
    html.hidden_fields()
    html.end_form()
示例#11
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()
示例#12
0
文件: forms.py 项目: KNGP14/checkmk
def edit_dictionaries(dictionaries,
                      value,
                      focus=None,
                      hover_help=True,
                      validate=None,
                      buttontext=None,
                      title=None,
                      buttons=None,
                      method="GET",
                      preview=False,
                      varprefix="",
                      formname="form",
                      consume_transid=True):

    # Convert list of entries/dictionaries
    sections = []
    for keyname, d in dictionaries:
        if isinstance(d, list):
            sections.append((keyname, title or _("Properties"), d))
        else:
            sections.append((keyname, None,
                             d))  # valuespec Dictionary, title used from dict

    if html.request.var("filled_in") == formname and html.transaction_valid():
        if not preview and consume_transid:
            html.check_transaction()

        messages = []
        new_value = {}
        for keyname, _section_title, entries in sections:
            if isinstance(entries, list):
                new_value[keyname] = value.get(keyname, {}).copy()
                for name, vs in entries:
                    if len(sections) == 1:
                        vp = varprefix
                    else:
                        vp = keyname + "_" + varprefix
                    try:
                        v = vs.from_html_vars(vp + name)
                        vs.validate_value(v, vp + name)
                        new_value[keyname][name] = v
                    except MKUserError as e:
                        messages.append("%s: %s" % (vs.title(), e))
                        html.add_user_error(e.varname, e)

            else:
                new_value[keyname] = {}
                try:
                    edited_value = entries.from_html_vars(keyname)
                    entries.validate_value(edited_value, keyname)
                    new_value[keyname].update(edited_value)
                except MKUserError as e:
                    messages.append("%s: %s" %
                                    (entries.title() or _("Properties"), e))
                    html.add_user_error(e.varname, e)
                except Exception as e:
                    messages.append("%s: %s" %
                                    (entries.title() or _("Properties"), e))
                    html.add_user_error(None, e)

            if validate and not html.has_user_errors():
                try:
                    validate(new_value[keyname])
                except MKUserError as e:
                    messages.append(e)
                    html.add_user_error(e.varname, e)

        if messages:
            messages_joined = "".join(["%s<br>\n" % m for m in messages])
            if not preview:
                html.show_error(messages_joined)
            else:
                raise MKUserError(None, messages_joined)
        else:
            return new_value

    html.begin_form(formname, method=method)
    for keyname, title1, entries in sections:
        subvalue = value.get(keyname, {})
        if isinstance(entries, list):
            header(title1)
            first = True
            for name, vs in entries:
                section(vs.title())
                html.help(vs.help())
                if name in subvalue:
                    v = subvalue[name]
                else:
                    v = vs.default_value()
                if len(sections) == 1:
                    vp = varprefix
                else:
                    vp = keyname + "_" + varprefix
                vs.render_input(vp + name, v)
                if (not focus and first) or (name == focus):
                    vs.set_focus(vp + name)
                    first = False
        else:
            entries.render_input_as_form(keyname, subvalue)

    end()
    if buttons:
        for name, button_title, _icon in buttons:
            html.button(name, button_title)
    else:
        if buttontext is None:
            buttontext = _("Save")
        html.button("save", buttontext)
    # Should be ignored be hidden_fields, but I do not dare to change it there
    html.request.del_var("filled_in")
    html.hidden_fields()
    html.end_form()
示例#13
0
def _wato_page_handler(current_mode: str,
                       mode_permissions: Optional[List[PermissionName]],
                       mode_class: Type[WatoMode]) -> None:
    try:
        init_wato_datastructures(with_wato_lock=not html.is_transaction())
    except Exception:
        # Snapshot must work in any case
        if current_mode == 'snapshot':
            pass
        else:
            raise

    # Check general permission for this mode
    if mode_permissions is not None and not config.user.may("wato.seeall"):
        _ensure_mode_permissions(mode_permissions)

    mode = mode_class()

    # Do actions (might switch mode)
    if html.is_transaction():
        try:
            config.user.need_permission("wato.edit")

            # Even if the user has seen this mode because auf "seeall",
            # he needs an explicit access permission for doing changes:
            if config.user.may("wato.seeall"):
                if mode_permissions:
                    _ensure_mode_permissions(mode_permissions)

            if cmk.gui.watolib.read_only.is_enabled(
            ) and not cmk.gui.watolib.read_only.may_override():
                raise MKUserError(None, cmk.gui.watolib.read_only.message())

            result = mode.action()
            if isinstance(result, (tuple, str, bool)):
                raise MKGeneralException(
                    f"WatoMode \"{current_mode}\" returns unsupported return value: {result!r}"
                )

            # We assume something has been modified and increase the config generation ID by one.
            update_config_generation()

            if config.wato_use_git:
                do_git_commit()

            # Handle two cases:
            # a) Don't render the page content after action
            #    (a confirm dialog is displayed by the action, or a non-HTML content was sent)
            # b) Redirect to another page
            if isinstance(result, FinalizeRequest):
                raise result

        except MKUserError as e:
            html.add_user_error(e.varname, str(e))

        except MKAuthException as e:
            reason = e.args[0]
            html.add_user_error(None, reason)

    breadcrumb = make_main_menu_breadcrumb(
        mode.main_menu()) + mode.breadcrumb()
    page_menu = mode.page_menu(breadcrumb)
    wato_html_head(title=mode.title(),
                   breadcrumb=breadcrumb,
                   page_menu=page_menu,
                   show_body_start=display_options.enabled(display_options.H),
                   show_top_heading=display_options.enabled(display_options.T))

    if not html.is_transaction() or (cmk.gui.watolib.read_only.is_enabled() and
                                     cmk.gui.watolib.read_only.may_override()):
        _show_read_only_warning()

    # Show outcome of failed action on this page
    if html.has_user_errors():
        html.show_user_errors()

    # Show outcome of previous page (that redirected to this one)
    for message in get_flashed_messages():
        html.show_message(message)

    # Show content
    mode.handle_page()

    if is_sidebar_reload_needed():
        html.reload_whole_page()

    wato_html_footer(show_body_end=display_options.enabled(display_options.H))
示例#14
0
def _wato_page_handler(current_mode: str,
                       mode_permissions: List[PermissionName],
                       mode_class: Type[WatoMode]) -> None:
    try:
        init_wato_datastructures(with_wato_lock=not html.is_transaction())
    except Exception:
        # Snapshot must work in any case
        if current_mode == 'snapshot':
            pass
        else:
            raise

    # Check general permission for this mode
    if mode_permissions is not None and not config.user.may("wato.seeall"):
        _ensure_mode_permissions(mode_permissions)

    mode = mode_class()

    # Do actions (might switch mode)
    action_message: Optional[str] = None
    if html.is_transaction():
        try:
            config.user.need_permission("wato.edit")

            # Even if the user has seen this mode because auf "seeall",
            # he needs an explicit access permission for doing changes:
            if config.user.may("wato.seeall"):
                if mode_permissions:
                    _ensure_mode_permissions(mode_permissions)

            if cmk.gui.watolib.read_only.is_enabled(
            ) and not cmk.gui.watolib.read_only.may_override():
                raise MKUserError(None, cmk.gui.watolib.read_only.message())

            result = mode.action()
            if isinstance(result, tuple):
                newmode, action_message = result
            else:
                newmode = result

            # We assume something has been modified and increase the config generation ID by one.
            update_config_generation()

            # If newmode is False, then we shall immediately abort.
            # This is e.g. the case, if the page outputted non-HTML
            # data, such as a tarball (in the export function). We must
            # be sure not to output *any* further data in that case.
            if newmode is False:
                return

            # if newmode is not None, then the mode has been changed
            if newmode is not None:
                assert not isinstance(newmode, bool)
                if newmode == "":  # no further information: configuration dialog, etc.
                    if action_message:
                        html.show_message(action_message)
                        wato_html_footer()
                    return
                mode_permissions, mode_class = _get_mode_permission_and_class(
                    newmode)
                current_mode = newmode
                mode = mode_class()
                html.request.set_var("mode",
                                     newmode)  # will be used by makeuri

                # Check general permissions for the new mode
                if mode_permissions is not None and not config.user.may(
                        "wato.seeall"):
                    for pname in mode_permissions:
                        if '.' not in pname:
                            pname = "wato." + pname
                        config.user.need_permission(pname)

        except MKUserError as e:
            action_message = "%s" % e
            html.add_user_error(e.varname, action_message)

        except MKAuthException as e:
            reason = e.args[0]
            action_message = reason
            html.add_user_error(None, reason)

    breadcrumb = make_main_menu_breadcrumb(
        mode.main_menu()) + mode.breadcrumb()
    page_menu = mode.page_menu(breadcrumb)
    wato_html_head(title=mode.title(),
                   breadcrumb=breadcrumb,
                   page_menu=page_menu,
                   show_body_start=display_options.enabled(display_options.H),
                   show_top_heading=display_options.enabled(display_options.T))

    if not html.is_transaction() or (cmk.gui.watolib.read_only.is_enabled() and
                                     cmk.gui.watolib.read_only.may_override()):
        _show_read_only_warning()

    # Show outcome of action
    if html.has_user_errors():
        html.show_user_errors()
    elif action_message:
        html.show_message(action_message)

    # Show content
    mode.handle_page()

    if is_sidebar_reload_needed():
        html.reload_sidebar()

    if config.wato_use_git and html.is_transaction():
        do_git_commit()

    wato_html_footer(show_footer=display_options.enabled(display_options.Z),
                     show_body_end=display_options.enabled(display_options.H))