Operaciones de Usuario de Inquilino
Los endpoints de usuario con ámbito de inquilino gestionan usuarios dentro de un inquilino específico. Estos endpoints pueden ser accedidos con una Clave API Global o una Clave API del Inquilino.
Autenticación
| Tipo de Clave API | Acceso |
|---|---|
| Clave API Global | Puede acceder a cualquier inquilino |
| Clave API del Inquilino | Solo puede acceder a su propio inquilino |
Listar Usuarios del Inquilino
GET /api/tenant/{tenantId}/user
Recupera los usuarios asignados a un inquilino específico.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
Parámetros de Consulta
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
page |
integer | 1 | Número de página para paginación |
pageSize |
integer | 50 | Número de elementos por página (máximo: 1000) |
includeDisabled |
boolean | false | Incluir usuarios deshabilitados |
role |
string | null | Filtrar por nombre de rol |
search |
string | null | Buscar por correo electrónico o nombre para mostrar |
Respuesta (200 OK)
Misma estructura que la lista global de todos los usuarios, pero filtrada al inquilino especificado.
Crear Usuario en el Inquilino
POST /api/tenant/{tenantId}/user
Crea un usuario nuevo Y lo asigna al inquilino, o asigna un usuario existente al inquilino.
Nota: Si ya existe un usuario con el correo electrónico especificado, se le asignará al inquilino en lugar de crear un duplicado.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
Cuerpo de la Solicitud
{
"email": "john.smith@example.com",
"displayName": "John Smith",
"firstName": "John",
"lastName": "Smith",
"roleName": "Analyst"
}
Campos de la Solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
email |
string | Sí | Correo electrónico del usuario |
displayName |
string | Sí | Nombre para mostrar (2-100 caracteres) |
firstName |
string | No | Nombre (máx. 50 caracteres) |
lastName |
string | No | Apellido (máx. 50 caracteres) |
roleName |
string | Sí | Nombre del rol (ver Roles y Permisos) |
Validación de Capacidad
La operación valida los límites de capacidad del inquilino:
- Se verifica el límite MaxUsers para todos los roles
- Se verifica el límite MaxAnalyst para roles de Analista
Respuesta (201 Created)
{
"userId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "john.smith@example.com",
"displayName": "John Smith",
"message": "Usuario creado y asignado al inquilino correctamente"
}
Respuestas de Error
Conflicto (409):
{
"error": "El usuario ya está asignado a este inquilino"
}
Capacidad Excedida (400):
{
"error": "No se puede agregar el usuario: el inquilino ha alcanzado su límite máximo de usuarios (100)",
"hint": "Aumente el límite de usuarios o analistas del inquilino para agregar más usuarios"
}
Obtener Usuario en el Inquilino
GET /api/tenant/{tenantId}/user/{userId}
Recupera un usuario específico dentro del contexto del inquilino.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
userId |
GUID | Sí | El identificador del usuario |
Respuesta (200 OK)
Devuelve el objeto usuario si está asignado al inquilino.
Obtener Usuario por Correo en el Inquilino
GET /api/tenant/{tenantId}/user/by-email/{email}
Recupera un usuario por correo electrónico dentro del contexto del inquilino.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
email |
string | Sí | El correo electrónico del usuario (codificado en URL) |
Respuesta (200 OK)
Devuelve el objeto usuario si está asignado al inquilino.
Asignar Usuario Existente al Inquilino
POST /api/tenant/{tenantId}/user/{userId}
Asigna un usuario existente a un inquilino.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
userId |
GUID | Sí | El identificador del usuario |
Cuerpo de la Solicitud (Opcional)
{
"roleName": "Analyst"
}
Respuesta (200 OK)
{
"message": "Usuario asignado al inquilino correctamente"
}
Actualizar Usuario en el Inquilino
PUT /api/tenant/{tenantId}/user/{userId}
Actualiza las propiedades de un usuario dentro del contexto del inquilino.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
userId |
GUID | Sí | El identificador del usuario |
Cuerpo de la Solicitud
{
"displayName": "Nombre Actualizado",
"roleName": "TenantAdmin"
}
Respuesta (200 OK)
{
"message": "Usuario actualizado correctamente"
}
Eliminar Usuario del Inquilino
DELETE /api/tenant/{tenantId}/user/{userId}
Elimina la asignación de un usuario de un inquilino. Esto NO elimina al usuario del sistema.
Parámetros de Ruta
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tenantId |
GUID | Sí | El identificador del inquilino |
userId |
GUID | Sí | El identificador del usuario |
Respuesta (200 OK)
{
"message": "Usuario removido del inquilino correctamente"
}
Respuestas de Error
No Encontrado (404):
{
"error": "El usuario no está asignado a este inquilino"
}
Ejemplos de Implementación
cURL
# Listar usuarios de un inquilino (funciona con Clave API del Inquilino)
curl -X GET "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user" \
-H "Authorization: Bearer YOUR_TENANT_API_KEY"
# Buscar usuarios en el inquilino
curl -X GET "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user?search=john" \
-H "Authorization: Bearer YOUR_TENANT_API_KEY"
# Crear usuario en el inquilino (crea usuario Y asigna)
curl -X POST "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user" \
-H "Authorization: Bearer YOUR_TENANT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "new.user@example.com",
"displayName": "New User",
"roleName": "Analyst"
}'
# Asignar usuario existente al inquilino
curl -X POST "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_TENANT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"roleName": "Analyst"}'
# Remover usuario del inquilino
curl -X DELETE "https://your-mindzie-instance.com/api/tenant/12345678-1234-1234-1234-123456789012/user/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_TENANT_API_KEY"
Python
import requests
BASE_URL = 'https://your-mindzie-instance.com'
class TenantUserManager:
def __init__(self, api_key, tenant_id):
"""
Inicializa con una clave API y un ID de inquilino.
Funciona con claves API Globales o de Inquilino.
"""
self.headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
self.tenant_id = tenant_id
def list_users(self, page=1, page_size=50, role=None, search=None):
"""Lista usuarios asignados a este inquilino."""
url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user'
params = {'page': page, 'pageSize': page_size}
if role:
params['role'] = role
if search:
params['search'] = search
response = requests.get(url, headers=self.headers, params=params)
response.raise_for_status()
return response.json()
def create_user(self, email, display_name, role_name,
first_name=None, last_name=None):
"""Crea un usuario y lo asigna al inquilino (o asigna usuario existente)."""
url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user'
payload = {
'email': email,
'displayName': display_name,
'roleName': role_name
}
if first_name:
payload['firstName'] = first_name
if last_name:
payload['lastName'] = last_name
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
return response.json()
def assign_user(self, user_id, role_name=None):
"""Asigna un usuario existente a este inquilino."""
url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user/{user_id}'
payload = {}
if role_name:
payload['roleName'] = role_name
response = requests.post(url, json=payload, headers=self.headers)
response.raise_for_status()
return response.json()
def remove_user(self, user_id):
"""Elimina a un usuario de este inquilino (no elimina el usuario)."""
url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user/{user_id}'
response = requests.delete(url, headers=self.headers)
response.raise_for_status()
return response.json()
def get_user(self, user_id):
"""Obtiene un usuario específico en este inquilino."""
url = f'{BASE_URL}/api/tenant/{self.tenant_id}/user/{user_id}'
response = requests.get(url, headers=self.headers)
response.raise_for_status()
return response.json()
# Uso con clave API del Inquilino
tenant_id = '12345678-1234-1234-1234-123456789012'
manager = TenantUserManager('your-tenant-api-key', tenant_id)
# Listar todos los analistas en el inquilino
analysts = manager.list_users(role='Analyst')
print(f"El inquilino tiene {analysts['totalCount']} analistas")
for user in analysts['users']:
print(f" - {user['displayName']} ({user['email']})")
# Agregar un nuevo analista
new_user = manager.create_user(
email='new.analyst@example.com',
display_name='Nuevo Analista',
role_name='Analyst'
)
print(f"Usuario agregado: {new_user['userId']}")
# Eliminar usuario del inquilino (usuario sigue existiendo en el sistema)
manager.remove_user(new_user['userId'])
print("Usuario removido del inquilino")
JavaScript/Node.js
const BASE_URL = 'https://your-mindzie-instance.com';
class TenantUserManager {
constructor(apiKey, tenantId) {
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
this.tenantId = tenantId;
}
async listUsers(options = {}) {
const params = new URLSearchParams({
page: options.page || 1,
pageSize: options.pageSize || 50
});
if (options.role) params.append('role', options.role);
if (options.search) params.append('search', options.search);
const url = `${BASE_URL}/api/tenant/${this.tenantId}/user?${params}`;
const response = await fetch(url, { headers: this.headers });
if (!response.ok) throw new Error(`Falló: ${response.status}`);
return await response.json();
}
async createUser(email, displayName, roleName) {
const url = `${BASE_URL}/api/tenant/${this.tenantId}/user`;
const response = await fetch(url, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({ email, displayName, roleName })
});
if (!response.ok) throw new Error(`Falló: ${response.status}`);
return await response.json();
}
async assignUser(userId, roleName = null) {
const url = `${BASE_URL}/api/tenant/${this.tenantId}/user/${userId}`;
const body = roleName ? { roleName } : {};
const response = await fetch(url, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(body)
});
if (!response.ok) throw new Error(`Falló: ${response.status}`);
return await response.json();
}
async removeUser(userId) {
const url = `${BASE_URL}/api/tenant/${this.tenantId}/user/${userId}`;
const response = await fetch(url, {
method: 'DELETE',
headers: this.headers
});
if (!response.ok) throw new Error(`Falló: ${response.status}`);
return await response.json();
}
}
// Uso
const tenantId = '12345678-1234-1234-1234-123456789012';
const manager = new TenantUserManager('your-tenant-api-key', tenantId);
// Listar usuarios
const users = await manager.listUsers();
console.log(`El inquilino tiene ${users.totalCount} usuarios`);
// Agregar nuevo usuario
const newUser = await manager.createUser(
'new@example.com',
'Nuevo Usuario',
'Analyst'
);
console.log(`Agregado: ${newUser.userId}`);
Buenas Prácticas
- Usar Claves API del Inquilino: Para la mayoría de operaciones, las claves con ámbito de inquilino son más seguras
- Verificar Capacidad: Confirma los límites del inquilino antes de crear usuarios en masa
- Eliminar vs Remover: Remover del inquilino mantiene al usuario en el sistema para otros inquilinos
- Buscar Antes de Crear: Verifica si el usuario existe para evitar duplicados