diff options
Diffstat (limited to 'backend/src')
| -rw-r--r-- | backend/src/API/AuthenticationAPI.zig | 30 | ||||
| -rw-r--r-- | backend/src/API/ErrorDescription.zig | 4 | ||||
| -rw-r--r-- | backend/src/API/WeaponsAPI.zig | 4 | ||||
| -rw-r--r-- | backend/src/Database/Connection.zig | 1 | ||||
| -rw-r--r-- | backend/src/Database/UserAccessLayer.zig | 48 | ||||
| -rw-r--r-- | backend/src/Handler.zig | 2 | ||||
| -rw-r--r-- | backend/src/main.zig | 1 |
7 files changed, 87 insertions, 3 deletions
diff --git a/backend/src/API/AuthenticationAPI.zig b/backend/src/API/AuthenticationAPI.zig new file mode 100644 index 0000000..23a979f --- /dev/null +++ b/backend/src/API/AuthenticationAPI.zig @@ -0,0 +1,30 @@ +const std = @import("std"); +const httpz = @import("httpz"); +const model = @import("../Models/User.zig"); +const db = @import("../Database/Connection.zig"); +const errDesc = @import("ErrorDescription.zig"); +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, .{}); +} + +fn register(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !void { + var body = try req.json(model.RequestBody) orelse { + res.setStatus(.bad_request); + return; + }; + + var body_model = try body.ToModel(req.arena); + + db.Users.Create(&body_model) catch |err| { + if (err == db.ResultErrors.AlreadyExists) { + res.setStatus(.bad_request); + try res.json(errDesc.AlreadyExistsDescriptor, .{}); + return; + } + res.setStatus(.internal_server_error); + return; + }; + res.setStatus(.created); +} diff --git a/backend/src/API/ErrorDescription.zig b/backend/src/API/ErrorDescription.zig index 76f420a..2c3f338 100644 --- a/backend/src/API/ErrorDescription.zig +++ b/backend/src/API/ErrorDescription.zig @@ -5,3 +5,7 @@ pub const ErrorDescriptor = struct { pub const NotFoundDescriptor = ErrorDescriptor { .Message = "The requested object was not found" }; + +pub const AlreadyExistsDescriptor = ErrorDescriptor { + .Message = "The object already exists in the database" +}; diff --git a/backend/src/API/WeaponsAPI.zig b/backend/src/API/WeaponsAPI.zig index 75cd6e8..901bbb0 100644 --- a/backend/src/API/WeaponsAPI.zig +++ b/backend/src/API/WeaponsAPI.zig @@ -62,12 +62,12 @@ fn newRangedWeapon(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Respons fn updateRangedWeapon(_: *Handler.Handler, req: *httpz.Request, res: *httpz.Response) !void { const id = req.param("id") orelse { - res.setStatus(.no_content); + res.setStatus(.bad_request); return; }; var body = try req.json(model.RequestBody) orelse { - res.setStatus(.no_content); + res.setStatus(.bad_request); return; }; diff --git a/backend/src/Database/Connection.zig b/backend/src/Database/Connection.zig index e08760c..0114cba 100644 --- a/backend/src/Database/Connection.zig +++ b/backend/src/Database/Connection.zig @@ -32,4 +32,5 @@ pub fn Disconnect() void { pool.deinit(); } +pub const Users = @import("UserAccessLayer.zig"); pub const RangedWeapons = @import("RangedWeaponsAccessLayer.zig"); diff --git a/backend/src/Database/UserAccessLayer.zig b/backend/src/Database/UserAccessLayer.zig new file mode 100644 index 0000000..46692ad --- /dev/null +++ b/backend/src/Database/UserAccessLayer.zig @@ -0,0 +1,48 @@ +// You are not supposed to include this file. To access this you should use +// Connection.Users. + +const conn = @import("Connection.zig"); +const std = @import("std"); +const pg = @import("pg"); +const model = @import("../Models/User.zig"); + + +pub fn Create(NewUser: *model.User) !void { + if (try ExistsByUsername(NewUser.Username)) + return conn.ResultErrors.AlreadyExists; + const query = + \\ INSERT INTO Users + \\ (Username, PasswordHash, Role) + \\ VALUES + \\ ($1, $2, $3) + ; + + _ = try conn.pool.exec(query, .{ + NewUser.Username, + NewUser.PasswordHash, + model.Role.ToString(NewUser.Role), + }); +} + +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 + ; + var row = try conn.pool.row(query, .{ username, passwordHash }) orelse { + return conn.ResultErrors.NotFound; + }; + + const outp = try model.User.MapWithAllocator(allocator, row.row); + try row.deinit(); + return outp; +} + +pub fn ExistsByUsername(username: []const u8) !bool { + const query = "SELECT Id FROM Users WHERE Username = $1"; + var row = try conn.pool.row(query, .{username}) orelse { + return false; + }; + try row.deinit(); + return true; +} diff --git a/backend/src/Handler.zig b/backend/src/Handler.zig index 0cee922..010dd0e 100644 --- a/backend/src/Handler.zig +++ b/backend/src/Handler.zig @@ -4,6 +4,6 @@ const httpz = @import("httpz"); pub const Handler = struct { pub fn dispatch(self: *Handler, action: httpz.Action(*Handler), req: *httpz.Request, res: *httpz.Response) !void { try action(self, req, res); - std.debug.print("{any} {s}\n", .{req.method, req.url.raw}); + std.debug.print("{any} {s}: {d}\n", .{req.method, req.url.raw, res.status}); } }; diff --git a/backend/src/main.zig b/backend/src/main.zig index 6ed630f..db48a38 100644 --- a/backend/src/main.zig +++ b/backend/src/main.zig @@ -24,6 +24,7 @@ pub fn main() !void { router.get("/", index, .{}); @import("API/WeaponsAPI.zig").RegisterEndpoints(router); + @import("API/AuthenticationAPI.zig").RegisterEndpoints(router); // PSQL connection try db.Connect(allocator); |
