summaryrefslogtreecommitdiff
path: root/backend/src/Database/UserAccessLayer.zig
blob: fd5bf5ae34cf728a44b777145ba3a6bf4b9d5c87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// You are not supposed to include this file. To access this you should use
// Connection.Users. 

const conn = @import("Connection.zig");
const std = @import("std");
const pg = @import("pg");
const model = @import("../Models/User.zig");
const pwd = @import("../Authentication/Password.zig");

pub fn Create(NewUser: *model.User) !void {
    if (try ExistsByUsername(NewUser.Username)) 
        return conn.ResultErrors.AlreadyExists;
    const query = 
        \\ INSERT INTO Users
        \\ (Username, PasswordHash, Role)
        \\ VALUES
        \\ ($1, $2, $3)
        ;
    
    _ = try conn.pool.exec(query, .{
        NewUser.Username,
        NewUser.PasswordHash,
        model.Role.ToString(NewUser.Role),
    });
}

pub fn GetByCredentials(allocator: std.mem.Allocator, username: []const u8, passwordHash: []const u8) !model.User {
    const query = 
        \\ SELECT * FROM Users WHERE
        \\ Username = $1
        ;
    var row = try conn.pool.row(query, .{ username }) orelse {
        return conn.ResultErrors.NotFound;
    };

    const outp = try model.User.MapWithAllocator(allocator, &row.row);
    try row.deinit();

    if (!pwd.CheckPasswordHash(outp.PasswordHash, passwordHash)) {
        return conn.ResultErrors.NotFound;
    }

    return outp;
}

pub fn ExistsByUsername(username: []const u8) !bool {
    const query = "SELECT Id FROM Users WHERE Username = $1";
    var row = try conn.pool.row(query, .{username}) orelse {
        return false;
    };
    try row.deinit();
    return true;
}