private rover request fixes finally

This commit is contained in:
legop3
2026-06-01 19:53:17 -04:00
parent d205d3a05d
commit af5ddfb11d
9 changed files with 81 additions and 27 deletions
@@ -74,14 +74,25 @@ function createPrivateAccessPolicy(deps) {
}
function getControlDenialReason(record, socket, options = {}) {
const { allowUser = false } = options;
const { allowUser = false, allowClosedPrivateGrantInLockdown = false } = options;
if (!record) return 'Unknown rover';
if (!allowUser && !isAdmin(socket)) return 'Only admins can request control';
if (record.locked && !isAdmin(socket)) return 'Rover locked';
const mode = getMode();
if (!allowUser && mode === MODES.ADMIN && !isAdmin(socket)) return 'Admins only';
if (!allowUser && mode === MODES.LOCKDOWN && !isLockdownAdmin(socket)) return 'Server in lockdown';
if (mode === MODES.LOCKDOWN && !isLockdownAdmin(socket)) return 'Server in lockdown';
if (
mode === MODES.LOCKDOWN &&
!isLockdownAdmin(socket) &&
!(
allowClosedPrivateGrantInLockdown &&
isPrivateRecord(record) &&
!isPrivateOpen(record) &&
socketHasClosedPrivateAccess(socket, record.id)
)
) {
return 'Server in lockdown';
}
const { isDeterred } = require('../verificationService');
if (!isAdmin(socket) && isDeterred(socket)) return 'Not authorized';
if (!isPrivateRecord(record)) return null;
@@ -33,9 +33,17 @@ function createRoverLifecycle(deps) {
}
function requestControl(roverId, socket, options = {}) {
const { force = false, allowUser = false } = options;
const {
force = false,
allowUser = false,
forceTurn = false,
allowClosedPrivateGrantInLockdown = false,
} = options;
const record = rovers.get(roverId);
const denied = getControlDenialReason(record, socket, { allowUser });
const denied = getControlDenialReason(record, socket, {
allowUser,
allowClosedPrivateGrantInLockdown,
});
if (denied) throw new Error(denied);
record.drivers.add(socket.id);
if (!socketToRovers.has(socket.id)) {
@@ -43,7 +51,7 @@ function createRoverLifecycle(deps) {
}
socketToRovers.get(socket.id).add(roverId);
socket.join(record.room);
turnService.driverAdded(roverId, socket.id, force && isAdmin(socket));
turnService.driverAdded(roverId, socket.id, (force && isAdmin(socket)) || forceTurn);
socket.emit('controlGranted', { roverId });
managerEvents.emit('driver', { socketId: socket.id, roverId, action: 'add' });
sendAlert({
@@ -77,7 +85,10 @@ function createRoverLifecycle(deps) {
function canDrive(roverId, socket) {
const record = rovers.get(roverId);
if (!record) return false;
const denied = getControlDenialReason(record, socket, { allowUser: true });
const denied = getControlDenialReason(record, socket, {
allowUser: true,
allowClosedPrivateGrantInLockdown: true,
});
if (denied) return false;
const _mode = getMode();
if (isAdmin(socket)) return true;
@@ -116,10 +127,13 @@ function createRoverLifecycle(deps) {
return false;
}
function canSwitchRover(socket, targetRoverId) {
function canSwitchRover(socket, targetRoverId, options = {}) {
const target = rovers.get(targetRoverId);
if (!target) return { ok: false, message: 'Unknown rover' };
const denied = getControlDenialReason(target, socket, { allowUser: true });
const denied = getControlDenialReason(target, socket, {
allowUser: true,
allowClosedPrivateGrantInLockdown: Boolean(options.allowClosedPrivateGrantInLockdown),
});
if (denied) return { ok: false, message: denied };
const currentId = getPrimaryRoverForSocket(socket.id);
if (!currentId || currentId === targetRoverId) return { ok: true, currentId };
@@ -57,15 +57,20 @@ function registerSocketHandlers(deps) {
throw new Error('No rovers available');
}
const previousJoined = getRoversForSocket(socket.id);
const allowClosedPrivateGrantInLockdown = true;
if (!isAdmin(socket)) {
const { ok, message } = canSwitchRover(socket, targetId);
const { ok, message } = canSwitchRover(socket, targetId, { allowClosedPrivateGrantInLockdown });
if (!ok) {
throw new Error(message || 'Switch denied');
}
}
const forceAllowed = Boolean(force) && isAdmin(socket);
logger.info('Request control', socket.id, targetId, { force: forceAllowed });
requestControl(targetId, socket, { force: forceAllowed, allowUser: true });
requestControl(targetId, socket, {
force: forceAllowed,
allowUser: true,
allowClosedPrivateGrantInLockdown,
});
previousJoined.forEach((rid) => {
if (rid !== targetId) {
releaseControl(rid, socket);