diff options
Diffstat (limited to 'src/storage/session-manager')
| -rw-r--r-- | src/storage/session-manager/root.zig | 59 | ||||
| -rw-r--r-- | src/storage/session-manager/session.zig | 34 |
2 files changed, 93 insertions, 0 deletions
diff --git a/src/storage/session-manager/root.zig b/src/storage/session-manager/root.zig new file mode 100644 index 0000000..7f44bf0 --- /dev/null +++ b/src/storage/session-manager/root.zig @@ -0,0 +1,59 @@ +const std = @import("std"); +const config = @import("../../config.zig"); +const Storage = @import("../root.zig"); + +pub const Session = @import("session.zig"); + +const Self = @This(); + +pub const empty: Self = .{ + .cache = .empty, +}; + +cache: std.StringHashMapUnmanaged(Session), + +pub fn add(self: *Self, storage: *Storage, info: Storage.User.Info) !*Session { + const session = try Session.init(storage.allocator, info); + errdefer session.deinit(storage.allocator); + try self.cache.put(storage.allocator, session.fingerprint, session); + return self.cache.getPtr(session.fingerprint) orelse unreachable; +} + +pub fn renew(self: *Self, storage: *Storage, fingerprint: []const u8) !*Session { + if (self.cache.get(fingerprint)) |s| { + var session = s; + try session.reset(); + + try self.cache.put(storage.allocator, session.fingerprint, session); + + _ = self.cache.remove(fingerprint); + + return self.cache.getPtr(session.fingerprint) orelse unreachable; + } + return error.SessionNotFound; +} + +pub fn remove(self: *Self, storage: *Storage, fingerprint: []const u8) void { + if (self.cache.getPtr(fingerprint)) |session| { + session.deinit(storage.allocator); + _ = self.cache.remove(fingerprint); + } +} + +pub fn get(self: *Self, storage: *Storage, fingerprint: []const u8) ?*Session { + if (self.cache.getPtr(fingerprint)) |session| { + const now = std.time.Instant.now() catch return null; + const since = now.since(session.age); + + if (since > config.session_expires_after) { + std.debug.print("here\n", .{}); + session.deinit(storage.allocator); + _ = self.cache.remove(fingerprint); + return null; + } + + return session; + } + + return null; +} diff --git a/src/storage/session-manager/session.zig b/src/storage/session-manager/session.zig new file mode 100644 index 0000000..943334b --- /dev/null +++ b/src/storage/session-manager/session.zig @@ -0,0 +1,34 @@ +const std = @import("std"); +const User = @import("../user.zig"); + +const Self = @This(); + +const fingerprint_size = 512; + +age: std.time.Instant, +info: User.Info, +fingerprint: []u8, + +pub fn init(allocator: std.mem.Allocator, info: User.Info) !Self { + var self: Self = undefined; + self.info = try info.clone(allocator); + self.fingerprint = try allocator.alloc(u8, fingerprint_size); + try self.reset(); + + return self; +} + +pub fn reset(self: *Self) !void { + var raw_buffer: [fingerprint_size / 2]u8 = undefined; + std.crypto.random.bytes(&raw_buffer); + + var writer = std.Io.Writer.fixed(self.fingerprint); + writer.print("{x}", .{raw_buffer}) catch unreachable; + + self.age = try std.time.Instant.now(); +} + +pub fn deinit(self: *const Self, allocator: std.mem.Allocator) void { + self.info.deinit(allocator); + allocator.free(self.fingerprint); +} |