From 59bb8c4d0e190ca03a326144ea2e667b7a89c491 Mon Sep 17 00:00:00 2001 From: Luka Vandervelden Date: Sun, 17 Nov 2019 18:42:11 +0100 Subject: [PATCH] Passwd#remove_user(uid), Passwd#remove_group(gid) --- src/passwd.cr | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/passwd.cr b/src/passwd.cr index e898844..947e760 100644 --- a/src/passwd.cr +++ b/src/passwd.cr @@ -1,4 +1,5 @@ require "csv" +require "file_utils" # FIXME: Should we work on arrays and convert to CSV at the last second when adding rows? # FIXME: Use split, not CSV. @@ -9,14 +10,11 @@ class Passwd @group : String # FIXME: Missing operations: - # - Removing users. # - Reading groups. # - Adding and removing groups (ok, maybe admins can do that?) # - Adding users to group. # - Removing users from group. - # FIXME: Safety. Ensure passwd and group cannot be in a half-written state. (backups will probably work well enough in the mean-time) - def initialize(@passwd, @group) end @@ -188,6 +186,58 @@ class Passwd File.write @passwd, new_passwd.join("\n") + "\n" end + + private def safe_rewrite(path : String, body : String) + tempfile = File.tempfile(File.basename path) + tempfile << body + tempfile.close + + FileUtils.cp tempfile.path, path + end + + def remove_user(uid) + user = get_user(uid) + + return nil unless user + + user_login = user.login + + new_group = group_as_array.map do |line| + group = Group.new line + + group.users.select! &.!=(user_login) + + group.to_csv + end + + safe_rewrite @group, new_group.join('\n') + '\n' + + new_passwd = passwd_as_array.compact_map do |line| + user = User.new line + + if uid == user.uid + nil + else + line.join ':' + end + end + + safe_rewrite @passwd, new_passwd.join("\n") + "\n" + end + + def remove_group(gid) + new_group = group_as_array.compact_map do |line| + group = Group.new line + + if gid == group.gid + nil + else + line.join ':' + end + end + + safe_rewrite @group, new_group.join('\n') + '\n' + end end class Passwd::Group