/* global __appdir */ var path = require('path') var express = require('express') var router = express.Router() var noAuthRouter = express.Router() var db = require(path.join(__appdir, 'lib', 'sequelize')) const ExternalBackends = require(path.join(__appdir, 'lib', 'external-backends')) // GET requests. /* * TODO: CURRENTLY TEST FUNCTION */ router.get('/', (req, res) => { db.backend.findOne({ where: { id: 1 } }).then(result => { const b = new ExternalBackends() const instance = b.getInstance(result.type) instance.getClient(result.credentials, {}).then(result => { res.status(200).send(result) }) }) }) module.exports.router = router // GET requests. // POST requests. /* * Returns all root parents or all childs of a group. * * @return: Ipxe menu with a list of groups. */ noAuthRouter.post('/group', (req, res) => { const id = req.body.id var parents = [] if (req.body.parents) parents = JSON.parse(req.body.parents) if (id === '0') { db.group.findAll({ where: { '$parents.id$': null }, include: ['parents'] }).then(groups => { if (groups) { res.send(buildIpxeMenu(id, 'Root', groups, [])) } else { res.status(404).end() } }) } else { db.group.findOne({ where: { id: id }, include: ['parents', 'subgroups', 'clients'] }).then(group => { if (group) { res.send(buildIpxeMenu(id, group.name, group.subgroups, parents)) } else { res.status(404).end() } }) } }) /* * Adds the client in the database and set parents if a parent was selected. */ noAuthRouter.post('/add', (req, res) => { const mac = req.body.mac const uuid = req.body.uuid const ip = req.body.ip const name = req.body.name const parentId = req.body.id db.client.findOne({ where: { uuid: uuid } }).then(client => { if (client) res.status(200).send('#!ipxe\r\necho Client already exists\r\necho Press any key to continue ...\r\nread x\r\nreboot') else { db.client.create({ name: name, ip: ip, mac: mac, uuid: uuid }).then(client => { if (parentId) { client.addGroup(parentId) } res.send('#!ipxe\r\nreboot') }) } }) }) module.exports.noAuthRouter = noAuthRouter /* * id: id of the current selected location. * name: Name of the current selected location * groups: List of group [{ id: , name: }, ...] * * Build the ipxe menu out of the list of groups. * Used by the manual registration. */ function buildIpxeMenu (id, name, groups, parents) { var script = '#!ipxe\r\n' // script = script.concat(`console --picture \${img} --x 800 --y 600 || shell\r\n`) // Add parent to keep track of the path we clicked through. var parentId = 0 var oldParents = parents.slice(0) if (parents.length > 0) { parentId = oldParents[oldParents.length - 1].id oldParents.length = oldParents.length - 1 } parents.push({ id: id, name: toAscii(name) }) script += `set space:hex 20:20\r\n` script += `set space \${space:string}\r\n` script += `set parents ` + JSON.stringify(parents) + '\r\n\r\n' // Menu var menuscript = '' script += ':start\r\n' script += 'menu Choose the group you want the client to be saved in\r\n' // Parent menu entries. var spacer = '' parents.forEach(parent => { script += 'item --gap ' + spacer + '[' + parent.id + '] ' + parent.name + '\r\n' spacer += `\${space}` }) // Back button script += 'item --key b back ' + spacer + '..\r\n' menuscript += ':back\r\nparams\r\nparam id ' + parentId + '\r\nparam parents ' + JSON.stringify(oldParents) + '\r\n' menuscript += 'chain --replace https://bas.stfu-kthx.net:8888/api/registrations/group##params\r\n\r\n' // Group menu entries. First 1-9 are pressable via key? var counter = '1' groups.forEach(group => { script += 'item --key ' + counter + ' ' + counter + ' ' + spacer + '[' + group.id + '] ' + toAscii(group.name) + '\r\n' menuscript += ':' + counter + '\r\n' + 'params\r\nparam id ' + group.id + `\r\nparam parents \${parents}\r\n` menuscript += 'chain --replace https://bas.stfu-kthx.net:8888/api/registrations/group##params\r\n\r\n' counter++ }) // Menu seperator script += 'item --gap\r\n' // Add client menu script += 'item select Add client to ' + toAscii(name) + '\r\n' menuscript += `:select\r\necho Enter client name\r\nread clientname\r\nparams\r\nparam name \${clientname}\r\n` menuscript += 'param id ' + id + `\r\nparam mac \${net0/mac}\r\nparam uuid \${uuid}\r\nparam ip \${net0/ip}\r\n` menuscript += 'chain --replace https://bas.stfu-kthx.net:8888/api/registrations/add##params\r\n\r\n' // Goto start menu if (id !== '0') { script += 'item reset Go to start\r\n' menuscript += ':reset\r\nparams\r\nparam id ' + 0 + '\r\nchain --replace https://bas.stfu-kthx.net:8888/api/registrations/group##params\r\n\r\n' } // Exit menu script += 'item exit Exit manual registration\r\n' menuscript += ':exit\r\nexit 1\r\n\r\n' // Concat script + menuscript and return it. script += `choose target && goto \${target}\r\n\r\n` script += menuscript return script } function toAscii (string) { string = string.replace('ü', 'ue') string = string.replace('ö', 'oe') string = string.replace('ä', 'ae') return ascii(string) } /* eslint-disable */ var escapable = /[\\"\x00-\x1f\x7f-\uffff]/g /* eslint-enable */ var meta = { // table of character substitutions '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' } function ascii (string) { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. escapable.lastIndex = 0 return escapable.test(string) ? string.replace(escapable, function (a) { var c = meta[a] return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4) }) : string }