Verify incoming tokens
This commit is contained in:
parent
b05abf95ac
commit
a7b1361048
3 changed files with 18 additions and 40 deletions
|
@ -13,7 +13,7 @@ const pw_hash_encoding = .phc;
|
||||||
const pw_hash_buf_size = 128;
|
const pw_hash_buf_size = 128;
|
||||||
|
|
||||||
const token_len = 20;
|
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
|
// Frees an api struct and its fields allocated from alloc
|
||||||
pub fn free(alloc: std.mem.Allocator, val: anytype) void {
|
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 {
|
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{
|
return ApiContext{
|
||||||
.user_context = .{
|
.user_context = .{
|
||||||
|
@ -170,7 +177,7 @@ pub const ApiServer = struct {
|
||||||
|
|
||||||
const LoginResult = struct {
|
const LoginResult = struct {
|
||||||
user_id: Uuid,
|
user_id: Uuid,
|
||||||
token: [token_len]u8,
|
token: [token_str_len]u8,
|
||||||
issued_at: DateTime,
|
issued_at: DateTime,
|
||||||
};
|
};
|
||||||
pub fn login(self: *ApiServer, username: []const u8, password: []const u8, alloc: std.mem.Allocator) !LoginResult {
|
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);
|
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{
|
return LoginResult{
|
||||||
.user_id = user_info.id,
|
.user_id = user_info.id,
|
||||||
.token = token.value,
|
.token = token_enc,
|
||||||
.issued_at = token.info.issued_at,
|
.issued_at = token.info.issued_at,
|
||||||
};
|
};
|
||||||
//return (try self.db.getBy(models.Actor, .id, user_info.actor_id.?, alloc)) orelse unreachable;
|
//return (try self.db.getBy(models.Actor, .id, user_info.actor_id.?, alloc)) orelse unreachable;
|
||||||
|
|
|
@ -15,11 +15,13 @@ pub const utils = struct {
|
||||||
.indent = .{ .Space = 2 },
|
.indent = .{ .Space = 2 },
|
||||||
.separator = true,
|
.separator = true,
|
||||||
},
|
},
|
||||||
|
.string = .{ .String = .{} },
|
||||||
} else .{
|
} else .{
|
||||||
.whitespace = .{
|
.whitespace = .{
|
||||||
.indent = .None,
|
.indent = .None,
|
||||||
.separator = false,
|
.separator = false,
|
||||||
},
|
},
|
||||||
|
.string = .{ .String = .{} },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Responds to a request with a json value
|
// Responds to a request with a json value
|
||||||
|
|
|
@ -8,40 +8,6 @@ const DateTime = util.DateTime;
|
||||||
const String = []const u8;
|
const String = []const u8;
|
||||||
const comptimePrint = std.fmt.comptimePrint;
|
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 {
|
fn tableName(comptime T: type) String {
|
||||||
return switch (T) {
|
return switch (T) {
|
||||||
models.Note => "note",
|
models.Note => "note",
|
||||||
|
|
Loading…
Reference in a new issue