summaryrefslogblamecommitdiffstats
path: root/server/api/clients.js
blob: 66b6a3f96d64f109694fed9177db8e914b989a35 (plain) (tree)
1
2
3
4
5
6
7
8
9
                     

                                                         
                                                        
                                                                                               
                                
                                                   
                                          
                                                                        
                                                      
                                                                      
 

















                                                                                                                                                 



                                                                               




                                                                                 
  
 
                                             
                                                                     
                                                                                                         
                                          
                                                     






                                                                               
                                                                                                       











                                                                                                



                                                                                                      































                                                                                                    


                                                                                                                               

              
                          











                                                        

                                                    
                        
                                                                                                        





                                                    



                                            
                                   
                                                                        
                                                                        








                                                     
                                               
            
                                               
     
                                             
                                                               
   




                                                                               

                                                                    
                                                                         








                                                                      





                                                                               
/* global __appdir */
var path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
var io = require(path.join(__appdir, 'lib', 'socketio'))
const backendHelper = require(path.join(__appdir, 'lib', 'external-backends', 'backendhelper'))
var express = require('express')
const { decorateApp } = require('@awaitjs/express')
var router = decorateApp(express.Router())
const HttpResponse = require(path.join(__appdir, 'lib', 'httpresponse'))
const log = require(path.join(__appdir, 'lib', 'log'))
const groupHelper = require(path.join(__appdir, 'lib', 'grouphelper'))

// Permission check middleware
router.all(['', '/:id'], async (req, res, next) => {
  switch (req.method) {
    case 'GET':
      if (!await req.user.hasPermission('clients.view')) return res.status(403).send({ error: 'Missing permission', permission: 'clients.view' })
      break

    case 'POST': case 'DELETE':
      if (!await req.user.hasPermission('clients.edit')) return res.status(403).send({ error: 'Missing permission', permission: 'clients.edit' })
      break

    default:
      return res.status(400).send()
  }

  next()
})

// ############################################################################
// ###########################  GET requests  #################################

router.getAsync('', async (req, res) => {
  const includePaths = req.query.path !== undefined && req.query.path !== 'false'
  const include = includePaths ? ['groups'] : []
  let clients = await db.client.findAll({ order: [['name', 'ASC']], include })
  if (includePaths) clients = await groupHelper.addPathsToClients(clients, false)
  res.send(clients)
})

router.getAsync('/:id', async (req, res) => {
  if (!(req.params.id > 0)) return HttpResponse.invalidId().send(res)
  const client = await db.client.findOne({ where: { id: req.params.id }, include: ['groups', 'config'] })
  if (client) res.status(200).send(client)
  else HttpResponse.notFound(req.params.id).send(res)
})

// ############################################################################
// ##########################  POST requests  #################################

router.postAsync(['', '/:id'], async (req, res) => {
  if (req.query.delete !== undefined && req.query.delete !== 'false') {
    if (!Array.isArray(req.body.ids)) return HttpResponse.invalidBodyValue('ids', 'an array').send(res)

    const user = await db.user.findOne({ where: { id: req.user.id } })
    // Only need to log batch request if there is more than one client to delete.
    if (req.body.ids.length > 1) {
      await log({
        category: 'CLIENT_BATCH_DELETE',
        description: 'Batch deletion of ' + req.body.ids.length + ' clients initiated by user.',
        user,
        userId: req.user.id
      })
    }

    // Delete objects from the selected external backends
    const deletedBackendObjects = await backendHelper.deleteClients(req.body.ids, req.body.backendIds)
    const externalDeletionErrors = deletedBackendObjects.filter(x => x.error !== undefined)

    let deletionCounter = 0
    // Delete every client on its own, to get a better log
    for (let index in req.body.ids) {
      const client = await db.client.findOne({ where: { id: req.body.ids[index] } })
      const count = await db.client.destroy({ where: { id: req.body.ids[index] } })
      if (count !== 1) {
        await log({
          category: 'ERROR_CLIENT_DELETE',
          description: 'Client could not be deleted.',
          client,
          user,
          userId: req.user.id
        })
      } else {
        await log({
          category: 'CLIENT_DELETE',
          description: 'Client successfully deleted.',
          client,
          user,
          userId: req.user.id
        })
        deletionCounter++
      }
    }
    if (req.body.ids.length > 1) {
      log({
        category: 'CLIENT_BATCH_DELETE',
        description: deletionCounter + '/' + req.body.ids.length + ' clients successfully deleted.',
        user,
        userId: req.user.id
      })
    }

    if (externalDeletionErrors.length <= 0) HttpResponse.successBatch('deleted', 'client', deletionCounter).send(res)
    else HttpResponse.warningBatch('deleted', 'client', deletionCounter, req.body.ids.length, externalDeletionErrors).send(res)
  } else {
    let client
    let action = 'updated'

    let backendClient = {
      id: req.params.id,
      name: req.body.data.name,
      type: 'CLIENT',
      uuid: req.body.data.uuid,
      parents: req.body.groupIds,
      networks: [
        { ip: req.body.data.ip, mac: req.body.data.mac }
      ]
    }

    if (req.params.id === undefined) {
      client = await db.client.create(req.body.data)
      action = 'created'
      io.in('broadcast newClient').emit('notifications newAlert', { type: 'info', text: 'New client!' })
      log({
        category: 'CLIENT_CREATE',
        description: 'Client successfully created.',
        clientId: client.id,
        userId: req.user.id
      })

      // Add client to the backends
      backendClient.id = client.id
      backendHelper.addClient(backendClient)
    } else if (req.params.id > 0) {
      client = await db.client.findOne({ where: { id: req.params.id } })
      if (!client) return HttpResponse.notFound(req.params.id).send(res)
      else {
        await client.update(req.body.data)
        log({
          category: 'CLIENT_EDIT',
          description: 'Client successfully edited.',
          clientId: client.id,
          userId: req.user.id
        })
      }
      backendHelper.updateClient(backendClient)
    } else {
      return HttpResponse.invalidId().send(res)
    }
    await client.setGroups(req.body.groupIds)
    HttpResponse.success(action, 'client', client.id).send(res)
  }
})

// ############################################################################
// ##########################  DELETE requests  ###############################

router.deleteAsync('/:id', async (req, res) => {
  const client = db.client.findOne({ where: { id: req.params.id } })
  const count = await db.client.destroy({ where: { id: req.params.id } })
  if (count) {
    log({
      category: 'CLIENT_DELETE',
      description: 'Client successfully deleted.',
      client,
      userId: req.user.id
    })
    HttpResponse.success('deleted', 'client', req.params.id).send(res)
  } else HttpResponse.notFound(req.params.id).send(res)
})

// ############################################################################
// ############################################################################

module.exports.router = router