╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Grant.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
78 const order_key = evt.orderKeyDesc(record.created_order, event_id); 79 80 // the id set retains removed records so merges can carry removals 81 if (existing_cursor_maybe == null) { 82 const ids = try DB.SortedSet(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, all_id_set_key))); 83 try ids.put(&order_key); 84 } 85 86 // the id fixes the target, so a grant never moves between sets 87 const target_grants = try DB.SortedSet(.read_write).init(try by_target.putCursor(hash.hashInt(hash_kind, record.event.target_id))); 88 if (record.removed) { 89 _ = try target_grants.remove(&order_key); 90 } else { 91 try target_grants.put(&order_key); 92 } 93 } 94 95 // the role a user was granted on a target, or null without an active grant 96 pub fn readRole( 97 comptime DB: type, 98 comptime hash_kind: hash.HashKind, 99 haxy_moment: DB.HashMap(.read_only), 100 arena: *std.heap.ArenaAllocator, 101 target_id: []const u8, 102 user_id: []const u8, 103 ) !?evt.Repo.Role { 104 const Granted = struct { event: struct { role: evt.Repo.Role }, removed: bool }; 105 const grant = (try evt.readRecordSubset(Self, Granted, DB, hash_kind, haxy_moment, arena, &idOf(target_id, user_id))) orelse return null; 106 return if (grant.removed) null else grant.event.role; 107 } 108 109 // a target's active grants, newest first 110 pub fn readByTarget( 111 comptime DB: type, 112 comptime hash_kind: hash.HashKind, 113 haxy_moment: DB.HashMap(.read_only), 114 arena: *std.heap.ArenaAllocator, 115 target_id: []const u8, 116 ) ![]const Self { 117 var grants: std.ArrayList(Self) = .empty; 118 const by_target_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, target_to_grant_id_set_key)) orelse return grants.items; 119 const by_target = try DB.HashMap(.read_only).init(by_target_cursor); 120 const target_grants_cursor = try by_target.getCursor(hash.hashInt(hash_kind, target_id)) orelse return grants.items; 121 const target_grants = try DB.SortedSet(.read_only).init(target_grants_cursor); 122 123 var iter = try target_grants.iteratorFromIndex(0); 124 while (try iter.next()) |kv_cursor| { 125 const grant_id = try evt.readOrderKeyId(DB, kv_cursor); 126 const grant = (try evt.readRecordSubset(Self, struct { event: Self }, DB, hash_kind, haxy_moment, arena, &grant_id)) orelse continue; 127 try grants.append(arena.allocator(), grant.event); 128 } 129 return grants.items; 130 } 131