aboutsummaryrefslogtreecommitdiff
path: root/src/storage/user.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/storage/user.zig')
-rw-r--r--src/storage/user.zig234
1 files changed, 0 insertions, 234 deletions
diff --git a/src/storage/user.zig b/src/storage/user.zig
deleted file mode 100644
index c2cc82a..0000000
--- a/src/storage/user.zig
+++ /dev/null
@@ -1,234 +0,0 @@
-const std = @import("std");
-const Storage = @import("root.zig");
-
-const log = std.log.scoped(.user);
-
-const Self = @This();
-
-pub const Info = struct {
- name: []const u8,
- full_name: []const u8,
- birthday: []const u8,
- hash: []const u8,
- is_admin: bool,
-
- pub fn clone(self: *const @This(), allocator: std.mem.Allocator) !@This() {
- var clone_self: @This() = undefined;
- var i: usize = 0;
-
- inline for (std.meta.fields(@This())) |field_info| {
- if (field_info.type == []const u8) {
- @field(clone_self, field_info.name) = try allocator.dupe(
- u8,
- @field(self, field_info.name),
- );
- errdefer allocator.free(@field(clone_self, field_info.name));
- } else {
- @field(clone_self, field_info.name) = @field(self, field_info.name);
- }
- i += 1;
- }
-
- return clone_self;
- }
-
- pub fn deinit(self: *const @This(), allocator: std.mem.Allocator) void {
- inline for (std.meta.fields(@This())) |field_info| {
- if (field_info.type == []const u8) {
- allocator.free(@field(self, field_info.name));
- }
- }
- }
-};
-
-dir: std.fs.Dir,
-info: Info,
-arena: std.heap.ArenaAllocator,
-
-pub fn open(
- storage: *Storage,
- name: []const u8,
-) !Self {
- var arena: std.heap.ArenaAllocator = .init(storage.allocator);
- errdefer arena.deinit();
- const allocator = arena.allocator();
-
- var user_dir = try storage.dir.openDir("user", .{});
- defer user_dir.close();
-
- var dir = try user_dir.openDir(name, .{});
- errdefer dir.close();
-
- const file = try dir.openFile("info.json", .{ .lock = .shared });
- defer file.close();
- const content = try file.readToEndAlloc(allocator, std.math.maxInt(usize));
-
- const info = try std.json.parseFromSliceLeaky(Info, allocator, content, .{});
-
- return .{
- .dir = dir,
- .arena = arena,
- .info = info,
- };
-}
-
-pub fn new(
- storage: *Storage,
- name: []const u8,
- full_name: []const u8,
- birthday: []const u8,
- password: []const u8,
- is_admin: bool,
- inner_allocator: std.mem.Allocator
-) !Self {
- var arena: std.heap.ArenaAllocator = .init(inner_allocator);
- const allocator = arena.allocator();
- errdefer arena.deinit();
-
- var user_dir = try storage.dir.openDir("user", .{});
- defer user_dir.close();
-
- try user_dir.makeDir(name);
- var dir = try user_dir.openDir(name, .{});
- errdefer dir.close();
-
- var file = try dir.createFile("info.json", .{ .lock = .exclusive });
- file.close();
-
- const hash_buf = try allocator.alloc(u8, 256);
- const hash = try std.crypto.pwhash.bcrypt.strHash(
- password,
- .{
- .params = .{
- .rounds_log = 3,
- .silently_truncate_password = false,
- },
- .encoding = .phc,
- },
- hash_buf
- );
-
- const info: Info = .{
- .name = name,
- .full_name = full_name,
- .birthday = birthday,
- .hash = hash,
- .is_admin = is_admin,
- };
-
-
- return .{
- .dir = dir,
- .arena = arena,
- .info = info,
- };
-}
-
-pub fn set_password(self: *Self, password: []const u8) !void {
- const allocator = self.arena.allocator();
- const hash_buf = try allocator.alloc(u8, 256);
- const hash = try std.crypto.pwhash.bcrypt.strHash(
- password,
- .{
- .params = .{
- .rounds_log = 3,
- .silently_truncate_password = false,
- },
- .encoding = .phc,
- },
- hash_buf
- );
-
- self.info.hash = hash;
-}
-
-pub fn sync(self: *Self) !void {
- const file = try self.dir.createFile("info.json", .{
- .lock = .exclusive,
- });
- defer file.close();
-
- var buffer: [1024]u8 = undefined;
- var writer = file.writer(&buffer);
-
- var stringify = std.json.Stringify {
- .writer = &writer.interface,
- .options = .{ .whitespace = .indent_2 }
- };
-
- try stringify.write(self.info);
- try writer.interface.flush();
-}
-
-pub fn check_password(self: *Self, password: []const u8) bool {
- std.crypto.pwhash.bcrypt.strVerify(self.info.hash, password, .{
- .silently_truncate_password = false,
- }) catch return false;
- return true;
-}
-
-pub fn deinit(self: *Self) void {
- self.dir.close();
- self.arena.deinit();
- self.* = undefined;
-}
-
-pub fn exists(storage: *Storage, name: []const u8) bool {
- var user = storage.dir.openDir("user", .{}) catch return false;
- defer user.close();
-
- user.access(name, .{}) catch return false;
- return true;
-}
-
-pub fn image(storage: *Storage, name: []const u8) ?std.fs.File {
- var user = storage.dir.openDir("user", .{}) catch return null;
- defer user.close();
-
- var profile = user.openDir(name, .{}) catch return null;
- defer profile.close();
- return profile.openFile("image.jpg", .{ .lock = .shared }) catch null;
-}
-
-pub fn set_image(
- storage: *Storage,
- name: []const u8,
- reader: *std.Io.Reader,
- size: usize,
-) !void {
- var user = try storage.dir.openDir("user", .{});
- defer user.close();
-
- var profile = try user.openDir(name, .{});
- defer profile.close();
-
- var image_file = try profile.createFile("image.jpg", .{ .lock = .exclusive });
- defer image_file.close();
-
- var buffer: [1024]u8 = undefined;
- var file_writer = image_file.writer(&buffer);
-
- log.info("uploaded to profile {s} [{} bytes]", .{ name, size });
-
- try reader.streamExact(&file_writer.interface, size);
-
- try file_writer.interface.flush();
-}
-
-pub fn list(
- storage: *Storage,
- allocator: std.mem.Allocator,
-) ![][]const u8 {
- var user = try storage.dir.openDir("user", .{ .iterate = true });
- defer user.close();
-
- var ids: std.ArrayList([]const u8) = .empty;
-
- var iterator = user.iterate();
-
- while (try iterator.next()) |entry| {
- try ids.append(allocator, try allocator.dupe(u8, entry.name));
- }
-
- return ids.toOwnedSlice(allocator);
-}