slik-dispenser/backend/Controllers/UserController.cs

145 lines
3.8 KiB
C#

using Microsoft.AspNetCore.Mvc;
using backend.Application;
using backend.Models;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Identity;
using System.Web;
using backend.Middleware;
using backend.Migrations;
namespace backend.Controllers;
[ApiController]
public class UserController : ControllerBase
{
[HttpPost("Register")]
public IActionResult Register([FromBody] JsonObject input)
{
// Validate
if (String.IsNullOrEmpty(input["username"]?.ToString()) || String.IsNullOrEmpty(input["password"]?.ToString())) {
return BadRequest("Username and password required");
}
if (ApplicationState.DbContext!.Users.FirstOrDefault(user => user.Username == input["username"]!.ToString()) != null) {
return BadRequest("User already exists");
}
// Hash password
var passwordHasher = new PasswordHasher<object>();
string hashedPassword = passwordHasher.HashPassword(null, input["password"]!.ToString());
// Generate touch code
string touchCode = "";
for (int i = 0; i < 4; i++) {
touchCode += (1 + new Random().Next() % 5).ToString();
}
// Create user
var user = new User {
Username = input["username"]!.ToString(),
Password = hashedPassword,
TouchCode = touchCode,
IsParent = false,
};
// Save user
ApplicationState.DbContext!.Add(user);
ApplicationState.DbContext!.SaveChanges();
Console.WriteLine("Created user: " + user.Username);
return Ok();
}
[HttpPost("Login")]
public IActionResult Login([FromBody] JsonObject input)
{
// Validate
if (String.IsNullOrEmpty(input["username"]?.ToString()) || String.IsNullOrEmpty(input["password"]?.ToString())) {
return BadRequest("Username and password required");
}
if (Request.Cookies["session"] != null) {
return BadRequest("You are already logged in");
}
// Get user
var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.Username == input["username"]!.ToString());
if (user == null) {
return BadRequest("Invalid username");
}
// Verify password
var passwordHasher = new PasswordHasher<object>();
if (passwordHasher.VerifyHashedPassword(null, user.Password, input["password"]!.ToString()) == PasswordVerificationResult.Failed) {
return BadRequest("Invalid password");
}
// Create session token if necessary
if (string.IsNullOrEmpty(user.SessionToken)) {
user.SessionToken = Guid.NewGuid().ToString();
ApplicationState.DbContext!.SaveChanges();
}
// Set session cookie
Response.Cookies.Append("session", user.SessionToken);
Console.WriteLine(user.Username + " has logged in");
return Ok();
}
[HttpPost("Logout")]
[MiddlewareFilter(typeof(AuthenticationMiddlewareBuilder))]
public IActionResult LogOut()
{
// Get user
var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.SessionToken == Request.Cookies["session"]!.ToString());
if (user == null) {
return BadRequest("Invalid session token");
}
// Log out
user.SessionToken = null;
ApplicationState.DbContext!.SaveChanges();
Response.Cookies.Delete("session");
return Ok();
}
[HttpGet("UserInfo")]
[MiddlewareFilter(typeof(AuthenticationMiddlewareBuilder))]
public IActionResult UserInfo()
{
// Get user
var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.SessionToken == Request.Cookies["session"]!.ToString());
if (user == null) {
return BadRequest("Invalid session token");
}
var data = new {
username = user.Username,
touchCode = user.TouchCode,
isParent = user.IsParent,
dispenses = user.Dispenses,
};
return new JsonResult(data);
}
[HttpGet("Children")]
[MiddlewareFilter(typeof(ParentMiddlewareBuilder))]
public IActionResult ListChildren()
{
var users = ApplicationState.DbContext!.Users
.Where(user => !user.IsParent)
.Select(user => new {
username = user.Username,
dispenses = user.Dispenses,
});
return new JsonResult(users);
}
}