fix: tenant dinamico desde BD - sin hardcodeo en frontend cliente

This commit is contained in:
2026-03-10 13:45:23 -06:00
parent 597286fff0
commit 6bc5145b9c
3 changed files with 36 additions and 23 deletions

View File

@@ -284,6 +284,7 @@ async def login(
"last_name": user.last_name, "last_name": user.last_name,
"role": user.role, "role": user.role,
"tenant_id": str(user.tenant_id), "tenant_id": str(user.tenant_id),
"tenant_slug": tenant.slug if tenant else str(user.tenant_id),
"is_active": user.is_active, "is_active": user.is_active,
"is_two_factor_enabled": user.totp_enabled or False, "is_two_factor_enabled": user.totp_enabled or False,
"created_at": user.created_at.isoformat() if user.created_at else None "created_at": user.created_at.isoformat() if user.created_at else None

View File

@@ -148,9 +148,12 @@ async def read_user(
✅ Implementa multi-tenancy: solo permite acceso a usuarios del propio tenant. ✅ Implementa multi-tenancy: solo permite acceso a usuarios del propio tenant.
""" """
if current_user.role.value == 'ADMIN':
query = select(User).where(User.id == user_id)
else:
query = select(User).where( query = select(User).where(
User.id == user_id, User.id == user_id,
User.tenant_id == current_user.tenant_id # ✅ Seguridad multi-tenant User.tenant_id == current_user.tenant_id
) )
result = await db.execute(query) result = await db.execute(query)
user = result.scalar_one_or_none() user = result.scalar_one_or_none()
@@ -187,7 +190,10 @@ async def update_user(
detail="You don't have permission to update users" detail="You don't have permission to update users"
) )
# Buscar usuario # Buscar usuario - ADMIN global puede editar cualquier tenant
if current_user.role.value == "ADMIN":
query = select(User).where(User.id == user_id)
else:
query = select(User).where( query = select(User).where(
User.id == user_id, User.id == user_id,
User.tenant_id == current_user.tenant_id User.tenant_id == current_user.tenant_id
@@ -294,7 +300,10 @@ async def delete_user(
detail="You cannot delete yourself" detail="You cannot delete yourself"
) )
# Buscar usuario # Buscar usuario - ADMIN global puede editar cualquier tenant
if current_user.role.value == "ADMIN":
query = select(User).where(User.id == user_id)
else:
query = select(User).where( query = select(User).where(
User.id == user_id, User.id == user_id,
User.tenant_id == current_user.tenant_id User.tenant_id == current_user.tenant_id
@@ -371,7 +380,10 @@ async def activate_user(
detail="You don't have permission to activate users" detail="You don't have permission to activate users"
) )
# Buscar usuario # Buscar usuario - ADMIN global puede editar cualquier tenant
if current_user.role.value == "ADMIN":
query = select(User).where(User.id == user_id)
else:
query = select(User).where( query = select(User).where(
User.id == user_id, User.id == user_id,
User.tenant_id == current_user.tenant_id User.tenant_id == current_user.tenant_id

View File

@@ -2,8 +2,6 @@ import { auth } from '$lib/stores/auth';
import { get } from 'svelte/store'; import { get } from 'svelte/store';
const API_BASE = '/api/v1'; const API_BASE = '/api/v1';
const TENANT_SLUG = 'aduanasoft';
interface RequestOptions extends RequestInit { interface RequestOptions extends RequestInit {
params?: Record<string, string>; params?: Record<string, string>;
} }
@@ -34,7 +32,8 @@ async function request<T>(endpoint: string, options: RequestOptions = {}): Promi
headers.set('Content-Type', 'application/json'); headers.set('Content-Type', 'application/json');
} }
headers.set('X-App', 'client'); headers.set('X-App', 'client');
headers.set('X-Tenant-Slug', TENANT_SLUG); const slug = get(authStore)?.user?.tenant_slug || get(authStore)?.user?.tenant_id || '';
headers.set('X-Tenant-Slug', slug);
const response = await fetch(url, { const response = await fetch(url, {
...init, ...init,
@@ -72,7 +71,8 @@ async function downloadFile(endpoint: string, filename: string): Promise<void> {
headers.set('X-Tenant-ID', authState.user.tenant_id); headers.set('X-Tenant-ID', authState.user.tenant_id);
} }
headers.set('X-App', 'client'); headers.set('X-App', 'client');
headers.set('X-Tenant-Slug', TENANT_SLUG); const slug = get(authStore)?.user?.tenant_slug || get(authStore)?.user?.tenant_id || '';
headers.set('X-Tenant-Slug', slug);
const response = await fetch(`${API_BASE}${endpoint}`, { const response = await fetch(`${API_BASE}${endpoint}`, {
method: 'GET', method: 'GET',