From a7b1361048202ea3e32a418ac417934db67fff96 Mon Sep 17 00:00:00 2001 From: jaina heartles Date: Sun, 24 Jul 2022 17:04:44 -0700 Subject: [PATCH] Verify incoming tokens --- src/main/api.zig | 22 ++++++++++++++++------ src/main/controllers.zig | 2 ++ src/main/db.zig | 34 ---------------------------------- 3 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/main/api.zig b/src/main/api.zig index 2e240db..c8de686 100644 --- a/src/main/api.zig +++ b/src/main/api.zig @@ -13,7 +13,7 @@ const pw_hash_encoding = .phc; const pw_hash_buf_size = 128; const token_len = 20; -const token_str_len = std.base64.standard.count(token_len); +const token_str_len = std.base64.standard.Encoder.calcSize(token_len); // Frees an api struct and its fields allocated from alloc pub fn free(alloc: std.mem.Allocator, val: anytype) void { @@ -98,11 +98,18 @@ pub const ApiServer = struct { } pub fn makeApiContext(self: *ApiServer, token: []const u8, alloc: std.mem.Allocator) !ApiContext { - if (token.len == 0) return error.InvalidToken; + const decoded_len = std.base64.standard.Decoder.calcSizeForSlice(token) catch return error.InvalidToken; + if (decoded_len != token_len) return error.InvalidToken; - const username = token; + var decoded: [token_len]u8 = undefined; + std.base64.standard.Decoder.decode(&decoded, token) catch return error.InvalidToken; - const user = (try self.db.getBy(models.LocalUser, .username, username, alloc)) orelse return error.InvalidToken; + var hash: models.ByteArray(models.Token.hash_len) = undefined; + models.Token.HashFn.hash(&decoded, &hash.data, .{}); + + const db_token = (try self.db.getBy(models.Token, .hash, hash, alloc)) orelse return error.InvalidToken; + + const user = (try self.db.getBy(models.LocalUser, .id, db_token.user_id, alloc)) orelse return error.InvalidToken; return ApiContext{ .user_context = .{ @@ -170,7 +177,7 @@ pub const ApiServer = struct { const LoginResult = struct { user_id: Uuid, - token: [token_len]u8, + token: [token_str_len]u8, issued_at: DateTime, }; pub fn login(self: *ApiServer, username: []const u8, password: []const u8, alloc: std.mem.Allocator) !LoginResult { @@ -186,9 +193,12 @@ pub const ApiServer = struct { const token = try self.createToken(user_info); + var token_enc: [token_str_len]u8 = undefined; + _ = std.base64.standard.Encoder.encode(&token_enc, &token.value); + return LoginResult{ .user_id = user_info.id, - .token = token.value, + .token = token_enc, .issued_at = token.info.issued_at, }; //return (try self.db.getBy(models.Actor, .id, user_info.actor_id.?, alloc)) orelse unreachable; diff --git a/src/main/controllers.zig b/src/main/controllers.zig index a3b4489..7a4e714 100644 --- a/src/main/controllers.zig +++ b/src/main/controllers.zig @@ -15,11 +15,13 @@ pub const utils = struct { .indent = .{ .Space = 2 }, .separator = true, }, + .string = .{ .String = .{} }, } else .{ .whitespace = .{ .indent = .None, .separator = false, }, + .string = .{ .String = .{} }, }; // Responds to a request with a json value diff --git a/src/main/db.zig b/src/main/db.zig index 6ae429b..ee0d7ae 100644 --- a/src/main/db.zig +++ b/src/main/db.zig @@ -8,40 +8,6 @@ const DateTime = util.DateTime; const String = []const u8; const comptimePrint = std.fmt.comptimePrint; -pub fn ByteArray(comptime n: usize) type { - return struct { - const Self = @This(); - - data: [n]u8, - - pub fn bindToSql(self: Self, stmt: sql.PreparedStmt, idx: u15) !void { - return stmt.bindBlob(idx, &self.data); - } - - pub fn getFromSql(row: sql.Row, idx: u15, _: std.mem.Alloc) !Self { - var self: Self = undefined; - _ = try row.getBlob(idx, &self.data); - return self; - } - }; -} - -pub const ByteSlice = struct { - const Self = @This(); - - data: []const u8, - - pub fn bindToSql(self: Self, stmt: sql.PreparedStmt, idx: u15) !void { - return stmt.bindBlob(idx, self.data); - } - - pub fn getFromSql(row: sql.Row, idx: u15, alloc: std.mem.Alloc) !void { - return Self{ - .data = try row.getBlobAlloc(idx, alloc), - }; - } -}; - fn tableName(comptime T: type) String { return switch (T) { models.Note => "note",