Kavita/API/Controllers/AccountController.cs
2020-12-12 20:14:56 -06:00

82 lines
2.6 KiB
C#

using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using API.Data;
using API.DTOs;
using API.Entities;
using API.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace API.Controllers
{
public class AccountController : BaseApiController
{
private readonly DataContext _context;
private readonly ITokenService _tokenService;
private readonly ILogger<AccountController> _logger;
public AccountController(DataContext context, ITokenService tokenService, ILogger<AccountController> logger)
{
_context = context;
_tokenService = tokenService;
_logger = logger;
}
[HttpPost("register")]
public async Task<ActionResult<UserDto>> Register(RegisterDto registerDto)
{
_logger.LogInformation("Username: " + registerDto.Password);
if (await UserExists(registerDto.Username))
{
return BadRequest("Username is taken.");
}
using var hmac = new HMACSHA512();
var user = new AppUser
{
UserName = registerDto.Username.ToLower(),
PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(registerDto.Password)),
PasswordSalt = hmac.Key
};
_context.Users.Add(user);
await _context.SaveChangesAsync();
return new UserDto()
{
Username = user.UserName,
Token = _tokenService.CreateToken(user)
};
}
[HttpPost("login")]
public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
{
var user = await _context.Users.SingleOrDefaultAsync(x => x.UserName == loginDto.Username.ToLower());
if (user == null) return Unauthorized("Invalid username");
using var hmac = new HMACSHA512(user.PasswordSalt);
var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(loginDto.Password));
for (int i = 0; i < computedHash.Length; i++)
{
if (computedHash[i] != user.PasswordHash[i]) return Unauthorized("Invalid password");
}
return new UserDto()
{
Username = user.UserName,
Token = _tokenService.CreateToken(user)
};
}
private async Task<bool> UserExists(string username)
{
return await _context.Users.AnyAsync(user => user.UserName == username.ToLower());
}
}
}