F1 - Autentcacion - Completa

This commit is contained in:
2026-08-10 15:54:42 -03:00
commit dd7f5b3bf6
245 changed files with 81985 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using vita_asistente.Models;
using vita_asistente.ViewModels;
using System.Threading.Tasks;
namespace vita_asistente.Controllers
{
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public AccountController(UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
// GET: /Account/Register
[HttpGet]
public IActionResult Register()
{
return View();
}
// POST: /Account/Register
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
// Crear el usuario con los datos del formulario
var user = new ApplicationUser
{
UserName = model.Email, // Usamos Email como nombre de usuario
Email = model.Email,
Nombre = model.Nombre,
Apellido = model.Apellido,
Documento = model.Documento,
Direccion = model.Direccion,
RolPrincipal = "Usuario" // valor por defecto, luego puedes asignar roles
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
// Asignar rol "Usuario" por defecto (si el rol existe)
// Si no existe, lo creamos o lo ignoramos. Lo veremos después.
// Por ahora, solo iniciamos sesión.
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// Si llegamos aquí, algo falló, devolver la vista con errores
return View(model);
}
// GET: /Account/Login
[HttpGet]
public IActionResult Login(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
// POST: /Account/Login
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(
model.Email,
model.Password,
model.RememberMe,
lockoutOnFailure: false);
if (result.Succeeded)
{
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
// Manejar 2FA si lo implementas después
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
return RedirectToAction(nameof(Lockout));
}
else
{
ModelState.AddModelError(string.Empty, "Intento de inicio de sesión inválido.");
return View(model);
}
}
// Si llegamos aquí, algo falló
return View(model);
}
// POST: /Account/Logout
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return RedirectToAction("Index", "Home");
}
// Acciones auxiliares para redirección, 2FA, bloqueo, etc. (opcionales)
private IActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
// GET: /Account/Lockout
[HttpGet]
public IActionResult Lockout()
{
return View();
}
// GET: /Account/LoginWith2fa (opcional)
[HttpGet]
public IActionResult LoginWith2fa(bool rememberMe, string returnUrl = null)
{
// Implementar si se usa 2FA
return View();
}
}
}
+32
View File
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using vita_asistente.Models;
namespace vita_asistente.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
+86
View File
@@ -0,0 +1,86 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using System.Linq;
namespace vita_asistente.Controllers
{
[Authorize(Roles = "Admin")]
public class RolesController : Controller
{
private readonly RoleManager<IdentityRole> _roleManager;
public RolesController(RoleManager<IdentityRole> roleManager)
{
_roleManager = roleManager;
}
// GET: Roles
public async Task<IActionResult> Index()
{
var roles = await _roleManager.Roles.ToListAsync();
return View(roles);
}
// GET: Roles/Create
public IActionResult Create()
{
return View();
}
// POST: Roles/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(string roleName)
{
if (string.IsNullOrEmpty(roleName))
{
ModelState.AddModelError("", "El nombre del rol no puede estar vacío.");
return View();
}
var roleExists = await _roleManager.RoleExistsAsync(roleName);
if (!roleExists)
{
var result = await _roleManager.CreateAsync(new IdentityRole(roleName));
if (result.Succeeded)
{
return RedirectToAction(nameof(Index));
}
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
else
{
ModelState.AddModelError("", "El rol ya existe.");
}
return View();
}
// GET: Roles/Delete/5
public async Task<IActionResult> Delete(string id)
{
if (id == null) return NotFound();
var rol = await _roleManager.FindByIdAsync(id);
if (rol == null) return NotFound();
return View(rol);
}
// POST: Roles/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
var rol = await _roleManager.FindByIdAsync(id);
if (rol != null)
{
await _roleManager.DeleteAsync(rol);
}
return RedirectToAction(nameof(Index));
}
}
}
+220
View File
@@ -0,0 +1,220 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
using vita_asistente.Models;
namespace vita_asistente.Controllers
{
[Authorize(Roles = "Admin")]
public class UsuariosController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
public UsuariosController(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
{
_userManager = userManager;
_roleManager = roleManager;
}
// GET: Usuarios
public async Task<IActionResult> Index()
{
var usuarios = await _userManager.Users.ToListAsync();
return View(usuarios);
}
// GET: Usuarios/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null) return NotFound();
var usuario = await _userManager.FindByIdAsync(id);
if (usuario == null) return NotFound();
var roles = await _userManager.GetRolesAsync(usuario);
ViewBag.Roles = roles;
return View(usuario);
}
// GET: Usuarios/Create
public IActionResult Create()
{
return View();
}
// POST: Usuarios/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ApplicationUser usuario, string password)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = usuario.Email,
Email = usuario.Email,
Nombre = usuario.Nombre,
Apellido = usuario.Apellido,
Documento = usuario.Documento,
Direccion = usuario.Direccion,
// RolPrincipal se asigna después
};
var result = await _userManager.CreateAsync(user, password);
if (result.Succeeded)
{
// Asignar un rol por defecto (por ejemplo "Usuario" si existe)
if (await _roleManager.RoleExistsAsync("Usuario"))
{
await _userManager.AddToRoleAsync(user, "Usuario");
}
return RedirectToAction(nameof(Index));
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return View(usuario);
}
// GET: Usuarios/Edit/5
public async Task<IActionResult> Edit(string id)
{
if (id == null) return NotFound();
var usuario = await _userManager.FindByIdAsync(id);
if (usuario == null) return NotFound();
return View(usuario);
}
// POST: Usuarios/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, ApplicationUser usuarioActualizado)
{
if (id != usuarioActualizado.Id) return NotFound();
if (ModelState.IsValid)
{
var usuario = await _userManager.FindByIdAsync(id);
if (usuario == null) return NotFound();
// Actualizar solo los campos permitidos
usuario.Nombre = usuarioActualizado.Nombre;
usuario.Apellido = usuarioActualizado.Apellido;
usuario.Documento = usuarioActualizado.Documento;
usuario.Direccion = usuarioActualizado.Direccion;
usuario.Email = usuarioActualizado.Email;
usuario.UserName = usuarioActualizado.Email;
var result = await _userManager.UpdateAsync(usuario);
if (result.Succeeded)
{
return RedirectToAction(nameof(Index));
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return View(usuarioActualizado);
}
// GET: Usuarios/Delete/5
public async Task<IActionResult> Delete(string id)
{
if (id == null) return NotFound();
var usuario = await _userManager.FindByIdAsync(id);
if (usuario == null) return NotFound();
return View(usuario);
}
// POST: Usuarios/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
var usuario = await _userManager.FindByIdAsync(id);
if (usuario != null)
{
var result = await _userManager.DeleteAsync(usuario);
if (!result.Succeeded)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
}
return RedirectToAction(nameof(Index));
}
// GET: Usuarios/ManageRoles/5
public async Task<IActionResult> ManageRoles(string id)
{
if (id == null) return NotFound();
var usuario = await _userManager.FindByIdAsync(id);
if (usuario == null) return NotFound();
var rolesDelUsuario = await _userManager.GetRolesAsync(usuario);
var todosLosRoles = await _roleManager.Roles.ToListAsync();
var model = new ManageRolesViewModel
{
UsuarioId = usuario.Id,
UsuarioNombre = $"{usuario.Nombre} {usuario.Apellido}",
RolesDisponibles = todosLosRoles.Select(r => new RoleCheckbox
{
RoleId = r.Id,
RoleName = r.Name,
IsSelected = rolesDelUsuario.Contains(r.Name)
}).ToList()
};
return View(model);
}
// POST: Usuarios/ManageRoles
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ManageRoles(ManageRolesViewModel model)
{
var usuario = await _userManager.FindByIdAsync(model.UsuarioId);
if (usuario == null) return NotFound();
var rolesDelUsuario = await _userManager.GetRolesAsync(usuario);
var rolesSeleccionados = model.RolesDisponibles.Where(r => r.IsSelected).Select(r => r.RoleName).ToList();
// Remover roles que ya no están seleccionados
var rolesAEliminar = rolesDelUsuario.Except(rolesSeleccionados).ToList();
foreach (var rol in rolesAEliminar)
{
await _userManager.RemoveFromRoleAsync(usuario, rol);
}
// Agregar roles nuevos
var rolesAAgregar = rolesSeleccionados.Except(rolesDelUsuario).ToList();
foreach (var rol in rolesAAgregar)
{
await _userManager.AddToRoleAsync(usuario, rol);
}
return RedirectToAction(nameof(Index));
}
}
// ViewModels para la gestión de roles (dentro del mismo archivo por simplicidad)
public class ManageRolesViewModel
{
public string UsuarioId { get; set; }
public string UsuarioNombre { get; set; }
public List<RoleCheckbox> RolesDisponibles { get; set; }
}
public class RoleCheckbox
{
public string RoleId { get; set; }
public string RoleName { get; set; }
public bool IsSelected { get; set; }
}
}