primeros cambios para manejar los permisos y grupos
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using Entidades.Dto;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Modelo;
|
using Modelo;
|
||||||
|
|
||||||
@@ -7,14 +8,17 @@ namespace AlquilaFacil.Controllers;
|
|||||||
public class AccionesController: ControllerBase {
|
public class AccionesController: ControllerBase {
|
||||||
|
|
||||||
[HttpPost("api/acciones")]
|
[HttpPost("api/acciones")]
|
||||||
public IActionResult ListarAccionesPorUsuario([FromBody] string email) {
|
public IActionResult ListarAccionesPorUsuario([FromBody] LoginDto email, [FromHeader(Name = "Auth")] string Auth) {
|
||||||
Request.Cookies.TryGetValue("token", out var token);
|
if (email.Email == "" || email.Email == null) return BadRequest();
|
||||||
if (token == null) return Unauthorized(new { esValido = false});
|
|
||||||
|
|
||||||
bool esValido = RepositorioUsuarios.Singleton.CheckToken(email, token);
|
|
||||||
|
if (Auth == "") return Unauthorized(new { esValido = false});
|
||||||
|
|
||||||
|
bool esValido = RepositorioUsuarios.Singleton.CheckToken(email.Email, Auth);
|
||||||
if (!esValido) return Unauthorized();
|
if (!esValido) return Unauthorized();
|
||||||
|
|
||||||
var Permisos = RepositorioPermisos.Singleton.ListarPermisos(email);
|
var Permisos = RepositorioPermisos.Singleton.ListarPermisos(email.Email);
|
||||||
|
Response.Headers["Content-Type"] = "application/json";
|
||||||
return Ok(Permisos);
|
return Ok(Permisos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#if DEBUG
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Modelo;
|
||||||
|
namespace AlquilaFacil.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
public class GruposController: ControllerBase {
|
||||||
|
[HttpPost("api/admin/grupos")]
|
||||||
|
public IActionResult CrearPermisos([FromBody] AdminGrupo grupo) {
|
||||||
|
if (String.IsNullOrEmpty(grupo.descripcion)) return BadRequest();
|
||||||
|
|
||||||
|
bool ret = RepositorioGrupos.Singleton.CrearGrupo(grupo.descripcion);
|
||||||
|
return (ret) ? Ok(ret) : BadRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record AdminGrupo(string descripcion);
|
||||||
|
#endif
|
||||||
@@ -12,8 +12,16 @@ public class InquilinoController: ControllerBase
|
|||||||
{
|
{
|
||||||
|
|
||||||
[HttpGet("api/inquilino")]
|
[HttpGet("api/inquilino")]
|
||||||
public IActionResult Get() {
|
public IActionResult Get([FromHeader(Name = "Auth")] string Auth) {
|
||||||
return Ok();
|
if (!string.IsNullOrEmpty(Auth)) return BadRequest();
|
||||||
|
string path = Request.Path;
|
||||||
|
|
||||||
|
var ret = RepositorioPermisos.Singleton.CheckPermisos(Auth, path);
|
||||||
|
if (ret == false) return BadRequest(ret);
|
||||||
|
|
||||||
|
var list = RepositorioInquilinos.Singleton.GetInquilinos();
|
||||||
|
|
||||||
|
return Ok(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("api/inquilino")]
|
[HttpPost("api/inquilino")]
|
||||||
|
|||||||
@@ -24,19 +24,19 @@ public class LoginController: ControllerBase
|
|||||||
var cookieOptions = new CookieOptions
|
var cookieOptions = new CookieOptions
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
Secure = true,
|
Secure = true,
|
||||||
//SameSite = SameSiteMode.Strict,
|
SameSite = SameSiteMode.None,
|
||||||
Expires = DateTimeOffset.UtcNow.AddHours(1)
|
Path = "/Menu",
|
||||||
|
|
||||||
|
Expires = DateTimeOffset.UtcNow.AddHours(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
Response.Cookies.Append("token", tokenString, cookieOptions);
|
Response.Cookies.Append("token", tokenString, cookieOptions);
|
||||||
return Ok( new {Email = loginDto.Email, Redirect = "/Menu"});
|
return Ok( new {Email = loginDto.Email, Token = tokenString, Redirect = "/Menu"});
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("api/login/validar")]
|
[HttpPost("api/login/validar")]
|
||||||
public IActionResult Verificar([FromBody] AccessDto request){
|
public IActionResult Verificar([FromBody] AccessDto request, [FromHeader(Name = "Auth")] string token){
|
||||||
|
|
||||||
Request.Cookies.TryGetValue("token", out var token);
|
|
||||||
|
|
||||||
if (request.Email == String.Empty || token == null ||request.Redirect == string.Empty)
|
if (request.Email == String.Empty || token == null ||request.Redirect == string.Empty)
|
||||||
{
|
{
|
||||||
@@ -44,8 +44,13 @@ public class LoginController: ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool esValido = RepositorioUsuarios.Singleton.CheckToken(request.Email, token);
|
bool esValido = RepositorioUsuarios.Singleton.CheckToken(request.Email, token);
|
||||||
return (esValido) ?
|
if (esValido) {
|
||||||
Ok( new { esValido = true}) : Unauthorized( new {esValido = false});
|
return Ok(new {esValido = esValido});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return Unauthorized(new {esValido = "el token no es valido"});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#if DEBUG
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Modelo;
|
||||||
|
namespace AlquilaFacil.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
public class PermisosController: ControllerBase {
|
||||||
|
[HttpPost("api/admin/permisos")]
|
||||||
|
public IActionResult CrearPermisos([FromBody] AdminPermiso permiso) {
|
||||||
|
if (String.IsNullOrEmpty(permiso.descripcion)) return BadRequest();
|
||||||
|
|
||||||
|
bool ret = RepositorioPermisos.Singleton.CrearPermiso(permiso.descripcion);
|
||||||
|
return (ret) ? Ok(ret) : BadRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record AdminPermiso(string descripcion);
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Entidades.Dto;
|
||||||
|
|
||||||
|
public class InquilinoDto {
|
||||||
|
public long Dni { get; set; }
|
||||||
|
public string Nombre { get; set; } = "";
|
||||||
|
public string Apellido { get; set; } = "";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace Entidades.Dto;
|
namespace Entidades.Dto;
|
||||||
|
|
||||||
public class LoginDto
|
public class LoginDto
|
||||||
{
|
{
|
||||||
public string Email {get; set;} = string.Empty;
|
public string Email {get; set;} = string.Empty;
|
||||||
public string Contraseña {get; set;} = string.Empty;
|
public string? Contraseña {get; set;} = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,59 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Navbar, NavbarBrand, NavbarToggler, NavItem, Nav, NavLink, Collapse } from "@sveltestrap/sveltestrap";
|
import { Navbar, NavbarBrand, NavbarToggler, NavItem, Nav, NavLink, Collapse } from "@sveltestrap/sveltestrap";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { navigate } from "svelte-routing";
|
import { writable } from 'svelte/store';
|
||||||
let isOpen = false;
|
|
||||||
|
|
||||||
function handleUpdate(event: any) {
|
|
||||||
isOpen = event.detail.isOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
let permisos = $state()
|
let isOpen: boolean = $state(false);
|
||||||
|
|
||||||
|
interface Permiso {
|
||||||
|
id: number;
|
||||||
|
descripcion: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const permisos = writable<Permiso[]>([]);
|
||||||
|
const email = localStorage.getItem('email');
|
||||||
|
const token = sessionStorage.getItem('token');
|
||||||
|
|
||||||
|
|
||||||
async function obtenerPermisos(){
|
async function obtenerPermisos(){
|
||||||
try {
|
try {
|
||||||
const response = await fetch("http://localhost:5007/api/acciones",{
|
const response = await fetch("http://localhost:5007/api/acciones",{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
'Auth' : String(token),
|
||||||
'Content-Type' : "application/json"
|
'Content-Type' : "application/json"
|
||||||
},
|
},
|
||||||
credentials: 'include'
|
body: JSON.stringify({email})
|
||||||
});
|
});
|
||||||
if (response.ok){
|
if (response.ok){
|
||||||
permisos = response.json();
|
const json = await response.json();
|
||||||
|
|
||||||
|
permisos.set(json);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
navigate("/");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
$inspect(permisos);
|
||||||
|
onMount( () => {
|
||||||
|
obtenerPermisos();
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Navbar container="xxl" expand="md" color="dark-subtle">
|
<Navbar container="xxl" expand="md" color="dark-subtle">
|
||||||
<NavbarBrand href="/Menu">AlquilaFacil</NavbarBrand>
|
<NavbarBrand href="/">
|
||||||
|
AlquilaFacil
|
||||||
|
</NavbarBrand>
|
||||||
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
|
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
|
||||||
<Collapse isOpen={isOpen} navbar expand="md" on:update={handleUpdate}>
|
<Collapse isOpen={isOpen} navbar expand="md">
|
||||||
<Nav class="ms-auto" navbar>
|
<Nav class="ms-auto" navbar>
|
||||||
|
{#each $permisos as item }
|
||||||
|
<NavItem>
|
||||||
|
<NavLink href="/accion/{item.id}">{item.descripcion}</NavLink>
|
||||||
|
</NavItem>
|
||||||
|
{/each}
|
||||||
</Nav>
|
</Nav>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</Navbar>
|
</Navbar>
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Navbar, NavbarBrand, NavbarToggler, NavItem, Nav, NavLink, Collapse } from "@sveltestrap/sveltestrap";
|
import { Navbar, NavbarBrand, NavbarToggler, NavItem, Nav, NavLink, Collapse } from "@sveltestrap/sveltestrap";
|
||||||
let isOpen = $state(false);
|
|
||||||
function handleUpdate(event) {
|
let isOpen:boolean = false;
|
||||||
isOpen = event.detail.isOpen;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
AlquilaFacil
|
AlquilaFacil
|
||||||
</NavbarBrand>
|
</NavbarBrand>
|
||||||
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
|
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
|
||||||
<Collapse isOpen={isOpen} navbar expand="md" on:update={handleUpdate}>
|
<Collapse isOpen={isOpen} navbar expand="md">
|
||||||
<Nav class="ms-auto" navbar>
|
<Nav class="ms-auto" navbar>
|
||||||
<NavItem>
|
<NavItem>
|
||||||
<NavLink href="/">Login</NavLink>
|
<NavLink href="/">Login</NavLink>
|
||||||
|
|||||||
@@ -1,51 +1,53 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { navigate } from 'svelte-routing'; // Asumiendo que estás usando svelte-routing
|
import { navigate } from 'svelte-routing';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
let isAuthenticated = writable(false);
|
export let component;
|
||||||
let isVerified = writable(false);
|
|
||||||
|
const isAuthenticated = writable(false);
|
||||||
|
const isVerified = writable(false);
|
||||||
let { component } = $props();
|
|
||||||
|
const redirect = window.location.pathname;
|
||||||
let redirect = window.location.pathname;
|
const email = localStorage.getItem('email');
|
||||||
|
const token = sessionStorage.getItem('token');
|
||||||
const email = localStorage.getItem('email');
|
|
||||||
|
const handleAccess = async () => {
|
||||||
const handleAccess = async () => {
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('http://127.0.0.1:5007/api/login/validar', {
|
const response = await fetch('http://127.0.0.1:5007/api/login/validar', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Auth': String(token),
|
||||||
},
|
'Content-Type': 'application/json',
|
||||||
body: JSON.stringify( {email, redirect} ),
|
},
|
||||||
credentials: "include"
|
body: JSON.stringify({ email, redirect }),
|
||||||
});
|
credentials: "include"
|
||||||
|
});
|
||||||
if (response.ok) {
|
|
||||||
isAuthenticated.set(true);
|
if (response.ok) {
|
||||||
}
|
isAuthenticated.set(true); // Actualiza el store
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error durante la autenticación:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isVerified.set(true);
|
isVerified.set(true); // Marca la verificación como completada
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(() => {
|
||||||
await handleAccess();
|
handleAccess();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !$isVerified}
|
{#if !$isVerified}
|
||||||
<div class="spinner-border position-absolute top-50 start-50 translate-middle" role="status">
|
<div class="spinner-border position-absolute top-50 start-50 translate-middle" role="status">
|
||||||
<span class="visually-hidden">Cargando</span>
|
<span class="visually-hidden">Cargando</span>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
{#if $isAuthenticated}
|
{#if $isAuthenticated}
|
||||||
{@const SvelteComponent = component}
|
<svelte:component this={component} />
|
||||||
<SvelteComponent/>
|
|
||||||
{:else}
|
{:else}
|
||||||
{navigate('/')}
|
{navigate('/')}
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
const ret = await response.json();
|
const ret = await response.json();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
localStorage.setItem('email', ret.email);
|
localStorage.setItem('email', ret.email);
|
||||||
|
sessionStorage.setItem('token', ret.token);
|
||||||
//setTimeout(() => console.log("50ms") ,50);
|
//setTimeout(() => console.log("50ms") ,50);
|
||||||
navigate(ret.redirect);
|
navigate(ret.redirect);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
+1
-1
@@ -17,5 +17,5 @@
|
|||||||
"moduleDetection": "force"
|
"moduleDetection": "force"
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
|
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
|
||||||
"references": [{ "path": "./tsconfig.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
using Entidades;
|
||||||
|
|
||||||
|
namespace Modelo;
|
||||||
|
public class RepositorioGrupos: RepositorioBase<RepositorioGrupos> {
|
||||||
|
public bool CrearGrupo(string descripcion)
|
||||||
|
{
|
||||||
|
var con = Context;
|
||||||
|
|
||||||
|
int mx = con.Grupos.Max(grupo => grupo.Id);
|
||||||
|
Grupo gru = new Grupo{
|
||||||
|
Id = mx+1,
|
||||||
|
Nombre = descripcion,
|
||||||
|
};
|
||||||
|
con.Grupos.Add(gru);
|
||||||
|
|
||||||
|
return Guardar(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Entidades.Dto;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Modelo;
|
||||||
|
|
||||||
|
public class RepositorioInquilinos: RepositorioBase<RepositorioInquilinos> {
|
||||||
|
public IQueryable<InquilinoDto> GetInquilinos()
|
||||||
|
{
|
||||||
|
FormattableString sqlq =
|
||||||
|
$"""
|
||||||
|
SELECT I.Dni, I.Nombre, I.Apellido FROM Inquilinos
|
||||||
|
""";
|
||||||
|
return Context.Database.SqlQuery<InquilinoDto>(sqlq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
using Entidades;
|
using Entidades;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
@@ -14,6 +15,46 @@ public class RepositorioPermisos: RepositorioBase<RepositorioPermisos> {
|
|||||||
.SelectMany(g => g.Idpermisos)
|
.SelectMany(g => g.Idpermisos)
|
||||||
.Distinct();
|
.Distinct();
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CheckPermisos(string token, string path){
|
||||||
|
var con = Context;
|
||||||
|
//checkeo que el token corresponda a un usuario
|
||||||
|
Cliente? cli = con.Clientes.FirstOrDefault(x => x.Token == token);
|
||||||
|
if (cli == null || cli.Dni == 0) return false;
|
||||||
|
|
||||||
|
// obtengo una lista de los permisos
|
||||||
|
var permisos = con.Clientes
|
||||||
|
.Where(x => x.Dni == cli.Dni)
|
||||||
|
.SelectMany(x => x.Idgrupos)
|
||||||
|
.SelectMany(x => x.Idpermisos)
|
||||||
|
.Distinct();
|
||||||
|
|
||||||
|
//me inspiré y hice un regex pero si eliminaba los primeros 8(?) caracteres del string era lo mismo
|
||||||
|
Match match = Regex.Match(path, @"^/accion/(\d+)$");
|
||||||
|
int.TryParse(match.Groups[1].Value, out int idpermiso);
|
||||||
|
bool tienePermiso = false;
|
||||||
|
|
||||||
|
Parallel.ForEach(permisos, (x, i) =>{
|
||||||
|
if (x.Id == idpermiso) {
|
||||||
|
tienePermiso = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return tienePermiso;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
public bool CrearPermiso(string descripcion) {
|
||||||
|
var con = Context;
|
||||||
|
int mx = con.Permisos.Max(x => x.Id);
|
||||||
|
|
||||||
|
Permiso per = new Permiso{
|
||||||
|
Id = mx,
|
||||||
|
Descripcion = descripcion
|
||||||
|
};
|
||||||
|
con.Permisos.Add(per);
|
||||||
|
return Guardar(con);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
@@ -57,6 +57,10 @@ public class RepositorioUsuarios: RepositorioBase<RepositorioUsuarios>
|
|||||||
var usu = Context.Clientes.FirstOrDefault(x => x.Email == email);
|
var usu = Context.Clientes.FirstOrDefault(x => x.Email == email);
|
||||||
if (usu == null) return false;
|
if (usu == null) return false;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
//Console.WriteLine(token + "\n" +usu.Token);
|
||||||
|
#endif
|
||||||
|
|
||||||
return usu.Token == token;
|
return usu.Token == token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user