Esempio n. 1
0
def edit_users(changed_users):
    all_users = userdb.load_users(lock=True)
    new_users_info = []
    modified_users_info = []
    for user_id, settings in changed_users.items():
        user_attrs = settings.get("attributes")
        is_new_user = settings.get("is_new_user", True)
        _validate_user_attributes(all_users, user_id, user_attrs, is_new_user=is_new_user)
        if is_new_user:
            new_users_info.append(user_id)
        else:
            modified_users_info.append(user_id)

        if is_new_user:
            add_internal_attributes(user_attrs)

        old_object = make_user_audit_log_object(all_users.get(user_id, {}))
        log_audit(action="edit-user",
                  message=(_("Created new user: %s") %
                           user_id if is_new_user else _("Modified user: %s") % user_id),
                  diff_text=make_diff_text(old_object, make_user_audit_log_object(user_attrs)),
                  object_ref=make_user_object_ref(user_id))

        all_users[user_id] = user_attrs

    if new_users_info:
        add_change("edit-users", _("Created new users: %s") % ", ".join(new_users_info))
    if modified_users_info:
        add_change("edit-users", _("Modified users: %s") % ", ".join(modified_users_info))

    userdb.save_users(all_users)
Esempio n. 2
0
def edit_users(changed_users):
    all_users = userdb.load_users(lock=True)
    new_users_info = []
    modified_users_info = []
    for user_id, settings in changed_users.items():
        user_attrs = settings.get("attributes")
        is_new_user = settings.get("is_new_user", True)
        _validate_user_attributes(all_users, user_id, user_attrs, is_new_user=is_new_user)
        if is_new_user:
            new_users_info.append(user_id)
        else:
            modified_users_info.append(user_id)

        if is_new_user:
            add_internal_attributes(user_attrs)

        all_users[user_id] = user_attrs

    if new_users_info:
        add_change("edit-users", _("Created new user: %s") % ", ".join(new_users_info))
    if modified_users_info:
        add_change("edit-users", _("Modified user: %s") % ", ".join(modified_users_info))

    userdb.save_users(all_users)
Esempio n. 3
0
def load_users(lock: bool = False) -> Users:
    filename = _root_dir() + "contacts.mk"

    if lock:
        # Note: the lock will be released on next save_users() call or at
        #       end of page request automatically.
        store.aquire_lock(filename)

    if 'users' in g:
        return g.users

    # First load monitoring contacts from Checkmk's world. If this is
    # the first time, then the file will be empty, which is no problem.
    # Execfile will the simply leave contacts = {} unchanged.
    contacts = store.load_from_mk_file(filename, "contacts", {})

    # Now load information about users from the GUI config world
    filename = _multisite_dir() + "users.mk"
    users = store.load_from_mk_file(_multisite_dir() + "users.mk",
                                    "multisite_users", {})

    # Merge them together. Monitoring users not known to Multisite
    # will be added later as normal users.
    result = {}
    for uid, user in users.items():
        # Transform user IDs which were stored with a wrong type
        uid = ensure_str(uid)

        profile = contacts.get(uid, {})
        profile.update(user)
        result[uid] = profile

        # Convert non unicode mail addresses
        if "email" in profile:
            profile["email"] = ensure_str(profile["email"])

    # This loop is only neccessary if someone has edited
    # contacts.mk manually. But we want to support that as
    # far as possible.
    for uid, contact in contacts.items():
        # Transform user IDs which were stored with a wrong type
        uid = ensure_str(uid)

        if uid not in result:
            result[uid] = contact
            result[uid]["roles"] = ["user"]
            result[uid]["locked"] = True
            result[uid]["password"] = ""

    # Passwords are read directly from the apache htpasswd-file.
    # That way heroes of the command line will still be able to
    # change passwords with htpasswd. Users *only* appearing
    # in htpasswd will also be loaded and assigned to the role
    # they are getting according to the multisite old-style
    # configuration variables.

    def readlines(f):
        try:
            return Path(f).open(encoding="utf-8")
        except IOError:
            return []

    # FIXME TODO: Consolidate with htpasswd user connector
    filename = cmk.utils.paths.htpasswd_file
    for line in readlines(filename):
        line = line.strip()
        if ':' in line:
            uid, password = line.strip().split(":")[:2]
            uid = ensure_str(uid)
            if password.startswith("!"):
                locked = True
                password = password[1:]
            else:
                locked = False
            if uid in result:
                result[uid]["password"] = password
                result[uid]["locked"] = locked
            else:
                # Create entry if this is an admin user
                new_user = {
                    "roles": config.roles_of_user(uid),
                    "password": password,
                    "locked": False,
                }

                add_internal_attributes(new_user)

                result[uid] = new_user
            # Make sure that the user has an alias
            result[uid].setdefault("alias", uid)
        # Other unknown entries will silently be dropped. Sorry...

    # Now read the serials, only process for existing users
    serials_file = '%s/auth.serials' % os.path.dirname(
        cmk.utils.paths.htpasswd_file)
    for line in readlines(serials_file):
        line = line.strip()
        if ':' in line:
            user_id, serial = line.split(':')[:2]
            user_id = ensure_str(user_id)
            if user_id in result:
                result[user_id]['serial'] = utils.saveint(serial)

    # Now read the user specific files
    directory = cmk.utils.paths.var_dir + "/web/"
    for d in os.listdir(directory):
        if d[0] != '.':
            uid = ensure_str(d)

            # read special values from own files
            if uid in result:
                for attr, conv_func in [
                    ('num_failed_logins', utils.saveint),
                    ('last_pw_change', utils.saveint),
                    ('enforce_pw_change', lambda x: bool(utils.saveint(x))),
                    ('idle_timeout', _convert_idle_timeout),
                    ('session_info', _convert_session_info),
                    ('ui_theme', lambda x: x),
                    ('ui_sidebar_position', lambda x: None
                     if x == "None" else x),
                ]:
                    val = load_custom_attr(uid, attr, conv_func)
                    if val is not None:
                        result[uid][attr] = val

            # read automation secrets and add them to existing
            # users or create new users automatically
            try:
                user_secret_path = Path(directory) / d / "automation.secret"
                with user_secret_path.open(encoding="utf-8") as f:
                    secret: Optional[str] = ensure_str(f.read().strip())
            except IOError:
                secret = None

            if secret:
                if uid in result:
                    result[uid]["automation_secret"] = secret
                else:
                    result[uid] = {
                        "roles": ["guest"],
                        "automation_secret": secret,
                    }

    # populate the users cache
    g.users = result

    return result