summaryrefslogtreecommitdiff
path: root/backend/src
diff options
context:
space:
mode:
Diffstat (limited to 'backend/src')
-rw-r--r--backend/src/API/AuthenticationAPI.zig6
-rw-r--r--backend/src/Authentication/Tokens.zig42
-rw-r--r--backend/src/Redis/Connection.zig15
-rw-r--r--backend/src/main.zig3
4 files changed, 61 insertions, 5 deletions
diff --git a/backend/src/API/AuthenticationAPI.zig b/backend/src/API/AuthenticationAPI.zig
index af3a975..a792e33 100644
--- a/backend/src/API/AuthenticationAPI.zig
+++ b/backend/src/API/AuthenticationAPI.zig
@@ -4,6 +4,7 @@ const model = @import("../Models/User.zig");
const db = @import("../Database/Connection.zig");
const errDesc = @import("ErrorDescription.zig");
const Handler = @import("../Handler.zig");
+const Tokens = @import("../Authentication/Tokens.zig");
pub fn RegisterEndpoints(router: *httpz.Router(*Handler.Handler,*const fn (*Handler.Handler, *httpz.request.Request, *httpz.response.Response) anyerror!void)) void {
router.post("/auth/register", register, .{});
@@ -39,7 +40,7 @@ fn login(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !void {
const username = body.Username;
const pwd = body.Password;
- _ = db.Users.GetByCredentials(req.arena, username, pwd) catch |err| {
+ const user = db.Users.GetByCredentials(req.arena, username, pwd) catch |err| {
if (err == db.ResultErrors.NotFound) {
res.setStatus(.unauthorized);
try res.json(errDesc.ErrorDescriptor {
@@ -50,5 +51,8 @@ fn login(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !void {
return err;
};
+ const token = try Tokens.GenerateNewSession(res.arena, user);
+ try res.json(.{ .Token = token } , .{});
+
// TODO: add token here
}
diff --git a/backend/src/Authentication/Tokens.zig b/backend/src/Authentication/Tokens.zig
new file mode 100644
index 0000000..6548ce7
--- /dev/null
+++ b/backend/src/Authentication/Tokens.zig
@@ -0,0 +1,42 @@
+const std = @import("std");
+const redis = @import("../Redis/Connection.zig");
+const userModel = @import("../Models/User.zig");
+
+const topicName = "cp2020_auth";
+const token_ttl: u16 = 43_200; // 12 hours
+
+var prng: std.Random.DefaultPrng= undefined;
+var rnd: std.Random = undefined;
+
+pub fn Init() !void {
+ // Random enough
+ var seed: u64 = undefined;
+ try std.posix.getrandom(std.mem.asBytes(&seed));
+ prng = std.Random.DefaultPrng.init(seed);
+ rnd = prng.random();
+}
+
+/// Generates a new token in the heap. Expects [64]u8 as an input
+fn generateSessionToken(buf: []u8) []u8 {
+ for (0..64) |i| {
+ buf[i] = std.Random.intRangeAtMost(rnd, u8, 'A', 'z');
+ }
+ return buf;
+}
+
+pub fn GenerateNewSession(allocator: std.mem.Allocator, user: userModel.User) ![]u8 {
+ const token: []u8 = try allocator.alloc(u8, 64);
+ const newToken = generateSessionToken(token);
+
+ // Redis cache
+ var string: std.io.Writer.Allocating = .init(allocator);
+ defer string.deinit();
+ try string.writer.print("{f}", .{std.json.fmt(user, .{})});
+ try redis.WriteToTopic(topicName, redis.Message {
+ .Key = token,
+ .Value = string.written(),
+ .SecondsToLive = token_ttl,
+ });
+
+ return newToken;
+}
diff --git a/backend/src/Redis/Connection.zig b/backend/src/Redis/Connection.zig
index 83adb2c..737d5cb 100644
--- a/backend/src/Redis/Connection.zig
+++ b/backend/src/Redis/Connection.zig
@@ -28,11 +28,15 @@ pub const Message = struct {
};
pub fn WriteToTopic(topic: []const u8, message: Message) !void {
- _ = redis.redisCommand(connection, "SET %s:%s %s EX %d",
- topic.ptr,
- message.Key.ptr,
- message.Value.ptr,
+ const rep = redis.redisCommand(connection, "SET %b:%b %b EX %d",
+ topic.ptr, topic.len,
+ message.Key.ptr, message.Key.len,
+ message.Value.ptr, message.Value.len,
message.SecondsToLive);
+
+ if (rep != null) {
+ redis.freeReplyObject(rep);
+ }
}
pub fn ReadFromTopic(topic: []const u8, Key: []const u8) ?[]const u8 {
@@ -42,6 +46,9 @@ pub fn ReadFromTopic(topic: []const u8, Key: []const u8) ?[]const u8 {
if (raw == null) {
return null;
}
+ defer {
+ redis.freeReplyObject(raw);
+ }
const resp: *redis.redisReply = @alignCast(@ptrCast(raw));
if (resp.type != redis.REDIS_REPLY_STRING) {
return null;
diff --git a/backend/src/main.zig b/backend/src/main.zig
index 6f9b21b..6fa8f56 100644
--- a/backend/src/main.zig
+++ b/backend/src/main.zig
@@ -3,11 +3,14 @@ const backend = @import("backend");
const httpz = @import("httpz");
const db = @import("Database/Connection.zig");
const handler = @import("Handler.zig");
+const tokens = @import("Authentication/Tokens.zig");
const redis = @import("Redis/Connection.zig");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
+
+ try tokens.Init();
// PSQL connection
try db.Connect(allocator);