Source: models/roles.js


/**
 * Class handles roles in basedata and offers methods to deal with roles in core database
 * @class
 */
class roles {
  /**
   * @constructor
   * @param {*} alogger ususally req.app.logger, logger to be used for output of class instance to the central log
   */
  constructor(alogger) {
    // always initialize all instance properties
    this.logger = alogger;
  }

  /**
   * Returns a list of all roles in core database
   * @param {function} callback rows or null
   */
  getListOfRoles(callback) {
    this.logger.debug('MODELS-ROLES | Reading Roles');
    let query = "SELECT * FROM `roles`";
    global.coreDb.all(query, [], (err, rows) => {
      if (err) {
        this._logger.error('MODELS-ROLES | Error loading roles from core data: ' + err.message);
        return callback(null);
      } else {
        return callback(rows);
      }
    });
  }

  /**
   * Returns one single Role from core database
   * @param {integer} rId id of role to be loaded
   * @param {function} callback row or null
   */
  getRoleForId(rId, callback) {
    this.logger.debug('MODELS-ROLES | Reading Role');
    let query = "SELECT * FROM `roles` WHERE id = ?";
    global.coreDb.all(query, [
      rId
    ], (err, rows) => {
      if (err) {
        this._logger.error('MODELS-ROLES | Error loading role for id ' + rId + ' from core data: ' + err.message);
        return callback(null);
      } else {
        return callback(rows);
      }
    });
  }


  /**
   * 
   * @param {integer} basedataId id of basedata roles to be returned for
   * @param {function} callback rows or null
   */
  getListOfRolesForBaseData(basedataId, callback) {
    this.logger.debug('MODELS-ROLES | reading Roles for basedata record with id ' + basedataId + ' is referenced for');
    let query = "SELECT roleId FROM xt_basedata_roles WHERE basedataId = ?";
    global.coreDb.all(query, [
      basedataId
    ], (err, rows) => {
      if (err) {
        this._logger.error('MODELS-ROLES | Error loading roles for basedataId ' + basedataId + ' from core data: ' + err.message);
        return callback(null);
      } else {
        return callback(rows);
      }
    });
  }

  /**
   * Adds a new role to core database
   * @param {string} roleName Name of new role to be added
   * @param {function} callback success true or false
   */
  addRole(roleName, callback) {
    this.doesRoleExist(roleName, (roleExists) => {
      if ((roleExists !== null) && (roleExists !== true)) {
        // role seems not to exist -> add role to core database
        let query = "INSERT INTO `roles` (rolename) VALUES (?)";
        global.coreDb.run(query, [
          roleName
        ], function (err) {
          if (err) {
            console.log('ERROR Adding new role to core database: ' + err.message);
            callback(false);
          } else {
            callback(true);
          }
        });
      } else {
        // can not add group as group exists or check could not be performed
        callback(false);
      }
    })
  }

  /**
   * Updates a role in core database
   * @param {integer} rId id of role to be updated
   * @param {string} roleName new role name
   * @param {function} callback success, true or false
   */
  updateRole(rId, roleName, callback) {
    this.doesRoleExist(roleName, (bolExists) => {
      if (bolExists !== true) {
        let query = "UPDATE `roles` SET `rolename` = ? WHERE `roles`.`id` = ?";
        global.coreDb.run(query, [
          roleName,
          rId
        ], function (err) {
          if (err) {
            console.log('ERROR Updating role with id ' + rId + ' in core database: ' + err.message);
            return callback(false);
          } else {
            return callback(true);
          }
        })
      } else {
        return callback(false);
      }
    })
  }

  /**
   * Deletes a role from core database
   * @param {integer} rId id of role to be deleted in core database
   * @param {*} callback success, true or false
   */
  deleteRole(rId, callback) {
    let query = "DELETE FROM roles WHERE id = ?";
    global.coreDb.run(query, [
      rId
    ], function (err) {
      if (err) {
        console.log('ERROR Deleting role with id ' + rId + ' in core database: ' + err.message);
        return callback(false);
      } else {
        return callback(true);
      }
    })
  }

  /**
   * Checks if a role exists in database or not
   * @param {string} roleName Name of role
   * @param {function} callback true if role exists, false if not
   */
  doesRoleExist(roleName, callback) {
    let query = "SELECT * FROM roles WHERE rolename = ?";
    global.coreDb.all(query, [
      roleName
    ], (err, rows) => {
      if (err) {
        this._logger.error(`ROLES-MODEL | Error checking for existing role: ${err.message}`);
        return callback(null);
      } else {
        if (rows.length > 0) {
          return callback(true);
        } else {
          return callback(false);
        }
      }
    });
  }

  /**
   * Deletes all assigned roles for given basedata id
   * @param {integer} basedataId basedata id the roles shall be deleted for
   * @param {*} callback success (true / false)
   */
  deleteRolesforBasedataId(basedataId, callback) {
    let query = "DELETE FROM xt_basedata_roles WHERE basedataId = ?";
    global.coreDb.run(query, [
      basedataId
    ], function (err) {
      if (err) {
        console.log(`ERROR Deleting roles for basedata id ${basedataId} in core database: ${err.message}`);
        return callback(false);
      } else {
        return callback(true);
      }
    })
  }


  /**
   * Assigns roles (role-ids) to a basedata entry in core database
   * @param {array} rolesArray array with role-id's to be added
   * @param {integer} basedataId id of basedata entry in core database
   * @param {function} callback success (true / false)
   */
  assignRolesToBasedata(rolesArray, basedataId, callback) {
    this.logger.debug('MODELS-ROLES | Assigning Role(s) to user with basedataid: ' + basedataId);
    let valuesPart = '';

    this.deleteRolesforBasedataId(basedataId, (success) => {
      if (success) {
        // existing roles for basedata haben been deleted in core database
        if (Array.isArray(rolesArray)) {
          let values = [];
          rolesArray.forEach(role => {
            values.push('(' + basedataId + ', ' + role[0] + ')');
          });
          valuesPart = values.join(',');
        } else {
          valuesPart = '(' + basedataId + ', ' + rolesArray + ') ';
        }

        if (valuesPart.length > 1) {
          let insertQuery = "INSERT INTO xt_basedata_roles (basedataId, roleId) VALUES " + valuesPart + ";";
          console.log(insertQuery);
          global.coreDb.run(insertQuery, [
          ], function (err) {
            if (err) {
              this.logger.error(`MODELS-ROLES | Error inserting basedata reference in roles table for basedataId ${basedataId}`);
              return callback(false);
            } else {
              return callback(true);
            }
          })
        } else {
          callback(true);
        }
      } else {
        return callback(null);
      }
    });

    /* MySql Version (deprecated)
    db.query(delQuery, (errRoles, resultRoles) => {
      if (errRoles) {
        // Errror loading organizations
        this.logger.info('MODELS-ROLES | Error deleting basedata reference in groups table for basedataId ' + basedataId);
        return null;
      } else {
        if (Array.isArray(rolesArray)) {
          let values = [];
          rolesArray.forEach(role => {
            values.push('(' + basedataId + ', ' + role[0] + ')');
          });
          valuesPart = values.join(',');
        } else {
          valuesPart = '(' + basedataId + ', ' + rolesArray + ') ';
        }

        if (valuesPart.length > 1) {
          let insertQuery = "INSERT INTO xt_basedata_roles (basedataId, roleId) VALUES " + valuesPart + ";";
          db.query(insertQuery, (errRoles, resultRoles) => {
            if (errRoles) {
              // Errror loading organizations
              this.logger.error('MODELS-ROLES | Error inserting basedata reference in roles table for basedataId ' + basedataId);
              callback(req, res);
            } else {
              callback(req, res);
            }
          });
        } else {
          callback(req, res);
        }
      }
    });
    */
  }

}

// export the class
module.exports = roles;