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)
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)
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