aboutsummaryrefslogtreecommitdiffstats
path: root/src/web/dispatcher.zig
blob: 77ea2823e77cb30f2220925145da5fa114c5e154 (plain) (blame)
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
pub const Dispatcher = struct {
    app: *App,
    // whether to try loading the user or not, this implies requires_user = false
    load_user: bool = true,

    // whether a user is required. When false, if we have a token, the user is still
    // loaded (unless load_user = false).
    requires_user: bool = false,

    pub fn dispatch(self: *const Dispatcher, action: httpz.Action(*Env), req: *httpz.Request, res: *httpz.Response) !void {
        const app = self.app;

        var env = Env{
            .app = app,
        };
        // defer env.deinit();
        //
        try self.doDispatch(action, req, res, &env);
    }

    fn doDispatch(_: *const Dispatcher, action: httpz.Action(*Env), req: *httpz.Request, res: *httpz.Response, env: *Env) !void {
        const query = try req.query();
        const user = try loadUser(env.app, query.get("user"));

        if (user) |u| {
            env.user = u;
            std.debug.print("user: {}, {s}\n", .{ u.id, u.username });
        }
        try action(env, req, res);
    }
};

fn loadUser(app: *App, optional_session_id: ?[]const u8) !?User {
    const session_id = optional_session_id orelse return null;

    var user: User = undefined;
    const row = try app.pool.row("SELECT user_id, username FROM users WHERE user_id = $1", .{session_id});
    if (row) |r| {
        user = try r.to(User, .{});
    } else {
        return null;
    }

    return try User.init(app.allocator, user.id, user.username);
}

const httpz = @import("httpz");
const std = @import("std");

const App = @import("../app.zig").App;
const User = @import("../User.zig");
const Env = @import("../env.zig").Env;