Ajout de HelloFresh

This commit is contained in:
2025-09-03 20:17:50 +02:00
parent bcef0a472b
commit d287112b7d
429 changed files with 82881 additions and 22074 deletions

View 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 dauth
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 lutilisateur 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 laffiche
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 dun compte admin si tu nas 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éé.");
}
}