F1 - Autentcacion - Completa
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user