Files
xen-orchestra/app/node_modules/xo-api/acl.js
2015-10-28 15:09:08 +01:00

124 lines
2.9 KiB
JavaScript

// These global variables are not a problem because the algorithm is
// synchronous.
let permissionsByObject
let getObject
// -------------------------------------------------------------------
const authorized = () => true // eslint-disable-line no-unused-vars
const forbiddden = () => false // eslint-disable-line no-unused-vars
function and (...checkers) { // eslint-disable-line no-unused-vars
return function (object, permission) {
for (const checker of checkers) {
if (!checker(object, permission)) {
return false
}
}
return true
}
}
function or (...checkers) { // eslint-disable-line no-unused-vars
return function (object, permission) {
for (const checker of checkers) {
if (checker(object, permission)) {
return true
}
}
return false
}
}
// -------------------------------------------------------------------
function checkMember (memberName) {
return function (object, permission) {
const member = object[memberName]
return checkAuthorization(member, permission)
}
}
function checkSelf ({ id }, permission) {
const permissionsForObject = permissionsByObject[id]
return (
permissionsForObject &&
permissionsForObject[permission]
)
}
// ===================================================================
const checkAuthorizationByTypes = {
host: or(checkSelf, checkMember('$poolId')),
message: checkMember('$object'),
network: or(checkSelf, checkMember('$poolId')),
SR: or(checkSelf, checkMember('$poolId')),
task: checkMember('$host'),
VBD: checkMember('VDI'),
// Access to a VDI is granted if the user has access to the
// containing SR or to a linked VM.
VDI (vdi, permission) {
// Check authorization for the containing SR.
if (checkAuthorization(vdi.$SR, permission)) {
return true
}
// Check authorization for each of the connected VMs.
for (const {$VM: vm} of vdi.$VBDs) {
if (checkAuthorization(vm, permission)) {
return true
}
}
return false
},
VIF: or(checkMember('$network'), checkMember('$VM')),
VM: or(checkSelf, checkMember('$container')),
'VM-snapshot': checkMember('snapshot_of'),
'VM-template': authorized
}
function checkAuthorization (objectId, permission) {
const object = getObject(objectId)
const checker = checkAuthorizationByTypes[object.type] || checkSelf
return checker(object, permission)
}
// -------------------------------------------------------------------
export default function (
permissionsByObject_,
getObject_,
permissions
) {
// Assign global variables.
permissionsByObject = permissionsByObject_
getObject = getObject_
try {
for (const [objectId, permission] of permissions) {
if (!checkAuthorization(objectId, permission)) {
return false
}
}
return true
} finally {
// Free the global variables.
permissionsByObject = getObject = null
}
}