119 lines
4.4 KiB
C#
119 lines
4.4 KiB
C#
using System.Security.Claims;
|
||
using administration.Models;
|
||
using Microsoft.AspNetCore.Authentication;
|
||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Identity;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
|
||
namespace administration.Controllers
|
||
{
|
||
public class ConnectionsController : Controller
|
||
{
|
||
private readonly LayoutDataContext _db;
|
||
private readonly IPasswordHasher<User> _hasher;
|
||
|
||
public ConnectionsController(LayoutDataContext db, IPasswordHasher<User> hasher)
|
||
{
|
||
_db = db;
|
||
_hasher = hasher;
|
||
}
|
||
|
||
// --- PAGE DE LOGIN ---
|
||
[HttpGet]
|
||
[AllowAnonymous]
|
||
public IActionResult Login() => View();
|
||
|
||
[HttpPost]
|
||
[AllowAnonymous]
|
||
[ValidateAntiForgeryToken]
|
||
public async Task<IActionResult> Login(string username, string password, string? returnUrl = null)
|
||
{
|
||
// 1) Recherche de l'utilisateur
|
||
var user = _db.Users.FirstOrDefault(u => u.Username == username);
|
||
if (user == null)
|
||
{
|
||
ViewBag.Error = "Nom d’utilisateur ou mot de passe incorrect.";
|
||
return View();
|
||
}
|
||
|
||
// 2) Vérification du mot de passe
|
||
var verification = _hasher.VerifyHashedPassword(user, user.PasswordHash ?? "", password);
|
||
if (verification != PasswordVerificationResult.Success &&
|
||
verification != PasswordVerificationResult.SuccessRehashNeeded)
|
||
{
|
||
ViewBag.Error = "Nom d’utilisateur ou mot de passe incorrect.";
|
||
return View();
|
||
}
|
||
|
||
// 3) Si rehash nécessaire → on sauvegarde
|
||
if (verification == PasswordVerificationResult.SuccessRehashNeeded)
|
||
{
|
||
user.PasswordHash = _hasher.HashPassword(user, password);
|
||
_db.SaveChanges();
|
||
}
|
||
|
||
// 4) Sauvegarde dans la session (si besoin pour ton code existant)
|
||
HttpContext.Session.SetInt32("UserId", user.Id);
|
||
HttpContext.Session.SetString("UserName", user.Username);
|
||
|
||
// 5) Création du cookie d'authentification
|
||
var claims = new[]
|
||
{
|
||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||
new Claim(ClaimTypes.Name, user.Username)
|
||
};
|
||
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||
await HttpContext.SignInAsync(
|
||
CookieAuthenticationDefaults.AuthenticationScheme,
|
||
new ClaimsPrincipal(identity));
|
||
|
||
// 6) Redirection sécurisée
|
||
if (!string.IsNullOrWhiteSpace(returnUrl) &&
|
||
Url.IsLocalUrl(returnUrl) &&
|
||
!returnUrl.Contains("/Connections/Login", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
return LocalRedirect(returnUrl);
|
||
}
|
||
|
||
return RedirectToAction("Index", "Home");
|
||
}
|
||
|
||
// --- DECONNEXION ---
|
||
[HttpPost]
|
||
[ValidateAntiForgeryToken]
|
||
public async Task<IActionResult> Logout()
|
||
{
|
||
await HttpContext.SignOutAsync(); // supprime le cookie
|
||
HttpContext.Session.Clear(); // vide la session
|
||
return RedirectToAction("Login", "Connections");
|
||
}
|
||
|
||
// --- MISE À JOUR DU MOT DE PASSE ---
|
||
// ⚠️ On met [Authorize] pour éviter un accès public
|
||
[HttpPost]
|
||
[Authorize]
|
||
public IActionResult SetPassword(string username, string newPassword)
|
||
{
|
||
var user = _db.Users.FirstOrDefault(u => u.Username == username);
|
||
if (user == null)
|
||
return Content("❌ Utilisateur introuvable");
|
||
|
||
user.PasswordHash = _hasher.HashPassword(user, newPassword);
|
||
_db.SaveChanges();
|
||
|
||
return Content("✅ Mot de passe mis à jour avec succès");
|
||
}
|
||
|
||
[HttpGet("/tools/hash")]
|
||
[Authorize] // et/ou protège par un flag d'env
|
||
public IActionResult HashTool(string username, string password, [FromServices] IPasswordHasher<User> hasher)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) return BadRequest("username/password requis");
|
||
var hash = hasher.HashPassword(new User { Username = username }, password);
|
||
return Content(hash);
|
||
}
|
||
|
||
}
|
||
}
|