╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │2258 .event = .{ .user = event }, │ │2259 }}); │ │2260 } │ │2261 - │ │2262 -pub const KeyAction = enum { add, remove }; │ │2261 │ │2264 -// add an authorized_keys line to the user's ssh keys, or remove the lines│ │2265 -// holding the same key. removing a key they don't hold writes nothing. │ │2266 -pub fn changeUserKey( │ │2262 +// add an authorized_keys line to the user's ssh keys │ │2263 +pub fn addUserKey( │ │2264 io: std.Io, │ │2265 allocator: std.mem.Allocator, │ │2266 users_dir: []const u8, │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────╮ │2267 admin_repo: *rp.Repo(.xit, admin_repo_opts), │ │2268 user_id: *const [event_id_size]u8, │ │2272 - action: KeyAction, │ │2269 key_text: []const u8, │ │2270 ) !void { │ │2271 const key = std.mem.trim(u8, key_text, " \t\r");│ ╰──────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2274 const fingerprint = User.fingerprintOfKey(key) orelse return error.InvalidKey; │ │2275 // the key types the ssh server verifies │ │2276 const key_type = std.mem.sliceTo(key, ' '); │ │2281 - if (action == .add and !std.mem.eql(u8, key_type, "ssh-ed25519") and !std.mem.eql(u8, key_type, "ssh-rsa")) return error.UnsupportedKey;│ │2277 + if (!std.mem.eql(u8, key_type, "ssh-ed25519") and !std.mem.eql(u8, key_type, "ssh-rsa")) return error.UnsupportedKey; │ │2278 + try writeUserKeys(io, allocator, users_dir, admin_repo, user_id, &fingerprint, key); │ │2279 +} │ │2280 + │ │2281 +// remove the user's ssh key with this fingerprint. removing a key they don't │ │2282 +// hold writes nothing. │ │2283 +pub fn removeUserKey( │ │2284 + io: std.Io, │ │2285 + allocator: std.mem.Allocator, │ │2286 + users_dir: []const u8, │ │2287 + admin_repo: *rp.Repo(.xit, admin_repo_opts), │ │2288 + user_id: *const [event_id_size]u8, │ │2289 + fingerprint: *const [User.fingerprint_len]u8, │ │2290 +) !void { │ │2291 + try writeUserKeys(io, allocator, users_dir, admin_repo, user_id, fingerprint, null); │ │2292 +} │ │2293 │ │2294 +// rewrite the user's ssh keys with `added` appended, or without the key with │ │2295 +// `fingerprint` when nothing is added │ │2296 +fn writeUserKeys( │ │2297 + io: std.Io, │ │2298 + allocator: std.mem.Allocator, │ │2299 + users_dir: []const u8, │ │2300 + admin_repo: *rp.Repo(.xit, admin_repo_opts), │ │2301 + user_id: *const [event_id_size]u8, │ │2302 + fingerprint: *const [User.fingerprint_len]u8, │ │2303 + added: ?[]const u8, │ │2304 +) !void { │ │2305 var arena = std.heap.ArenaAllocator.init(allocator); │ │2306 defer arena.deinit(); │ │2307 const moment = try currentMoment(admin_repo_opts, admin_repo); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │2313 var lines = std.mem.splitScalar(u8, user.event.ssh_keys, '\n'); │ │2314 while (lines.next()) |line| { │ │2315 const line_fingerprint = User.fingerprintOfKey(line) orelse continue;│ │2294 - if (std.mem.eql(u8, &line_fingerprint, &fingerprint)) { │ │2316 + if (std.mem.eql(u8, &line_fingerprint, fingerprint)) { │ │2317 held = true; │ │2296 - if (action == .remove) continue; │ │2318 + if (added == null) continue; │ │2319 } │ │2320 if (keys.items.len > 0) try keys.append(arena.allocator(), '\n'); │ │2321 try keys.appendSlice(arena.allocator(), line); │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │2322 } │ │2301 - switch (action) { │ │2302 - .add => { │ │2303 - if (held) return error.KeyAdded; │ │2304 - if (keys.items.len > 0) try keys.append(arena.allocator(), '\n');│ │2305 - try keys.appendSlice(arena.allocator(), key); │ │2306 - }, │ │2307 - .remove => if (!held) return, │ │2308 - } │ │2323 + if (added) |key| { │ │2324 + if (held) return error.KeyAdded; │ │2325 + if (keys.items.len > 0) try keys.append(arena.allocator(), '\n'); │ │2326 + try keys.appendSlice(arena.allocator(), key); │ │2327 + } else if (!held) return; │ │2328 │ │2329 var event = user.event; │ │2330 event.ssh_keys = keys.items; │ ╰───────────────────────────────────────────────────────────────────────────────────╯