This commit is contained in:
Bob Farrell 2024-11-08 20:42:54 +00:00
parent 6f8de03f07
commit 4210aa5e83
5 changed files with 64 additions and 4 deletions

View File

@ -17,8 +17,8 @@
.path = "../jetquery",
},
.jetcommon = .{
.url = "https://github.com/jetzig-framework/jetcommon/archive/5946df967d3cf2f843035464a6b8a17cb573afd3.tar.gz",
.hash = "12206a50c39a1766d24abcaa9f8fbeaaa20c853f987c667e0b8325e53d9c7ede7d24",
.url = "https://github.com/jetzig-framework/jetcommon/archive/a248776ba56d6cc2b160d593ac3305756adcd26e.tar.gz",
.hash = "1220a61e8650f84b28baf31fae5da31712aec4b711b3a41d11ed07c908bac96648d8",
},
.args = .{
.url = "https://github.com/ikskuh/zig-args/archive/0abdd6947a70e6d8cc83b66228cea614aa856206.tar.gz",

View File

@ -4,6 +4,10 @@ const jetzig = @import("../jetzig.zig");
pub const IdType = enum { string, integer };
pub const AuthOptions = struct {
user_model: []const u8,
};
pub fn getUserId(comptime id_type: IdType, request: *jetzig.Request) !?switch (id_type) {
.integer => i128,
.string => []const u8,

View File

@ -151,11 +151,15 @@ pub const smtp: mail.SMTPConfig = .{
};
/// HTTP cookie configuration
pub const cookie_options: http.Cookies.CookieOptions = .{
pub const cookies: http.Cookies.CookieOptions = .{
.domain = "localhost",
.path = "/",
};
pub const auth: @import("auth.zig").AuthOptions = .{
.user_model = "User",
};
/// Force email delivery in development mode (instead of printing email body to logger).
pub const force_development_email_delivery = false;

View File

@ -22,7 +22,7 @@ pub const CookieOptions = struct {
partitioned: bool = false,
};
const cookie_options = jetzig.config.get(CookieOptions, "cookie_options");
const cookie_options = jetzig.config.get(CookieOptions, "cookies");
pub const Cookie = struct {
name: []const u8,

View File

@ -0,0 +1,52 @@
const std = @import("std");
const jetzig = @import("jetzig");
pub const middleware_name = "auth";
// Default model is `.User`.
const user_model = jetzig.config.get(jetzig.auth.AuthOptions, "auth").user_model;
/// Define any custom data fields you want to store here. Assigning to these fields in the `init`
/// function allows you to access them in the `beforeRequest` and `afterRequest` functions, where
/// they can also be modified.
user: ?@TypeOf(jetzig.database.Query(user_model).find(0)).ResultType(),
const Self = @This();
/// Initialize middleware.
pub fn init(request: *jetzig.http.Request) !*Self {
const middleware = try request.allocator.create(Self);
middleware.* = .{ .user = null };
return middleware;
}
const map = std.StaticStringMap(void).initComptime(.{
.{ ".html", void },
.{ ".json", void },
});
/// For HTML/JSON requests, fetch a user ID from the encrypted session cookie and execute a
/// database query to match the user ID to a database record. Expects a `User` model defined in
/// the schema, configurable with `auth.user_model`.
///
/// User ID is accessible from a request:
/// ```zig
///
pub fn afterRequest(self: *Self, request: *jetzig.http.Request) !void {
if (request.path.extension) |extension| {
if (map.get(extension) == null) return;
}
const user_id = try jetzig.auth.getUserId(.integer, request) orelse return;
const query = jetzig.database.Query(user_model).find(user_id);
if (try request.repo.execute(query)) |user| {
self.user = user;
}
}
/// Invoked after `afterRequest` is called, use this function to do any clean-up.
/// Note that `request.allocator` is an arena allocator, so any allocations are automatically
/// done before the next request starts processing.
pub fn deinit(self: *Self, request: *jetzig.http.Request) void {
request.allocator.destroy(self);
}