Ajout de HelloFresh
This commit is contained in:
185
Controllers/AccountController.cs
Normal file
185
Controllers/AccountController.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using administration.Models.Finances;
|
||||
using administration.Models;
|
||||
using User = administration.Models.User;
|
||||
|
||||
public class AccountController : Controller
|
||||
{
|
||||
private readonly LayoutDataContext _db;
|
||||
private readonly IPasswordHasher<User> _hasher;
|
||||
|
||||
public AccountController(LayoutDataContext db, IPasswordHasher<User> hasher)
|
||||
{
|
||||
_db = db;
|
||||
_hasher = hasher;
|
||||
}
|
||||
|
||||
// GET /Account/Login
|
||||
[HttpGet]
|
||||
public IActionResult Login(string? returnUrl = null)
|
||||
{
|
||||
ViewBag.ReturnUrl = returnUrl;
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST /Account/Login
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Login(string username, string password, string? returnUrl = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
ModelState.AddModelError("", "Identifiants requis.");
|
||||
return View();
|
||||
}
|
||||
|
||||
var user = await _db.Users.FirstOrDefaultAsync(u => u.Username == username);
|
||||
if (user == null)
|
||||
{
|
||||
ModelState.AddModelError("", "Identifiants invalides.");
|
||||
return View();
|
||||
}
|
||||
|
||||
var verify = _hasher.VerifyHashedPassword(user, user.PasswordHash, password);
|
||||
if (verify == PasswordVerificationResult.Failed)
|
||||
{
|
||||
ModelState.AddModelError("", "Identifiants invalides.");
|
||||
return View();
|
||||
}
|
||||
|
||||
// Claims pour cookie d’auth
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||
new Claim(ClaimTypes.Name, user.Username)
|
||||
};
|
||||
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
var principal = new ClaimsPrincipal(identity);
|
||||
|
||||
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
|
||||
|
||||
// Compatibilité avec ton code existant
|
||||
HttpContext.Session.SetInt32("UserId", user.Id);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl))
|
||||
return Redirect(returnUrl);
|
||||
|
||||
return RedirectToAction("Index", "Home");
|
||||
}
|
||||
|
||||
// POST /Account/Logout
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Logout()
|
||||
{
|
||||
await HttpContext.SignOutAsync();
|
||||
HttpContext.Session.Clear();
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
// GET /Account/ForgotPassword
|
||||
[HttpGet]
|
||||
public IActionResult ForgotPassword() => View();
|
||||
|
||||
// POST /Account/ForgotPassword
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ForgotPassword(string usernameOrEmail)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(usernameOrEmail))
|
||||
{
|
||||
ModelState.AddModelError("", "Champ requis.");
|
||||
return View();
|
||||
}
|
||||
|
||||
var user = await _db.Users
|
||||
.FirstOrDefaultAsync(u => u.Username == usernameOrEmail);
|
||||
|
||||
// Par sécurité, on ne révèle pas si l’utilisateur existe
|
||||
if (user != null)
|
||||
{
|
||||
// Génère un token simple (tu peux le hasher si tu veux)
|
||||
var token = Convert.ToBase64String(Guid.NewGuid().ToByteArray())
|
||||
.Replace("+", "-").Replace("/", "_").TrimEnd('=');
|
||||
|
||||
user.ResetToken = token;
|
||||
user.ResetTokenExpiresAt = DateTimeOffset.UtcNow.AddHours(1);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
var resetUrl = Url.Action("ResetPassword", "Account", new { token = token }, Request.Scheme);
|
||||
// TODO: envoyer resetUrl par email.
|
||||
// Temporaire : on l’affiche
|
||||
TempData["ResetLink"] = resetUrl;
|
||||
}
|
||||
|
||||
TempData["Info"] = "Si un compte existe, un lien de réinitialisation a été envoyé.";
|
||||
return RedirectToAction("ForgotPassword");
|
||||
}
|
||||
|
||||
// GET /Account/ResetPassword?token=...
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ResetPassword(string token)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(token)) return RedirectToAction("Login");
|
||||
|
||||
var user = await _db.Users.FirstOrDefaultAsync(u =>
|
||||
u.ResetToken == token && u.ResetTokenExpiresAt > DateTimeOffset.UtcNow);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
TempData["Error"] = "Lien invalide ou expiré.";
|
||||
return RedirectToAction("ForgotPassword");
|
||||
}
|
||||
|
||||
ViewBag.Token = token;
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST /Account/ResetPassword
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ResetPassword(string token, string newPassword, string confirmPassword)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(token))
|
||||
{
|
||||
TempData["Error"] = "Token manquant.";
|
||||
return RedirectToAction("ForgotPassword");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(newPassword) || newPassword != confirmPassword)
|
||||
{
|
||||
ModelState.AddModelError("", "Les mots de passe ne correspondent pas.");
|
||||
ViewBag.Token = token;
|
||||
return View();
|
||||
}
|
||||
|
||||
var user = await _db.Users.FirstOrDefaultAsync(u =>
|
||||
u.ResetToken == token && u.ResetTokenExpiresAt > DateTimeOffset.UtcNow);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
TempData["Error"] = "Lien invalide ou expiré.";
|
||||
return RedirectToAction("ForgotPassword");
|
||||
}
|
||||
|
||||
user.PasswordHash = _hasher.HashPassword(user, newPassword);
|
||||
user.ResetToken = null;
|
||||
user.ResetTokenExpiresAt = null;
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
TempData["Ok"] = "Mot de passe réinitialisé. Connecte-toi.";
|
||||
return RedirectToAction("Login");
|
||||
}
|
||||
|
||||
// (Optionnel) création rapide d’un compte admin si tu n’as rien en BDD
|
||||
[HttpPost, ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SeedAdmin(string username = "admin", string password = "ChangeMe!123")
|
||||
{
|
||||
if (await _db.Users.AnyAsync()) return BadRequest("Déjà des utilisateurs en BDD.");
|
||||
var u = new User { Username = username };
|
||||
u.PasswordHash = _hasher.HashPassword(u, password);
|
||||
_db.Users.Add(u);
|
||||
await _db.SaveChangesAsync();
|
||||
return Ok("Admin créé.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user