summaryrefslogblamecommitdiffstats
path: root/server/api/backends.js
blob: 2fae6bdc818889988734644a8f4b55566bf93289 (plain) (tree)
1
2
3
4
5
6
7
                     
                            
                                                                                 
                                                         
 

                      





                                                                             






                                                                                                                           

                                                   
 




                                                   
                                    










                                                                      
 


                                                            
                                 

                                           
 



                                            
 

                               
 


                                                             
                                





                                        
 























                                                                                                                 



                                                               






                                                                                                                 
      

    




                                                                                                            




                                                               





                                                                   




                                                        
                                        


                                                               

                                                     
                               

                                 

    




                                                                






                                                               































































































































                                                                                                                                                                                     
   
 
 
 

                       








                                       
                             
                                  

                                                                
 
                           
                                      
                                                                                                  

                                              
                                                                                                                                 
     



                                   




                                         
                               
                                  
 
                                                                        

                                     

    









                                                        
                                        
                          
 
                         
                                                                  
                                                               
 
                                
                                                                                
                                      

                                                                        
                                                                                      

        

    







                                                                                   
                                         


                                                    
                              
                                                               
                                                                                                                     


                              
   
 
/* global __appdir */
const path = require('path')
const ExternalBackends = require(path.join(__appdir, 'lib', 'external-backends'))
var db = require(path.join(__appdir, 'lib', 'sequelize'))

// GET requests
module.exports.get = {

  /*
   * ?id=<BACKEND_ID>
   *
   * @return: Returns the credentials structure and fields of a backend type.
   */
  getCredentialsByType: function (req, res) {
    const backendType = req.query.type
    const b = new ExternalBackends()
    const instance = b.getInstance(backendType)
    if (instance === null) {
      res.status(500).send({ auth: false, status: 'TYPE_INVALID', error_message: 'The provided backend type is invalid.' })
    }
    res.status(200).send(instance.getCredentials())
  },

  /*
   * ?id=<BACKEND_ID>
   *
   * @return: Returns the information of a backend.
   */
  getInfoById: function (req, res) {
    const backendId = req.query.id
    db.backend.findOne({ where: { id: backendId } }).then(backend => {
      const b = {
        backendId: backendId,
        backendName: backend.name,
        backendType: backend.type,
        backendCredentials: backend.credentials
      }
      res.status(200).send(b)
    })
  },

  /*
   * @return: Returns a list of all available backend types.
   */
  getTypes: function (req, res) {
    const backends = new ExternalBackends()
    var files = backends.getBackends()

    for (var i = 0; i < files.length; i++) {
      // Cut off -backends.js
      files[i] = files[i].slice(0, -11)
    }

    res.status(200).send(files)
  },

  /*
   * @return: Returns a list of all backends saved in the db.
   */
  getList: function (req, res) {
    db.backend.findAll({
      attributes: ['id', 'name', 'type']
    }).then(function (backends) {
      res.status(200).send(backends)
    })
  },

  /*
   * ?id=<Backend_ID>
   *
   * @return: Returns a list with all objects of the backend.
   */
  getObjects: function (req, res) {
    const id = req.query.id
    db.backend.findOne({ where: { id: id } }).then(backend => {
      if (backend) {
        const ba = new ExternalBackends()
        const instance = ba.getInstance(backend.type)
        instance.getObjects(backend.credentials).then(result => {
          res.status(200).send(result)
        })
      } else res.status(500).send({ status: 'INVALID_BACKEND_ID', error: 'The provided backend id is invalid.' })
    })
  },

  /*
   * ?id=<Backend_ID>
   * ?oid=<OBJECT_ID>
   *
   * @return: Returns information about a given object and all childs.
   */
  getObject: function (req, res) {
    const id = req.query.id
    const oid = req.query.oid
    db.backend.findOne({ where: { id: id } }).then(backend => {
      if (backend) {
        const ba = new ExternalBackends()
        const instance = ba.getInstance(backend.type)
        instance.getObject(backend.credentials, oid).then(result => {
          res.status(200).send(result)
        })
      } else res.status(500).send({ status: 'INVALID_BACKEND_ID', error: 'The provided backend id is invalid.' })
    })
  },

  /*
   * ?id=<Backend_ID>
   *
   * @return: Returns a list of all the object types of the given backend. [{id: <id>, title: <title>}, ...]
   */
  getObjectTypes: function (req, res) {
    const id = req.query.id
    db.backend.findOne({ where: { id: id } }).then(backend => {
      const ba = new ExternalBackends()
      const instance = ba.getInstance(backend.type)
      instance.getObjectTypes(backend.credentials).then(result => {
        res.status(200).send(result)
      })
    })
  },

  /*
   * ?id=<Backend_ID>
   *
   * @return: Returns the sync settings saved in the db.
   */
  getSyncSettings: function (req, res) {
    const id = req.query.id
    var types = {}
    db.backend.findOne({ where: { id: id } }).then(backend => {
      types.groups = JSON.parse(backend.groupTypes)
      types.clients = JSON.parse(backend.clientTypes)
      types.sync = backend.sync
      res.status(200).send(types)
    })
  },

  /*
   * ?id=<Backend_ID>
   *
   * @return: Returns a list of sync types the backend supports.
   */
  getSyncTypes: function (req, res) {
    const id = req.query.id
    db.backend.findOne({ where: { id: id } }).then(backend => {
      const ba = new ExternalBackends()
      const instance = ba.getInstance(backend.type)
      res.status(200).send(instance.getSyncTypes())
    })
  },

  /*
   * ?id: <BACKEND_ID>
   * id: <BACKEND_ID>
   */
  importObjects: function (req, res) {
    const id = req.query.id
    // const id = req.body.id

    // Get the backend where the objects are importet from.
    db.backend.findOne({ where: { id: id } }).then(backend => {
      if (backend) {
        var endRequest = []
        const ba = new ExternalBackends()
        const instance = ba.getInstance(backend.type)
        const groups = JSON.parse(backend.groupTypes).map(x => x.id)
        const clients = JSON.parse(backend.clientTypes).map(x => x.id)

        // Get a list with all objects in the backend.
        const objectPromise = new Promise(function (resolve, reject) {
          resolve(instance.getObjects(backend.credentials))
        })

        objectPromise.then(result => {
          // Check for the not implemented exception
          if (result.status) res.status(501).send(result)

          // Filter those objects in groups / clients
          var groupObjects = []
          var clientObjects = []
          result.objects.filter(obj => {
            if (groups.find(x => x === obj.type)) groupObjects.push({ id: obj.id, name: obj.title, type: obj.type, typeName: obj.type_title, sysid: obj.sysid })
            else if (clients.find(y => y === obj.type)) clientObjects.push({ id: obj.id, name: obj.title, type: obj.type, typeName: obj.type_title, sysid: obj.sysid })
          })

          var promises = []
          var promises2 = []

          // Add all groups in the database.
          groupObjects.forEach(group => {
            // Insert the group.
            promises.push(db.group.create({ name: group.name, description: group.typeName }).then(g => {
              // Insert the backend_x_group relation.
              promises2.push(backend.addMappedGroups(g, { through: { externalId: group.id, externalType: group.type } }))
            }))
          })

          // Add all clients in the databse.
          clientObjects.forEach(client => {
            // Insert the client.
            promises.push(db.client.create({ name: client.name, description: client.typeName }).then(c => {
              // Insert the backend_x_client relation.
              promises2.push(backend.addMappedClients(c, { through: { externalId: client.id, externalType: client.type } }))
            }))
          })

          // Wait till all clients / groups are created and all mapping operations are done. Then add childs.
          Promise.all(promises).then(() => {
            Promise.all(promises2).then(() => {
              // Get the backend with all the mapped groups. ! Only groups can have childs !
              db.backend.findOne({ where: { id: backend.id }, include: ['mappedGroups'] }).then(b => {
                var objectData = []
                // Put all groups in the array to make a one session call which returns all needed informations.
                b.mappedGroups.forEach(mGroup => {
                  const mG = mGroup.backend_x_group
                  const eid = mG.externalId
                  const gid = mGroup.id
                  objectData.push({ eid: eid, gid: gid })
                })

                // Get all the information needed from the backend instance. (For all object ids in the array)
                var promise = new Promise(function (resolve) {
                  resolve(instance.getDataTree(backend.credentials, objectData))
                })

                promise.then(data => {
                  // Check for the not implemented exception
                  if (data.status) res.status(501).send(data)

                  data.forEach(obj => {
                    var groupChildsToAdd = []
                    var clientChildsToAdd = []
                    var prom = []

                    // Put all clientChilds in the clientList and all groupChilds in the groupList.
                    obj.childs.forEach(child => {
                      if (groups.find(x => x === child.type)) {
                        // Get the group id out of the externalId.
                        prom.push(db.backend.findOne({ where: { id: backend.id, '$mappedGroups.backend_x_group.externalId$': child.id }, include: ['mappedGroups'] }).then(ba => {
                          // The externalId should only be once in the db.
                          if (ba.mappedGroups.length === 1) {
                            groupChildsToAdd.push(ba.mappedGroups[0].backend_x_group.groupId)
                          }
                        }))
                      } else if (clients.find(x => x === child.type)) {
                        // Get the client id out of the externalId.
                        prom.push(db.backend.findOne({ where: { id: backend.id, '$mappedClients.backend_x_client.externalId$': child.id }, include: ['mappedClients'] }).then(ba => {
                          // The externalId should only be once in the db.
                          if (ba.mappedClients.length === 1) {
                            clientChildsToAdd.push(ba.mappedClients[0].backend_x_client.clientId)
                          }
                        }))
                      }
                    })

                    // After all the group and client ids are collected. Add them as subgroup / client
                    Promise.all(prom).then(() => {
                      endRequest.push(db.group.findOne({ where: { id: obj.gid } }).then(group => {
                        if (group) {
                          group.addSubgroups(groupChildsToAdd)
                          group.addClients(clientChildsToAdd)
                        }
                      }))
                    })
                  })
                })
              })
            })
          })

          // If all requests are fullfilled. End the request.
          Promise.all(endRequest).then(() => {
            res.status(200).send({ status: 'SUCCESS' })
          })
        })
      } else res.status(500).send({ status: 'INVALID_BACKEND_ID', error: 'The provided backend id is invalid.' })
    })
  }

}

// POST requests
module.exports.post = {

  /*
   * id: <BACKEND_ID>
   * name: <BACKEND_NAME>
   * type: <BACKEND_TYPE>
   * credentials: <BACKEND_CREDENTIALS>
   *
   * Creates or updates the backend.
   */
  save: function (req, res) {
    // Save credentials in the db.
    const backend = req.body
    const credentialString = JSON.stringify(backend.credentials)

    if (backend.id === 0) {
      // Insert new backend in the db.
      db.backend.create({ name: backend.name, type: backend.type, credentials: credentialString })
    } else {
      // Update an existing backend in the db.
      db.backend.update({ name: backend.name, type: backend.type, credentials: credentialString }, { where: { id: backend.id } })
    }

    res.status(200).send('success')
  },

  /*
   * id: <BACKEND_ID>
   *
   * Deletes the backend to the given id.
   */
  delete: function (req, res) {
    const backendIds = req.body.id

    db.backend.destroy({ where: { id: backendIds } }).then(function () {
      res.status(200).send('success')
    })
  },

  /*
   * id: <BACKEND_ID>
   * <OR>
   * name: <BACKEND_NAME>
   * type: <BACKEND_TYPE>
   * credentials: <BACKEND_CREDENTIALS>
   *
   * If the id is set, the backend in the db ist testet.
   * Else the backend is postet in the request.
   */
  checkConnection: function (req, res) {
    const id = req.body.id

    var getBackend = null
    if (id) getBackend = db.backend.findOne({ where: { id: id } })
    else getBackend = new Promise(resolve => resolve(req.body))

    getBackend.then(backend => {
      // Creating the backend instance and calling the specific checkConnection.
      const b = new ExternalBackends()
      const instance = b.getInstance(backend.type)
      instance.checkConnection(backend.credentials).then(connection => {
        res.status(200).send({ success: connection.success, error: connection.error })
      })
    })
  },

  /*
   * id: <BACKEND_ID>
   * groups: <JSON_OF_ASSIGNED_GROUPS> (list of backend types)
   * clients: <JSON_OF_ASSIGNED_CLIENTS> (list of backend types)
   * sync: <SYNC_OPTION>
   *
   * Saves the group / clients assigned object types in the database and sync type.
   */
  saveSyncSettings: function (req, res) {
    const id = req.body.id
    const groups = JSON.stringify(req.body.groups)
    const clients = JSON.stringify(req.body.clients)
    const sync = req.body.sync
    db.backend.findOne({ where: { id: id } }).then(backend => {
      db.backend.update({ groupTypes: groups, clientTypes: clients, sync: sync }, { where: { id: id } }).then(() => {
        res.status(200).send()
      })
    })
  }
}