generated from egmont11/ASP.Net-Core-MVC-Template
207 lines
5.8 KiB
C#
207 lines
5.8 KiB
C#
using System.Security.Claims;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Eshop.Application.Auth;
|
|
using Eshop.Web.ViewModels;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace Eshop.Web.Controllers;
|
|
|
|
public class AuthController : Controller
|
|
{
|
|
private readonly ILogger<AuthController> _logger;
|
|
private readonly IAuthenticationService _authenticationService;
|
|
private readonly IUserAccountService _userAccountService;
|
|
|
|
public AuthController(
|
|
ILogger<AuthController> logger,
|
|
IAuthenticationService authenticationService,
|
|
IUserAccountService userAccountService)
|
|
{
|
|
_logger = logger;
|
|
_authenticationService = authenticationService;
|
|
_userAccountService = userAccountService;
|
|
}
|
|
|
|
#region HttpGet
|
|
|
|
[HttpGet]
|
|
[AllowAnonymous]
|
|
public IActionResult Login(string? returnUrl)
|
|
{
|
|
if (User.Identity?.IsAuthenticated == true)
|
|
return RedirectToAction("Index", "Home");
|
|
|
|
return View(new AuthLoginViewModel { ReturnUrl = returnUrl });
|
|
}
|
|
|
|
[HttpGet]
|
|
[AllowAnonymous]
|
|
public IActionResult Register(string? returnUrl)
|
|
{
|
|
if (User.Identity?.IsAuthenticated == true)
|
|
return RedirectToAction("Index", "Home");
|
|
|
|
return View(new AuthRegisterViewModel { ReturnUrl = returnUrl });
|
|
}
|
|
|
|
[HttpGet]
|
|
public IActionResult AccessDenied() => View();
|
|
|
|
[HttpGet]
|
|
[Authorize]
|
|
public async Task<IActionResult> Profile()
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
if (userId is null) return RedirectToAction("Login");
|
|
|
|
var profile = await _userAccountService.GetProfileAsync(userId);
|
|
if (profile is null) return RedirectToAction("Login");
|
|
|
|
return View(new ProfileViewModel
|
|
{
|
|
UserName = profile.UserName,
|
|
Email = profile.Email,
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region HttpPost
|
|
|
|
[HttpPost]
|
|
[AllowAnonymous]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Login(AuthLoginViewModel model)
|
|
{
|
|
if (!ModelState.IsValid) return View(model);
|
|
|
|
var result = await _authenticationService.SignInAsync(
|
|
model.EmailOrUsername, model.Password, model.RememberMe);
|
|
|
|
if (!result.Succeeded)
|
|
{
|
|
ModelState.AddModelError(string.Empty, "Invalid credentials.");
|
|
return View(model);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl))
|
|
return Redirect(model.ReturnUrl);
|
|
|
|
return RedirectToAction("Index", "Home");
|
|
}
|
|
|
|
[HttpPost]
|
|
[AllowAnonymous]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Register(AuthRegisterViewModel model)
|
|
{
|
|
if (!ModelState.IsValid) return View(model);
|
|
|
|
var result = await _userAccountService.RegisterAsync(
|
|
model.UserName, model.Email, model.Password);
|
|
|
|
if (!result.Success)
|
|
{
|
|
foreach (var error in result.Errors)
|
|
ModelState.AddModelError(string.Empty, error);
|
|
return View(model);
|
|
}
|
|
|
|
_logger.LogInformation("User {UserName} registered.", model.UserName);
|
|
|
|
if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl))
|
|
return Redirect(model.ReturnUrl);
|
|
|
|
return RedirectToAction("Login");
|
|
}
|
|
|
|
[HttpPost]
|
|
[Authorize]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Profile(ProfileViewModel model)
|
|
{
|
|
if (!ModelState.IsValid) return View(model);
|
|
|
|
var userId = GetCurrentUserId();
|
|
if (userId is null) return RedirectToAction("Login");
|
|
|
|
var result = await _userAccountService.UpdateProfileAsync(
|
|
userId,
|
|
new UpdateProfileRequest(
|
|
model.UserName,
|
|
model.Email,
|
|
model.CurrentPassword,
|
|
model.NewPassword));
|
|
|
|
if (!result.Success)
|
|
{
|
|
foreach (var error in result.Errors)
|
|
ModelState.AddModelError(string.Empty, error);
|
|
return View(model);
|
|
}
|
|
|
|
TempData["SuccessMessage"] = "Profile updated successfully.";
|
|
return RedirectToAction("Profile");
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Logout()
|
|
{
|
|
await _authenticationService.SignOutAsync();
|
|
return RedirectToAction("Index", "Home");
|
|
}
|
|
|
|
[HttpPost]
|
|
[Authorize]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> DeleteAccount()
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
if (userId is null) return RedirectToAction("Login");
|
|
|
|
var result = await _userAccountService.DeleteAccountAsync(userId);
|
|
if (!result.Success)
|
|
{
|
|
foreach (var error in result.Errors)
|
|
ModelState.AddModelError(string.Empty, error);
|
|
return RedirectToAction("Profile");
|
|
}
|
|
|
|
_logger.LogInformation("User {UserId} deleted their account.", userId);
|
|
return RedirectToAction("Register");
|
|
}
|
|
|
|
[HttpGet]
|
|
[Authorize]
|
|
public async Task<IActionResult> DownloadData()
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
if (userId is null) return RedirectToAction("Login");
|
|
|
|
var data = await _userAccountService.ExportUserDataAsync(userId);
|
|
if (data is null) return RedirectToAction("Login");
|
|
|
|
var export = new
|
|
{
|
|
data.Id,
|
|
data.UserName,
|
|
data.Email,
|
|
Roles = data.Roles,
|
|
data.ExportDate,
|
|
};
|
|
|
|
var json = JsonSerializer.Serialize(export, new JsonSerializerOptions { WriteIndented = true });
|
|
var bytes = Encoding.UTF8.GetBytes(json);
|
|
|
|
return File(bytes, "application/json", $"user_data_{data.UserName}.json");
|
|
}
|
|
|
|
#endregion
|
|
|
|
private string? GetCurrentUserId() =>
|
|
User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
}
|