Пример #1
0
def inpage_search_form(mode: Optional[str] = None, default_value: str = "") -> None:
    form_name = "inpage_search_form"
    reset_button_id = "%s_reset" % form_name
    was_submitted = request.get_ascii_input("filled_in") == form_name
    html.begin_form(form_name, add_transid=False)
    html.text_input(
        "search",
        size=32,
        default_value=default_value,
        placeholder=_("Filter"),
        required=True,
        title="",
    )
    html.hidden_fields()
    if mode:
        html.hidden_field("mode", mode, add_var=True)
    reset_url = request.get_ascii_input_mandatory("reset_url", requested_file_with_query(request))
    html.hidden_field("reset_url", reset_url, add_var=True)
    html.button("submit", "", cssclass="submit", help_=_("Apply"))
    html.buttonlink(reset_url, "", obj_id=reset_button_id, title=_("Reset"))
    html.end_form()
    html.javascript(
        "cmk.page_menu.inpage_search_init(%s, %s)"
        % (json.dumps(reset_button_id), json.dumps(was_submitted))
    )
Пример #2
0
 def _show_item_title(self, item: TopicMenuItem) -> None:
     item_title: Union[HTML, str] = item.title
     if not item.button_title:
         html.write_text(item_title)
         return
     html.span(item.title)
     html.button(item.name, item.button_title)
Пример #3
0
    def _show_audit_log_options_controls(self):
        html.open_div(class_="side_popup_controls")

        html.open_div(class_="update_buttons")
        html.button("apply", _("Apply"), "submit")
        html.buttonlink(makeuri(request, [], remove_prefix="options_"), _("Reset"))
        html.close_div()

        html.close_div()
Пример #4
0
    def _show_report_form(self, crash_info: CrashInfo,
                          details: ReportSubmitDetails) -> None:
        if crash_info["crash_type"] == "gui":
            self._add_gui_user_infos_to_details(details)

        html.begin_form("report", method="GET")
        html.show_user_errors()
        vs = self._vs_crash_report()
        vs.render_input("_report", details)
        vs.set_focus("report")
        forms.end()
        html.button("_report", _("Submit Report"))
        html.hidden_fields()
        html.end_form()
Пример #5
0
def search_form(
    title: Optional[str] = None, mode: Optional[str] = None, default_value: str = ""
) -> None:
    html.begin_form("search", add_transid=False)
    if title:
        html.write_text(title + " ")
    html.text_input("search", size=32, default_value=default_value)
    html.hidden_fields()
    if mode:
        html.hidden_field("mode", mode, add_var=True)
    html.set_focus("search")
    html.write_text(" ")
    html.button("_do_seach", _("Search"))
    html.end_form()
Пример #6
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()
Пример #7
0
def confirm_with_preview(msg: Union[str, HTML],
                         confirm_options: List[Tuple[str, str]],
                         method: str = "POST") -> Optional[bool]:
    """Show a confirm dialog to the user

    BE AWARE: In case you just want to have some action confirmed by the user, you
    should use the javascript powere confirm dialg (make_confirm, add_confirm_on_submit, ...).

    This method is used only in places where we explicitly need to show important information to the
    user before he can decide whether or not to confirm the action.

    The confirm dialog is normally not a dialog which need to be protected by a transid itselfs. It
    is only a intermediate step to the real action But there are use cases where the confirm dialog
    is used during rendering a normal page, for example when deleting a dashlet from a dashboard. In
    such cases, the transid must be added by the confirm dialog.
    """
    if request.var("_do_actions") == _("Cancel"):
        # User has pressed "Cancel", now invalidate the unused transid
        transactions.check_transaction()
        return None  # None --> "Cancel"

    if not any(
            request.has_var(varname) for _title, varname in confirm_options):
        mobile = is_mobile(request, response)
        if mobile:
            html.open_center()
        html.open_div(class_="really")
        html.write_text(msg)
        html.begin_form("confirm", method=method, add_transid=False)
        html.hidden_fields(add_action_vars=True)
        for title, varname in confirm_options:
            html.button(varname, title, "really")
        html.button("_do_actions", _("Cancel"))
        html.end_form()
        html.close_div()
        if mobile:
            html.close_center()

        return False  # False --> "Dialog shown, no answer yet"

    # Now check the transaction. True: "Yes", None --> Browser reload of "yes" page
    return True if transactions.check_transaction() else None
Пример #8
0
def page_login() -> None:
    title = _("Checkmk Mobile")
    mobile_html_head(title)
    jqm_page_header(title, id_="login")
    html.div(_("Welcome to Checkmk Mobile."), id_="loginhead")

    html.begin_form("login", method="POST", add_transid=False)
    # Keep information about original target URL
    default_origtarget = (
        "index.py" if requested_file_name(request) in ["login", "logout"] else makeuri(request, [])
    )
    origtarget = request.get_url_input("_origtarget", default_origtarget)
    html.hidden_field("_origtarget", escaping.escape_attribute(origtarget))

    html.text_input("_username", label=_("Username:"******"username", id_="input_user")
    html.password_input(
        "_password",
        size=None,
        label=_("Password:"******"current-password",
        id_="input_pass",
    )
    html.br()
    html.button("_login", _("Login"))
    html.set_focus("_username")
    html.end_form()
    html.open_div(id_="loginfoot")
    html.img("themes/facelift/images/logo_cmk_small.png", class_="logomk")
    html.div(
        HTML(_('&copy; <a target="_blank" href="https://checkmk.com">tribe29 GmbH</a>')),
        class_="copyright",
    )
    html.close_div()  # close content-div
    html.close_div()
    html.close_div()  # close page-div
    mobile_html_foot()
Пример #9
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()
Пример #10
0
def _rename_tags_after_confirmation(
        breadcrumb: Breadcrumb, operation: ABCOperation) -> Union[bool, str]:
    """Handle renaming and deletion of tags

    Find affected hosts, folders and rules. Remove or fix those rules according
    the users' wishes.

    Returns:
        True: Proceed, no "question" dialog shown
        False: "Question dialog" shown
        str: Action done after "question" dialog
    """
    repair_mode = request.var("_repair")
    if repair_mode is not None:
        try:
            mode = TagCleanupMode(repair_mode)
        except ValueError:
            raise MKUserError("_repair", "Invalid mode")

        if mode == TagCleanupMode.ABORT:
            raise MKUserError("id_0", _("Aborting change."))

        # make attribute unknown to system, important for save() operations
        if isinstance(operation, OperationRemoveTagGroup):
            undeclare_host_tag_attribute(operation.tag_group_id)

        affected_folders, affected_hosts, affected_rulesets = change_host_tags_in_folders(
            operation, mode, Folder.root_folder())

        return _(
            "Modified folders: %d, modified hosts: %d, modified rulesets: %d"
        ) % (
            len(affected_folders),
            len(affected_hosts),
            len(affected_rulesets),
        )

    message = HTML()
    affected_folders, affected_hosts, affected_rulesets = change_host_tags_in_folders(
        operation, TagCleanupMode.CHECK, Folder.root_folder())

    if affected_folders:
        with output_funnel.plugged():
            html.write_text(
                _("Affected folders with an explicit reference to this tag "
                  "group and that are affected by the change") + ":")
            _show_affected_folders(affected_folders)
            message += HTML(output_funnel.drain())

    if affected_hosts:
        with output_funnel.plugged():
            html.write_text(
                _("Hosts where this tag group is explicitely set "
                  "and that are effected by the change") + ":")
            _show_affected_hosts(affected_hosts)
            message += HTML(output_funnel.drain())

    if affected_rulesets:
        with output_funnel.plugged():
            html.write_text(
                _("Rulesets that contain rules with references to the changed tags"
                  ) + ":")
            _show_affected_rulesets(affected_rulesets)
            message += HTML(output_funnel.drain())

    if message:
        wato_html_head(title=operation.confirm_title(), breadcrumb=breadcrumb)
        html.open_div(class_="really")
        html.h3(_("Your modifications affect some objects"))
        html.write_text(message)
        html.br()
        html.write_text(
            _("Setup can repair things for you. It can rename tags in folders, host and rules. "
              "Removed tag groups will be removed from hosts and folders, removed tags will be "
              "replaced with the default value for the tag group (for hosts and folders). What "
              "rules concern, you have to decide how to proceed."))
        html.begin_form("confirm", method="POST")

        if affected_rulesets and _is_removing_tags(operation):
            html.br()
            html.b(
                _("Some tags that are used in rules have been removed by you. What "
                  "shall we do with that rules?"))
            html.open_ul()
            html.radiobutton(
                "_repair", "remove", True,
                _("Just remove the affected tags from the rules."))
            html.br()
            html.radiobutton(
                "_repair",
                "delete",
                False,
                _("Delete rules containing tags that have been removed, if tag is used in a positive sense. Just remove that tag if it's used negated."
                  ),
            )
        else:
            html.open_ul()
            html.radiobutton("_repair", "repair", True,
                             _("Fix affected folders, hosts and rules."))

        html.br()
        html.radiobutton("_repair", "abort", False,
                         _("Abort your modifications."))
        html.close_ul()

        html.button("_do_confirm", _("Proceed"), "")
        html.hidden_fields(add_action_vars=True)
        html.end_form()
        html.close_div()
        return False

    return True
Пример #11
0
    def _write_table(
        self,
        rows: TableRows,
        num_rows_unlimited: int,
        actions_enabled: bool,
        actions_visible: bool,
        search_term: Optional[str],
    ) -> None:
        if not self.options["omit_update_header"]:
            row_info = _("1 row") if len(
                rows) == 1 else _("%d rows") % num_rows_unlimited
            html.javascript("cmk.utils.update_row_info(%s);" %
                            json.dumps(row_info))

        table_id = self.id

        num_cols = self._get_num_cols(rows)

        empty_columns = self._get_empty_columns(rows, num_cols)
        if self.options["omit_empty_columns"]:
            num_cols -= len([v for v in empty_columns if v])

        html.open_table(class_=["data", "oddeven"] + self.css)

        # If we have no group headers then paint the headers now
        if self.rows and not isinstance(self.rows[0], GroupHeader):
            self._render_headers(
                actions_enabled,
                actions_visible,
                empty_columns,
            )

        if actions_enabled and actions_visible:
            html.open_tr(class_=["data", "even0", "actions"])
            html.open_td(colspan=num_cols)
            if not html.in_form():
                html.begin_form("%s_actions" % table_id)

            if request.has_var("_%s_sort" % table_id):
                html.open_div(class_=["sort"])
                html.button("_%s_reset_sorting" % table_id, _("Reset sorting"))
                html.close_div()

            if not html.in_form():
                html.begin_form("%s_actions" % table_id)

            html.hidden_fields()
            html.end_form()
            html.close_tr()

        for nr, row in enumerate(rows):
            # Intermediate header
            if isinstance(row, GroupHeader):
                # Show the header only, if at least one (non-header) row follows
                if nr < len(rows) - 1 and not isinstance(
                        rows[nr + 1], GroupHeader):
                    html.open_tr(class_="groupheader")
                    html.open_td(colspan=num_cols)
                    html.h3(row.title)
                    html.close_td()
                    html.close_tr()

                    self._render_headers(actions_enabled, actions_visible,
                                         empty_columns)
                continue

            oddeven_name = "even" if nr % 2 == 0 else "odd"
            class_ = ["data", "%s%d" % (oddeven_name, row.state)]

            if isinstance(row.css, list):
                class_.extend([c for c in row.css if c is not None])
            elif row.css is not None:
                class_.append(row.css)

            html.open_tr(class_=class_,
                         id_=row.id_,
                         onmouseover=row.onmouseover,
                         onmouseout=row.onmouseout)
            for col_index, cell in enumerate(row.cells):
                if self.options["omit_empty_columns"] and empty_columns[
                        col_index]:
                    continue

                html.td(cell.content, class_=cell.css, colspan=cell.colspan)
            html.close_tr()

        if not rows and search_term:
            html.open_tr(class_=["data", "odd0", "no_match"])
            html.td(
                _("Found no matching rows. Please try another search term."),
                colspan=num_cols)
            html.close_tr()

        html.close_table()
Пример #12
0
class UserLoginTwoFactor(Page):
    def page(self) -> None:
        assert user.id is not None

        html.render_headfoot = False
        html.add_body_css_class("login")
        html.add_body_css_class("two_factor")
        make_header(html,
                    _("Two-factor authentication"),
                    Breadcrumb(),
                    javascripts=[])

        html.open_div(id_="login")

        html.open_div(id_="login_window")

        html.open_a(href="https://checkmk.com")
        html.img(
            src=theme.detect_icon_path(icon_name="logo", prefix="mk-"),
            id_="logo",
            class_="custom" if theme.has_custom_logo() else None,
        )
        html.close_a()

        if not is_two_factor_login_enabled(user.id):
            raise MKGeneralException(
                _("Two-factor authentication not enabled"))

        html.begin_form("two_factor_login",
                        method="POST",
                        add_transid=False,
                        action="user_login_two_factor.py")
        html.prevent_password_auto_completion()
        html.hidden_field(
            "_origtarget", origtarget :=
            request.get_url_input("_origtarget", "index.py"))

        if backup_code := request.get_ascii_input("_backup_code"):
            if is_two_factor_backup_code_valid(user.id, backup_code):
                set_two_factor_completed()
                raise HTTPRedirect(origtarget)

        html.label(
            _("Two-factor authentication"),
            for_="webauthn_message",
            id_="label_2fa",
            class_="legend",
        )
        html.div("", id_="webauthn_message")

        with foldable_container(
                treename="webauthn_backup_codes",
                id_="backup_container",
                isopen=False,
                title=_("Use backup code"),
                indent=False,
                save_state=False,
        ):
            html.label(
                "%s:" % _("Backup code"),
                id_="label_pass",
                class_=["legend"],
                for_="_backup_code",
            )
            html.br()
            html.password_input("_backup_code", id_="input_pass", size=None)

            html.open_div(id_="button_text")
            html.button("_use_backup_code",
                        _("Use backup code"),
                        cssclass="hot")
            html.close_div()
            html.close_div()

        if user_errors:
            html.open_div(id_="login_error")
            html.show_user_errors()
            html.close_div()

        html.javascript("cmk.webauthn.login()")

        html.hidden_fields()
        html.end_form()
        html.close_div()
        html.footer()
Пример #13
0
 def render(self, what):
     html.button("_delete_crash_reports", _("Delete"))