diff options
| -rw-r--r-- | backend/Makefile | 5 | ||||
| -rw-r--r-- | backend/src/API/AuthenticationAPI.zig | 24 | ||||
| -rw-r--r-- | backend/src/Database/UserAccessLayer.zig | 13 | ||||
| -rw-r--r-- | backend/src/Models/User.zig | 2 |
4 files changed, 39 insertions, 5 deletions
diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000..5d8bdb4 --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,5 @@ +all: + zig build test && zig build run + +test: + zig build test diff --git a/backend/src/API/AuthenticationAPI.zig b/backend/src/API/AuthenticationAPI.zig index 23a979f..af3a975 100644 --- a/backend/src/API/AuthenticationAPI.zig +++ b/backend/src/API/AuthenticationAPI.zig @@ -7,6 +7,7 @@ const Handler = @import("../Handler.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, .{}); + router.post("/auth/login", login, .{}); } fn register(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !void { @@ -28,3 +29,26 @@ fn register(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !voi }; res.setStatus(.created); } + +fn login(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !void { + const body = try req.json(model.RequestBody) orelse { + res.setStatus(.bad_request); + return; + }; + + const username = body.Username; + const pwd = body.Password; + + _ = db.Users.GetByCredentials(req.arena, username, pwd) catch |err| { + if (err == db.ResultErrors.NotFound) { + res.setStatus(.unauthorized); + try res.json(errDesc.ErrorDescriptor { + .Message = "Login or password is incorrect" + }, .{}); + return; + } + return err; + }; + + // TODO: add token here +} diff --git a/backend/src/Database/UserAccessLayer.zig b/backend/src/Database/UserAccessLayer.zig index 46692ad..fd5bf5a 100644 --- a/backend/src/Database/UserAccessLayer.zig +++ b/backend/src/Database/UserAccessLayer.zig @@ -5,7 +5,7 @@ const conn = @import("Connection.zig"); const std = @import("std"); const pg = @import("pg"); const model = @import("../Models/User.zig"); - +const pwd = @import("../Authentication/Password.zig"); pub fn Create(NewUser: *model.User) !void { if (try ExistsByUsername(NewUser.Username)) @@ -27,14 +27,19 @@ pub fn Create(NewUser: *model.User) !void { pub fn GetByCredentials(allocator: std.mem.Allocator, username: []const u8, passwordHash: []const u8) !model.User { const query = \\ SELECT * FROM Users WHERE - \\ Username = $1 AND PasswordHash = $2 + \\ Username = $1 ; - var row = try conn.pool.row(query, .{ username, passwordHash }) orelse { + var row = try conn.pool.row(query, .{ username }) orelse { return conn.ResultErrors.NotFound; }; - const outp = try model.User.MapWithAllocator(allocator, row.row); + const outp = try model.User.MapWithAllocator(allocator, &row.row); try row.deinit(); + + if (!pwd.CheckPasswordHash(outp.PasswordHash, passwordHash)) { + return conn.ResultErrors.NotFound; + } + return outp; } diff --git a/backend/src/Models/User.zig b/backend/src/Models/User.zig index 79015d0..a52186d 100644 --- a/backend/src/Models/User.zig +++ b/backend/src/Models/User.zig @@ -50,7 +50,7 @@ pub const User = struct { // Parses the db row and returns the result. You are expected to use the // actual DB schema and use * as a fields selector pub fn MapWithAllocator(allocator: std.mem.Allocator, row: *const pg.Row) !User { - const role_record = try allocator.dupe(u8, row.get([]const u8, 3)); + const role_record = try allocator.dupe(u8, try row.get([]const u8, 3)); return User { .Id = try allocator.dupe(u8, try row.get([]const u8, 0)), |
