╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────────╮ │src/serve_ssh.zig│ ╰─────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │533 │ │534 return .{ .service = service, .dir = try allocator.dupe(u8, dir_token) }; │ │535 } │ │536 + │ │537 +const RepoAuthorization = union(enum) { allowed: ?evt.CommitAuthor, create: RepoCreator, denied, not_found };│ │538 │ │549 -const RepoAuthorization = union(enum) { allowed: ?evt.CommitAuthor, denied, not_found }; │ │539 +// the owner of a repo a push may create │ │540 +const RepoCreator = struct { │ │541 + owner_id: [evt.event_id_size]u8, │ │542 + owner: evt.CommitAuthor, │ │543 +}; │ │544 │ │545 fn authorizeRepoKey( │ │546 io: std.Io, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │563 // no viewer yet, so this carries the base role │ │564 const repo = (try evt.readRepoByOwnerAndName(io, allocator, arena, moment, users_dir, owner_name, repo_name, null)) orelse { │ │565 if (service == .upload_pack) return .not_found; │ │572 - const owner = (try evt.User.readByName(io, allocator, admin_repo_path, arena, owner_name)) orelse return .not_found; │ │566 + const owner_id = (try evt.User.readIdByName(evt.AdminDB, evt.admin_repo_opts.hash, moment, owner_name)) orelse return .not_found;│ │567 + const owner = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, moment, arena, &owner_id)) orelse unreachable; │ │568 return if (isKeyInAuthorizedKeys(owner.event.ssh_keys, fingerprint)) │ │574 - .{ .allowed = .{ .name = owner.event.name, .email = owner.event.email } } │ │569 + .{ .create = .{ .owner_id = owner_id, .owner = .{ .name = owner.event.name, .email = owner.event.email } } } │ │570 else │ │571 .denied; │ │572 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────╮ │src/test/net.zig│ ╰────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │29 test "push creates missing repo under serve" { │ │30 const io = std.testing.io; │ │31 const allocator = std.testing.allocator; │ │32 - // the server creates missing repositories as sha1 │ │33 - try testPushCreatesMissingRepo(.xit, .{ .wire = .ssh }, 3201, io, allocator); │ │32 + try testPushCreatesMissingRepo(.xit, .{ .wire = .ssh }, .sha1, 3201, io, allocator); │ │33 + try testPushCreatesMissingRepo(.xit, .{ .wire = .ssh }, .sha256, 3203, io, allocator);│ │34 } │ │35 │ │36 test "push events" { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────╮ │855 fn testPushCreatesMissingRepo( │ │856 comptime repo_kind: rp.RepoKind, │ │857 comptime transport_def: net.TransportDefinition,│ │858 + comptime hash_kind: hash.HashKind, │ │859 comptime port: u16, │ │860 io: std.Io, │ │861 allocator: std.mem.Allocator, │ ╰─────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │871 const client_path = try std.fs.path.join(allocator, &.{ temp_path, "client" }); │ │872 defer allocator.free(client_path); │ │873 │ │873 - var client_repo = try rp.Repo(repo_kind, .{ .is_test = true }).init(io, allocator, .{ .path = client_path }); │ │874 + var client_repo = try rp.Repo(repo_kind, .{ .is_test = true, .hash = hash_kind }).init(io, allocator, .{ .path = client_path });│ │875 defer client_repo.deinit(io, allocator); │ │876 │ │877 const commit1 = blk: { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │912 } } }, │ │913 ); │ │914 │ │914 - // the push registered admin:server; resolve its on-disk directory │ │915 + // the push registered admin:testrepo in the client's hash format; resolve its on-disk directory│ │916 const server_path = (try repoOnDiskPath(io, allocator, temp_path, "testrepo", false)).?; │ │917 defer allocator.free(server_path); │ │918 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │918 - var server_repo = try rp.Repo(.xit, .{ .is_test = true }).open(io, allocator, .{ .path = server_path }); │ │919 + var server_repo = try rp.Repo(.xit, .{ .is_test = true, .hash = hash_kind }).open(io, allocator, .{ .path = server_path });│ │920 defer server_repo.deinit(io, allocator); │ │921 try std.testing.expect(try server_repo.isBare(io, allocator)); │ │922 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │87 return switch (host) { │ │88 .server => |server| blk: { │ │89 const identity = repoBaseIdentity(repo_base) orelse break :blk null; │ │90 - const path = switch (try serve_common.resolveRepoPath(io, allocator, server.users_dir, server.admin_repo_path, identity, false)) {│ │90 + const path = switch (try serve_common.resolveRepoPath(io, allocator, server.users_dir, server.admin_repo_path, identity)) { │ │91 .ok => |value| value, │ │92 .invalid, .not_found => break :blk null, │ │93 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯