Beispiel #1
0
    def _validate_ldap_connection(self, value, varprefix):
        for role_id, group_specs in value["active_plugins"].get(
                "groups_to_roles", {}).items():
            if role_id == "nested":
                continue  # This is the option to enabled/disable nested group handling, not a role to DN entry

            for index, group_spec in enumerate(group_specs):
                dn, connection_id = group_spec

                if connection_id is None:
                    group_dn = value["group_dn"]

                else:
                    connection = get_connection(connection_id)
                    if not connection:
                        continue
                    assert isinstance(connection, LDAPUserConnector)
                    group_dn = connection.get_group_dn()

                if not group_dn:
                    raise MKUserError(
                        varprefix,
                        _("You need to configure the group base DN to be able to "
                          "use the roles synchronization plugin."),
                    )

                if not dn.lower().endswith(group_dn.lower()):
                    varname = "connection_p_active_plugins_p_groups_to_roles_p_%s_1_%d" % (
                        role_id,
                        index,
                    )
                    raise MKUserError(
                        varname,
                        _("The configured DN does not match the group base DN."
                          ))
Beispiel #2
0
def create_non_existing_user(connection_id: str, username: UserId) -> None:
    if user_exists(username):
        return  # User exists. Nothing to do...

    users = load_users(lock=True)
    users[username] = new_user_template(connection_id)
    save_users(users)

    # Call the sync function for this new user
    connection = get_connection(connection_id)
    try:
        if connection is None:
            raise MKUserError(None,
                              _("Invalid user connection: %s") % connection_id)

        connection.do_sync(add_to_changelog=False,
                           only_username=username,
                           load_users_func=load_users,
                           save_users_func=save_users)
    except MKLDAPException as e:
        show_exception(connection_id,
                       _("Error during sync"),
                       e,
                       debug=config.debug)
    except Exception as e:
        show_exception(connection_id, _("Error during sync"), e)
Beispiel #3
0
def create_non_existing_user(connection_id: str, username: UserId) -> None:
    # Since user_exists also looks into the htpasswd and treats all users that can be found there as
    # "existing users", we don't care about partially known users here and don't create them ad-hoc.
    # The load_users() method will handle this kind of users (TODO: Consolidate this!).
    # Which makes this function basically relevant for users that authenticate using an LDAP
    # connection and do not exist yet.
    if user_exists(username):
        return  # User exists. Nothing to do...

    users = load_users(lock=True)
    users[username] = new_user_template(connection_id)
    save_users(users)

    # Call the sync function for this new user
    connection = get_connection(connection_id)
    try:
        if connection is None:
            raise MKUserError(None,
                              _("Invalid user connection: %s") % connection_id)

        connection.do_sync(add_to_changelog=False,
                           only_username=username,
                           load_users_func=load_users,
                           save_users_func=save_users)
    except MKLDAPException as e:
        show_exception(connection_id,
                       _("Error during sync"),
                       e,
                       debug=config.debug)
    except Exception as e:
        show_exception(connection_id, _("Error during sync"), e)
Beispiel #4
0
    def __init__(self, new, connection_id):
        self._new = new
        self._connection_id = connection_id
        self._connection = get_connection(self._connection_id)

        general_elements = self._general_elements()
        connection_elements = self._connection_elements()
        user_elements = self._user_elements()
        group_elements = self._group_elements()
        other_elements = self._other_elements()

        valuespec = Dictionary(
            title=_("LDAP Connection"),
            elements=general_elements
            + connection_elements
            + user_elements
            + group_elements
            + other_elements,
            headers=[
                (_("General Properties"), [key for key, _vs in general_elements]),
                (_("LDAP Connection"), [key for key, _vs in connection_elements]),
                (_("Users"), [key for key, _vs in user_elements]),
                (_("Groups"), [key for key, _vs in group_elements]),
                (_("Attribute Sync Plugins"), ["active_plugins"]),
                (_("Other"), ["cache_livetime"]),
            ],
            render="form",
            form_narrow=True,
            optional_keys=[
                "port",
                "use_ssl",
                "bind",
                "page_size",
                "response_timeout",
                "failover_servers",
                "user_filter",
                "user_filter_group",
                "user_id",
                "lower_user_ids",
                "connect_timeout",
                "version",
                "group_filter",
                "group_member",
                "suffix",
                "create_only_on_login",
            ],
            validate=self._validate_ldap_connection,
        )

        super().__init__(valuespec, forth=LDAPUserConnector.transform_config)
Beispiel #5
0
def _get_attributes(
        connection_id: Optional[str],
        selector: Callable[[UserConnector], List[str]]) -> List[str]:
    connection = get_connection(connection_id)
    return selector(connection) if connection else []
Beispiel #6
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 = users.items()

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

        roles = userdb.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" %
                        six.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 watolib.load_configuration_settings().get(
                        "enable_rulebased_notifications"):
                    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 watolib.load_configuration_settings().get(
                        "enable_rulebased_notifications"):
                    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 #7
0
def _get_attributes(connection_id, selector):
    # type: (Optional[str], Callable[[UserConnector], List[str]]) -> List[str]
    connection = get_connection(connection_id)
    return selector(connection) if connection else []