Beispiel #1
0
def _page_menu_entries_related(page_name: str) -> Iterator[PageMenuEntry]:
    if page_name != "user_change_pw":
        yield PageMenuEntry(
            title=_("Change password"),
            icon_name="topic_change_password",
            item=make_simple_link("user_change_pw.py"),
            is_shortcut=True,
        )

    if page_name != "user_two_factor_overview" and user.may(
            "general.manage_2fa"):
        yield PageMenuEntry(
            title=_("Edit two-factor authentication"),
            icon_name="topic_2fa",
            item=make_simple_link("user_two_factor_overview.py"),
            is_shortcut=True,
        )

    if page_name != "user_profile":
        yield PageMenuEntry(
            title=_("Edit profile"),
            icon_name="topic_profile",
            item=make_simple_link("user_profile.py"),
            is_shortcut=True,
        )

    if (page_name != "user_notifications_p"
            and rulebased_notifications_enabled()
            and user.may("general.edit_notifications")):
        yield PageMenuEntry(
            title=_("Notification rules"),
            icon_name="topic_events",
            item=make_simple_link("wato.py?mode=user_notifications_p"),
            is_shortcut=True,
        )
Beispiel #2
0
 def execute(self) -> Iterator[ACResult]:
     if not rulebased_notifications_enabled():
         yield ACResultCRIT(
             'Rulebased notifications are deactivated in the global settings'
         )
     else:
         yield ACResultOK(_("Rulebased notifications are activated"))
Beispiel #3
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()
Beispiel #4
0
 def _show_context_buttons(self) -> None:
     rulebased_notifications = rulebased_notifications_enabled()
     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()
Beispiel #5
0
    def _show_form(self, profile_changed: bool) -> None:
        assert config.user.id is not None

        users = userdb.load_users()

        if profile_changed:
            flash(_("Successfully updated user profile."))
            # Ensure theme changes are applied without additional user interaction
            html.reload_whole_page()

        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(_("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()
Beispiel #6
0
    def _show_form(self) -> None:
        assert user.id is not None

        users = userdb.load_users()

        user_spec: Optional[UserSpec] = users.get(user.id)
        if user_spec 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_spec.get("alias", user.id))

        select_language(user_spec)

        # Let the user configure how he wants to be notified
        rulebased_notifications = rulebased_notifications_enabled()
        if (
            not rulebased_notifications
            and user.may("general.edit_notifications")
            and user_spec.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_spec.get("notification_method")
            )

        if user.may("general.edit_user_attributes"):
            custom_user_attr_topics = get_user_attributes_by_topic()
            _show_custom_user_attr(user_spec, custom_user_attr_topics.get("personal", []))
            forms.header(_("User interface settings"))
            _show_custom_user_attr(user_spec, custom_user_attr_topics.get("interface", []))

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
Beispiel #7
0
def _user_menu_topics() -> List[TopicMenuTopic]:
    items = [
        TopicMenuItem(
            name="change_password",
            title=_("Change password"),
            url="user_change_pw.py",
            sort_index=10,
            is_advanced=False,
            icon_name="topic_change_password",
            emblem=None,
        ),
        TopicMenuItem(
            name="user_profile",
            title=_("Edit profile"),
            url="user_profile.py",
            sort_index=20,
            is_advanced=False,
            icon_name="topic_profile",
            emblem=None,
        ),
        TopicMenuItem(
            name="logout",
            title=_("Logout"),
            url="logout.py",
            sort_index=30,
            is_advanced=False,
            icon_name="sidebar_logout",
            emblem=None,
        ),
    ]

    if rulebased_notifications_enabled() and config.user.may('general.edit_notifications'):
        items.insert(
            1,
            TopicMenuItem(
                name="notification_rules",
                title=_("Notification rules"),
                url="wato.py?mode=user_notifications_p",
                sort_index=30,
                is_advanced=False,
                icon_name="topic_events",
                emblem=None,
            ))

    return [TopicMenuTopic(
        name="user",
        title=_("User"),
        icon_name="topic_profile",
        items=items,
    )]
Beispiel #8
0
def _page_menu_entries_related() -> Iterator[PageMenuEntry]:
    yield PageMenuEntry(
        title=_("Change password"),
        icon_name="topic_change_password",
        item=make_simple_link("user_change_pw.py"),
    )

    yield PageMenuEntry(
        title=_("Edit profile"),
        icon_name="topic_profile",
        item=make_simple_link("user_profile.py"),
    )

    if rulebased_notifications_enabled() and config.user.may('general.edit_notifications'):
        yield PageMenuEntry(
            title=_("Notification rules"),
            icon_name="topic_events",
            item=make_simple_link("wato.py?mode=user_notifications_p"),
        )
Beispiel #9
0
def _validate_user_attributes(all_users,
                              user_id,
                              user_attrs,
                              is_new_user=True):
    # Check user_id
    if is_new_user:
        if user_id in all_users:
            raise MKUserError(
                "user_id",
                _("This username is already being used by another user."))
        vs_user_id = UserID(allow_empty=False)
        vs_user_id.validate_value(user_id, "user_id")
    else:
        if user_id not in all_users:
            raise MKUserError(
                None, _("The user you are trying to edit does not exist."))

    # Full name
    alias = user_attrs.get("alias")
    if not alias:
        raise MKUserError(
            "alias",
            _("Please specify a full name or descriptive alias for the user."))

    # Locking
    locked = user_attrs.get("locked")
    if user_id == config.user.id and locked:
        raise MKUserError("locked", _("You cannot lock your own account!"))

    # Authentication: Password or Secret
    if "automation_secret" in user_attrs:
        secret = user_attrs["automation_secret"]
        if len(secret) < 10:
            raise MKUserError(
                'secret',
                _("Please specify a secret of at least 10 characters length."))
    else:
        password = user_attrs.get("password")
        if password:
            verify_password_policy(password)

    # Email
    email = user_attrs.get("email")
    vs_email = EmailAddress()
    vs_email.validate_value(email, "email")

    # Idle timeout
    idle_timeout = user_attrs.get("idle_timeout")
    vs_user_idle_timeout = get_vs_user_idle_timeout()
    vs_user_idle_timeout.validate_value(idle_timeout, "idle_timeout")

    # Notification settings are only active if we do *not* have rule based notifications!
    if not global_settings.rulebased_notifications_enabled():
        # Notifications
        notifications_enabled = user_attrs.get("notification_enabled")

        # Check if user can receive notifications
        if notifications_enabled:
            if not email:
                raise MKUserError(
                    "email",
                    _('You have enabled the notifications but missed to configure a '
                      'Email address. You need to configure your mail address in order '
                      'to be able to receive emails.'))

            contactgroups = user_attrs.get("contactgroups")
            if not contactgroups:
                raise MKUserError(
                    "notifications_enabled",
                    _('You have enabled the notifications but missed to make the '
                      'user member of at least one contact group. You need to make '
                      'the user member of a contact group which has hosts assigned '
                      'in order to be able to receive emails.'))

            roles = user_attrs.get("roles")
            if not roles:
                raise MKUserError(
                    "role_user",
                    _("Your user has no roles. Please assign at least one role."
                      ))

        notification_method = user_attrs.get("notification_method")
        get_vs_flexible_notifications().validate_value(notification_method,
                                                       "notification_method")
    else:
        fallback_contact = user_attrs.get("fallback_contact")
        if fallback_contact and not email:
            raise MKUserError(
                "email",
                _("You have enabled the fallback notifications but missed to configure an "
                  "email address. You need to configure your mail address in order "
                  "to be able to receive fallback notifications."))

    # Custom user attributes
    for name, attr in userdb.get_user_attributes():
        value = user_attrs.get(name)
        attr.valuespec().validate_value(value, "ua_" + name)
Beispiel #10
0
def _user_menu_topics() -> List[TopicMenuTopic]:
    quick_items = [
        TopicMenuItem(
            name="ui_theme",
            title=_("Color theme"),
            url=
            'javascript:cmk.sidebar.toggle_user_attribute("ajax_ui_theme.py")',
            target="",
            sort_index=10,
            icon="color_mode",
            button_title=_get_current_theme_titel(),
        ),
        TopicMenuItem(
            name="sidebar_position",
            title=_("Sidebar position"),
            url=
            'javascript:cmk.sidebar.toggle_user_attribute("ajax_sidebar_position.py")',
            target="",
            sort_index=20,
            icon="sidebar_position",
            button_title=_sidebar_position_title(_get_sidebar_position()),
        ),
    ]

    items = [
        TopicMenuItem(
            name="user_profile",
            title=_("Edit profile"),
            url="user_profile.py",
            sort_index=10,
            icon="topic_profile",
        ),
        TopicMenuItem(
            name="change_password",
            title=_("Change password"),
            url="user_change_pw.py",
            sort_index=30,
            icon="topic_change_password",
        ),
        TopicMenuItem(
            name="two_factor",
            title=_("Two-factor authentication"),
            url="user_two_factor_overview.py",
            sort_index=30,
            icon="topic_two_factor",
        ),
        TopicMenuItem(
            name="logout",
            title=_("Logout"),
            url="logout.py",
            sort_index=40,
            icon="sidebar_logout",
        ),
    ]

    if rulebased_notifications_enabled() and user.may(
            "general.edit_notifications"):
        items.insert(
            1,
            TopicMenuItem(
                name="notification_rules",
                title=_("Notification rules"),
                url="wato.py?mode=user_notifications_p",
                sort_index=20,
                icon="topic_events",
            ),
        )

    return [
        TopicMenuTopic(
            name="user",
            title=_("User interface"),
            icon="topic_user_interface",
            items=quick_items,
        ),
        TopicMenuTopic(
            name="user",
            title=_("User profile"),
            icon="topic_profile",
            items=items,
        ),
    ]
Beispiel #11
0
def _user_menu_topics() -> List[TopicMenuTopic]:
    quick_items = [
        TopicMenuItem(
            name="ui_theme",
            title=_("Interface theme"),
            url=
            "javascript:cmk.sidebar.toggle_user_attribute(\"ajax_ui_theme.py\")",
            target="",
            sort_index=10,
            icon="color_mode",
            button_title=_get_current_theme_titel(),
        ),
        TopicMenuItem(
            name="sidebar_position",
            title=_("Sidebar position"),
            url=
            "javascript:cmk.sidebar.toggle_user_attribute(\"ajax_sidebar_position.py\")",
            target="",
            sort_index=20,
            icon="sidebar_position",
            button_title=_sidebar_position_title(_get_sidebar_position()),
        ),
    ]

    items = [
        TopicMenuItem(
            name="change_password",
            title=_("Change password"),
            url="user_change_pw.py",
            sort_index=10,
            icon="topic_change_password",
        ),
        TopicMenuItem(
            name="user_profile",
            title=_("Edit profile"),
            url="user_profile.py",
            sort_index=20,
            icon="topic_profile",
        ),
        TopicMenuItem(
            name="logout",
            title=_("Logout"),
            url="logout.py",
            sort_index=30,
            icon="sidebar_logout",
        ),
    ]

    if rulebased_notifications_enabled() and config.user.may(
            'general.edit_notifications'):
        items.insert(
            1,
            TopicMenuItem(
                name="notification_rules",
                title=_("Notification rules"),
                url="wato.py?mode=user_notifications_p",
                sort_index=30,
                icon="topic_events",
            ))

    return [
        TopicMenuTopic(
            name="user",
            title=_("Quick toggle"),
            # TODO(rb): set correct icon
            icon="topic_profile",
            items=quick_items,
        ),
        TopicMenuTopic(
            name="user",
            title=_("Profile"),
            icon="topic_profile",
            items=items,
        )
    ]
Beispiel #12
0
    def _show_user_list(self):
        visible_custom_attrs = [(name, attr)
                                for name, attr in userdb.get_user_attributes()
                                if attr.show_in_table()]

        users = userdb.load_users()

        entries = list(users.items())

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

        roles = userdb_utils.load_roles()
        timeperiods = watolib.timeperiods.load_timeperiods()
        contact_groups = load_contact_group_information()

        with table_element("users",
                           None,
                           empty_text=_("No users are defined yet.")) as table:
            online_threshold = time.time() - config.user_online_maxage
            for uid, user in sorted(
                    entries, key=lambda x: x[1].get("alias", x[0]).lower()):
                table.row()

                # Checkboxes
                table.cell(html.render_input(
                    "_toggle_group",
                    type_="button",
                    class_="checkgroup",
                    onclick="cmk.selection.toggle_all_rows();",
                    value='X'),
                           sortable=False,
                           css="checkbox")

                if uid != config.user.id:
                    html.checkbox(
                        "_c_user_%s" %
                        ensure_str(base64.b64encode(uid.encode("utf-8"))))

                user_connection_id = cleanup_connection_id(
                    user.get('connector'))
                connection = get_connection(user_connection_id)

                # Buttons
                table.cell(_("Actions"), css="buttons")
                if connection:  # only show edit buttons when the connector is available and enabled
                    edit_url = watolib.folder_preserving_link([("mode",
                                                                "edit_user"),
                                                               ("edit", uid)])
                    html.icon_button(edit_url, _("Properties"), "edit")

                    clone_url = watolib.folder_preserving_link([
                        ("mode", "edit_user"), ("clone", uid)
                    ])
                    html.icon_button(clone_url,
                                     _("Create a copy of this user"), "clone")

                delete_url = make_action_link([("mode", "users"),
                                               ("_delete", uid)])
                html.icon_button(delete_url, _("Delete"), "delete")

                notifications_url = watolib.folder_preserving_link([
                    ("mode", "user_notifications"), ("user", uid)
                ])
                if rulebased_notifications_enabled():
                    html.icon_button(
                        notifications_url,
                        _("Custom notification table of this user"),
                        "notifications")

                # ID
                table.cell(_("ID"), uid)

                # Online/Offline
                if config.save_user_access_times:
                    last_seen = user.get('last_seen', 0)
                    if last_seen >= online_threshold:
                        title = _('Online')
                        img_txt = 'online'
                    elif last_seen != 0:
                        title = _('Offline')
                        img_txt = 'offline'
                    elif last_seen == 0:
                        title = _('Never logged in')
                        img_txt = 'inactive'

                    title += ' (%s %s)' % (render.date(last_seen),
                                           render.time_of_day(last_seen))
                    table.cell(_("Act."))
                    html.icon(title, img_txt)

                    table.cell(_("Last seen"))
                    if last_seen != 0:
                        html.write_text("%s %s" %
                                        (render.date(last_seen),
                                         render.time_of_day(last_seen)))
                    else:
                        html.write_text(_("Never logged in"))

                if cmk_version.is_managed_edition():
                    table.cell(_("Customer"), managed.get_customer_name(user))

                # Connection
                if connection:
                    table.cell(
                        _("Connection"), '%s (%s)' %
                        (connection.short_title(), user_connection_id))
                    locked_attributes = userdb.locked_attributes(
                        user_connection_id)
                else:
                    table.cell(
                        _("Connection"),
                        "%s (%s) (%s)" %
                        (_("UNKNOWN"), user_connection_id, _("disabled")),
                        css="error")
                    locked_attributes = []

                # Authentication
                if "automation_secret" in user:
                    auth_method = _("Automation")
                elif user.get("password") or 'password' in locked_attributes:
                    auth_method = _("Password")
                else:
                    auth_method = "<i>%s</i>" % _("none")
                table.cell(_("Authentication"), auth_method)

                table.cell(_("State"))
                if user.get("locked", False):
                    html.icon(_('The login is currently locked'),
                              'user_locked')

                if "disable_notifications" in user and isinstance(
                        user["disable_notifications"], bool):
                    disable_notifications_opts = {
                        "disable": user["disable_notifications"]
                    }
                else:
                    disable_notifications_opts = user.get(
                        "disable_notifications", {})

                if disable_notifications_opts.get("disable", False):
                    html.icon(_('Notifications are disabled'),
                              'notif_disabled')

                # Full name / Alias
                table.text_cell(_("Alias"), user.get("alias", ""))

                # Email
                table.text_cell(_("Email"), user.get("email", ""))

                # Roles
                table.cell(_("Roles"))
                if user.get("roles", []):
                    role_links = [(watolib.folder_preserving_link([
                        ("mode", "edit_role"), ("edit", role)
                    ]), roles[role].get("alias")) for role in user["roles"]]
                    html.write_html(
                        HTML(", ").join(
                            html.render_a(alias, href=link)
                            for (link, alias) in role_links))

                # contact groups
                table.cell(_("Contact groups"))
                cgs = user.get("contactgroups", [])
                if cgs:
                    cg_aliases = [
                        contact_groups[c]['alias']
                        if c in contact_groups else c for c in cgs
                    ]
                    cg_urls = [
                        watolib.folder_preserving_link([("mode",
                                                         "edit_contact_group"),
                                                        ("edit", c)])
                        for c in cgs
                    ]
                    html.write_html(
                        HTML(", ").join(
                            html.render_a(content, href=url)
                            for (content, url) in zip(cg_aliases, cg_urls)))
                else:
                    html.i(_("none"))

                #table.cell(_("Sites"))
                #html.write(vs_authorized_sites().value_to_text(user.get("authorized_sites",
                #                                                vs_authorized_sites().default_value())))

                # notifications
                if not rulebased_notifications_enabled():
                    table.cell(_("Notifications"))
                    if not cgs:
                        html.i(_("not a contact"))
                    elif not user.get("notifications_enabled", True):
                        html.write_text(_("disabled"))
                    elif user.get("host_notification_options", "") == "" and \
                         user.get("service_notification_options", "") == "":
                        html.write_text(_("all events disabled"))
                    else:
                        tp = user.get("notification_period", "24X7")
                        if tp not in timeperiods:
                            tp = tp + _(" (invalid)")
                        elif tp not in watolib.timeperiods.builtin_timeperiods(
                        ):
                            url = watolib.folder_preserving_link([
                                ("mode", "edit_timeperiod"), ("edit", tp)
                            ])
                            tp = html.render_a(timeperiod_spec_alias(
                                timeperiods[tp], tp),
                                               href=url)
                        else:
                            tp = timeperiod_spec_alias(timeperiods[tp], tp)
                        html.write(tp)

                # the visible custom attributes
                for name, attr in visible_custom_attrs:
                    vs = attr.valuespec()
                    table.cell(escaping.escape_attribute(_u(vs.title())))
                    html.write(
                        vs.value_to_text(user.get(name, vs.default_value())))

        html.button("_bulk_delete_users",
                    _("Bulk Delete"),
                    "submit",
                    style="margin-top:10px")
        html.hidden_fields()
        html.end_form()

        if not load_contact_group_information():
            url = "wato.py?mode=contact_groups"
            html.open_div(class_="info")
            html.write(
                _("Note: you haven't defined any contact groups yet. If you <a href='%s'>"
                  "create some contact groups</a> you can assign users to them und thus "
                  "make them monitoring contacts. Only monitoring contacts can receive "
                  "notifications.") % url)
            html.write(
                " you can assign users to them und thus "
                "make them monitoring contacts. Only monitoring contacts can receive "
                "notifications.")
            html.close_div()
Beispiel #13
0
 def _rbn_enabled(self):
     # Check if rule based notifications are enabled (via WATO)
     return rulebased_notifications_enabled()