╭ changed ────────╮ │src/serve_ssh.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │508 const role = value.role orelse return writeError(sess, "repo not found"); │ │509 if (!role.atLeast(patch_role)) return writeError(sess, "unauthorized: your role in this repo may not write patches"); │ │510 } │ │511 + } │ │512 + if (service == .upload_pack) { │ │513 + // a fork is as readable as its target, and only its forker's once the target is gone │ │514 + const readable = if (target) |value| readable: { │ │515 + const owner = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, admin_moment, &admin_arena, &target_owner_id)) orelse unreachable; │ │516 + break :readable try authorizeRepoKey(io, &admin_arena, handler.admin_repo_path, handler.server.users_dir, owner.event.name, value.repo.event.name, .upload_pack, &sess.fingerprint) == .allowed;│ │517 + } else try evt.User.holdsKey(evt.AdminDB, evt.admin_repo_opts.hash, admin_moment, &admin_arena, &forker_id, &sess.fingerprint); │ │518 + if (!readable) return writeError(sess, "unauthorized: this SSH key cannot read this patch draft"); │ │519 } │ │520 │ │521 const draft_path = try fork.forkPath(allocator, handler.server.users_dir, &forker_id, &fork_id); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯