mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-17 01:50:47 -04:00
139 lines
4.4 KiB
JavaScript
139 lines
4.4 KiB
JavaScript
// rover Manager private access
|
|
// Purpose: Encapsulates private-rover visibility and control-authorization policy checks.
|
|
// Scope: Keeps runtime behavior unchanged while isolating policy decisions from orchestration wiring.
|
|
function createPrivateAccessPolicy(deps) {
|
|
const {
|
|
io,
|
|
turnService,
|
|
MODES,
|
|
getMode,
|
|
isAdmin,
|
|
isLockdownAdmin,
|
|
normalizePrivateSafety,
|
|
DEFAULT_PRIVATE_SAFETY,
|
|
} = deps;
|
|
|
|
function parsePrivateMeta(meta = {}) {
|
|
const raw = meta?.private;
|
|
if (raw === true) {
|
|
return { enabled: true, safety: { ...DEFAULT_PRIVATE_SAFETY } };
|
|
}
|
|
if (!raw || typeof raw !== 'object') {
|
|
return { enabled: false, safety: { ...DEFAULT_PRIVATE_SAFETY } };
|
|
}
|
|
const safety = normalizePrivateSafety(raw.safety || {});
|
|
return {
|
|
enabled: Boolean(raw.enabled),
|
|
safety,
|
|
};
|
|
}
|
|
|
|
function isPrivateRecord(record) {
|
|
return Boolean(record?.private?.enabled);
|
|
}
|
|
|
|
function isPrivateOpen(record) {
|
|
if (!isPrivateRecord(record)) return true;
|
|
return Boolean(record?.privateOpen);
|
|
}
|
|
|
|
function getPrivateSafety(record) {
|
|
if (!record) return { ...DEFAULT_PRIVATE_SAFETY };
|
|
return normalizePrivateSafety(record.privateSafety || record.private?.safety || {});
|
|
}
|
|
|
|
function shouldApplyPrivateSafety(record, socket) {
|
|
if (!isPrivateRecord(record)) return false;
|
|
if (isLockdownAdmin(socket)) return false;
|
|
return true;
|
|
}
|
|
|
|
function shouldApplyPrivateSensorSafety(record) {
|
|
if (!isPrivateRecord(record)) return false;
|
|
const activeDrivers = turnService.getActiveDrivers();
|
|
const activeDriverId = activeDrivers?.[record.id];
|
|
if (!activeDriverId) return false;
|
|
const activeSocket = io.sockets.sockets.get(activeDriverId);
|
|
if (!activeSocket) return true;
|
|
return !isLockdownAdmin(activeSocket);
|
|
}
|
|
|
|
function socketHasClosedPrivateAccess(socket, roverId) {
|
|
const list = Array.isArray(socket?.data?.privateClosedAccessRovers)
|
|
? socket.data.privateClosedAccessRovers
|
|
: [];
|
|
return list.some((id) => String(id) === String(roverId));
|
|
}
|
|
|
|
function isRoverVisibleToSocket(record, socket) {
|
|
if (!record) return false;
|
|
if (!isPrivateRecord(record)) return true;
|
|
if (isPrivateOpen(record)) return true;
|
|
if (isLockdownAdmin(socket)) return true;
|
|
if (socket?.id && record.drivers?.has(socket.id)) return true;
|
|
return socketHasClosedPrivateAccess(socket, record.id);
|
|
}
|
|
|
|
function getControlDenialReason(record, socket, options = {}) {
|
|
const {
|
|
allowUser = false,
|
|
allowClosedPrivateGrantInLockdown = false,
|
|
allowClosedPrivateCurrentDriver = 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) &&
|
|
!(
|
|
allowClosedPrivateGrantInLockdown &&
|
|
isPrivateRecord(record) &&
|
|
!isPrivateOpen(record) &&
|
|
socketHasClosedPrivateAccess(socket, record.id)
|
|
) &&
|
|
!(
|
|
allowClosedPrivateCurrentDriver &&
|
|
isPrivateRecord(record) &&
|
|
!isPrivateOpen(record)
|
|
)
|
|
) {
|
|
return 'Server in lockdown';
|
|
}
|
|
const { isDeterred } = require('../verificationService');
|
|
if (!isAdmin(socket) && isDeterred(socket)) return 'Not authorized';
|
|
if (!isPrivateRecord(record)) return null;
|
|
if (!isPrivateOpen(record)) {
|
|
if (!isLockdownAdmin(socket)) {
|
|
if (allowClosedPrivateCurrentDriver) return null;
|
|
if (socketHasClosedPrivateAccess(socket, record.id)) return null;
|
|
return 'Private rover is closed';
|
|
}
|
|
return null;
|
|
}
|
|
if (isLockdownAdmin(socket)) return null;
|
|
const { isVerified } = require('../verificationService');
|
|
if (!isVerified(socket)) return 'Private rover requires verification';
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
parsePrivateMeta,
|
|
isPrivateRecord,
|
|
isPrivateOpen,
|
|
getPrivateSafety,
|
|
shouldApplyPrivateSafety,
|
|
shouldApplyPrivateSensorSafety,
|
|
socketHasClosedPrivateAccess,
|
|
isRoverVisibleToSocket,
|
|
getControlDenialReason,
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
createPrivateAccessPolicy,
|
|
};
|