identificacion, asignacion y seguimiento de conexion de dispositivos por usuario listo
This commit is contained in:
@@ -3,12 +3,21 @@ import { VLAN_ID } from '../config/env.js';
|
||||
import { buildAcceptPayload, normalizeAttributes } from '../utils/attrs.js';
|
||||
import { pushRequest } from '../sse.js';
|
||||
import { activeSessions, sendRadiusSelfTest } from '../services/radius.js';
|
||||
import { addDeviceToUser, connectDeviceForUser, disconnectDeviceForUser, getOrCreateDevice } from '../services/db.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.post('/authorize', (req, res) => {
|
||||
const attrs = normalizeAttributes(req.body);
|
||||
const reply = buildAcceptPayload();
|
||||
// Try to record device usage
|
||||
const mac = attrs['Calling-Station-Id'] || attrs['Calling-Station-Id*0'] || '';
|
||||
const username = attrs['User-Name'] || attrs['User-Name*0'] || '';
|
||||
if (mac && username) {
|
||||
getOrCreateDevice({ mac: String(mac) }).then(async (id) => {
|
||||
await addDeviceToUser(String(username), id);
|
||||
}).catch(() => {});
|
||||
}
|
||||
pushRequest({
|
||||
id: Date.now() + ':' + Math.random().toString(16).slice(2),
|
||||
ts: new Date().toISOString(),
|
||||
@@ -37,8 +46,22 @@ router.post('/accounting', (req, res) => {
|
||||
calledStationId: attrs['Called-Station-Id'] || '',
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
// upsert device and link as connected
|
||||
const mac = attrs['Calling-Station-Id'] || '';
|
||||
if (mac) {
|
||||
getOrCreateDevice({ mac: String(mac) }).then(async (id) => {
|
||||
await addDeviceToUser(String(username), id);
|
||||
await connectDeviceForUser(String(username), id);
|
||||
}).catch(() => {});
|
||||
}
|
||||
} else if (st === 'STOP') {
|
||||
activeSessions.delete(sessionId);
|
||||
const mac = attrs['Calling-Station-Id'] || '';
|
||||
if (mac) {
|
||||
getOrCreateDevice({ mac: String(mac) }).then(async (id) => {
|
||||
await disconnectDeviceForUser(String(username), id);
|
||||
}).catch(() => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
@@ -56,6 +79,13 @@ router.post('/authorize-inner', async (_req, res) => res.status(410).json({}));
|
||||
router.post('/post-auth', async (req, res) => {
|
||||
try {
|
||||
const attrs = normalizeAttributes(req.body);
|
||||
const mac = attrs['Calling-Station-Id'] || attrs['Calling-Station-Id*0'] || '';
|
||||
const username = attrs['User-Name'] || attrs['User-Name*0'] || '';
|
||||
if (mac && username) {
|
||||
getOrCreateDevice({ mac: String(mac) }).then(async (id) => {
|
||||
await addDeviceToUser(String(username), id);
|
||||
}).catch(() => {});
|
||||
}
|
||||
pushRequest({
|
||||
id: Date.now() + ':' + Math.random().toString(16).slice(2),
|
||||
ts: new Date().toISOString(),
|
||||
@@ -91,4 +121,3 @@ router.post('/test/radius', async (_req, res) => {
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
|
||||
@@ -68,6 +68,70 @@ export async function ensureSchema() {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getOrCreateDevice({ mac, nombre = null, vendor = null, descripcion = null }) {
|
||||
if (!mac) throw new Error('mac required');
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
const up = await client.query(
|
||||
`INSERT INTO dispositivos (mac, nombre, vendor, descripcion)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (mac) DO UPDATE SET
|
||||
last_seen = NOW(),
|
||||
nombre = COALESCE(dispositivos.nombre, EXCLUDED.nombre),
|
||||
vendor = COALESCE(dispositivos.vendor, EXCLUDED.vendor),
|
||||
descripcion = COALESCE(dispositivos.descripcion, EXCLUDED.descripcion)
|
||||
RETURNING id`,
|
||||
[String(mac), nombre, vendor, descripcion]
|
||||
);
|
||||
return up.rows[0].id;
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureUserRow(username) {
|
||||
await pool.query('INSERT INTO users (username) VALUES ($1) ON CONFLICT (username) DO NOTHING', [username]);
|
||||
}
|
||||
|
||||
export async function addDeviceToUser(username, deviceId) {
|
||||
await ensureUserRow(username);
|
||||
await pool.query(
|
||||
`UPDATE users SET dispositivos_utilizados = (
|
||||
SELECT ARRAY(
|
||||
SELECT DISTINCT x FROM (
|
||||
SELECT unnest(coalesce(dispositivos_utilizados, '{}'::int[])) AS x
|
||||
UNION ALL SELECT $2::int
|
||||
) AS t
|
||||
)
|
||||
) WHERE username = $1`,
|
||||
[username, deviceId]
|
||||
);
|
||||
}
|
||||
|
||||
export async function connectDeviceForUser(username, deviceId) {
|
||||
await ensureUserRow(username);
|
||||
await pool.query(
|
||||
`UPDATE users SET dispositivos_conectados = (
|
||||
SELECT ARRAY(
|
||||
SELECT DISTINCT x FROM (
|
||||
SELECT unnest(coalesce(dispositivos_conectados, '{}'::int[])) AS x
|
||||
UNION ALL SELECT $2::int
|
||||
) AS t
|
||||
)
|
||||
) WHERE username = $1`,
|
||||
[username, deviceId]
|
||||
);
|
||||
}
|
||||
|
||||
export async function disconnectDeviceForUser(username, deviceId) {
|
||||
await ensureUserRow(username);
|
||||
await pool.query(
|
||||
`UPDATE users SET dispositivos_conectados = array_remove(coalesce(dispositivos_conectados, '{}'::int[]), $2::int)
|
||||
WHERE username = $1`,
|
||||
[username, deviceId]
|
||||
);
|
||||
}
|
||||
|
||||
export async function readUsersFromDb() {
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user