/** * Handler for the HMI language * $Id$ * $HeadURL$ * $Author$ */ #include "object_operator.h" #include "main_handler.h" #include #include #include #include #include namespace OperatorManagement { ObjectOperator::ObjectOperator(MainHandler *mainHandler) : m_mainHandler(mainHandler) , m_originalPrimaryGroupId(0) , m_logger(getLogger("ObjectOperator")) { } ObjectOperator::~ObjectOperator() { m_mainHandler->dds()->dts()->removeUserByKey(m_data.id); } Core::FunctionReplyObject ObjectOperator::createObject(const Database::OpmOperator &data, const QVector &vec) { m_data = data; m_dataExercise = vec; m_originalPrimaryGroupId = data.primaryGroupId; if (m_data.id <= 0) { if (!m_mainHandler->db()->insert(m_data)) return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting operator into database.")); } return updateEffectiveAcls(calculateEffectiveAcls()); } Core::FunctionReplyObject ObjectOperator::updateEffectiveAcls(const QSet &effectiveAcls) { m_effectiveAcls = effectiveAcls; onPublishData(); return Core::FunctionReplyObject(m_data.id); } Core::FunctionReplyObject ObjectOperator::updateExercises(const std::vector &exercises, bool dontUpdateDb) { if (m_exercises == exercises) return Core::FunctionReplyObject(m_data.id); if (dontUpdateDb) { m_exercises = exercises; onPublishData(); return Core::FunctionReplyObject(m_data.id); } // Remove all an set them all new... if (!m_mainHandler->db()->removeOpmOperatorExerciseByOperatorId(m_data.id)) return Core::FunctionReplyObject(0, tr_lts("dds", "Could not remove exercises from operator with id %1 in database.")).arg(m_data.id); m_exercises.clear(); // insert can fail due to (deleted) exerciseId m_mainHandler->db()->setEmitMessageOnError(false); for (int exerciseId : exercises) { Database::OpmOperatorExercise mapping; mapping.operatorId = m_data.id; mapping.exerciseId = exerciseId; bool add_to_map = true; //for (const auto &ooe : copy) for(int i = 0; i< m_dataExercise.size(); ++i) { if (m_dataExercise.at(i).exerciseId != exerciseId) continue; add_to_map = false; mapping.visibleParties = m_dataExercise.at(i).visibleParties; //replace internal vector auto data = m_dataExercise.at(i); data.visibleParties = mapping.visibleParties; m_dataExercise.replace(i,data); } if (mapping.visibleParties().empty()) { DEBUG_LOG(m_logger)<< "Update Operator visible Parties for Execise: No parties found for " << exerciseId << " use default (ex0)"; // Add default visibleParties from ex0 mapping.visibleParties = m_data.visibleParties; } if (!m_mainHandler->db()->insert(mapping)) INFO_LOG(m_logger) << "Can not add operator " << mapping.operatorId << " to exercise " << exerciseId << " - exercise does no longer exist"; else { if (std::find(m_exercises.begin(), m_exercises.end(), exerciseId) == m_exercises.end()) m_exercises.push_back(exerciseId); if (add_to_map) m_dataExercise.push_back(mapping); } } m_mainHandler->db()->setEmitMessageOnError(true); onPublishData(); return Core::FunctionReplyObject(m_data.id); } Core::FunctionReplyObject ObjectOperator::updateObject(const Database::OpmOperator &data) { m_data.name = data.name; DEBUG_LOG(m_logger) << "ObjectOperator::updateObject" << " data.id = " << data.id << " data.rolePresetId = " << data.rolePresetId; m_data.description = data.description; m_data.password = data.password; m_data.image = data.image; m_data.visibleParties = data.visibleParties; m_data.workstationIp = data.workstationIp; m_data.workstationId = data.workstationId; m_data.projectionPriority = data.projectionPriority; m_data.audioChannelPriority = data.audioChannelPriority; m_data.primaryGroupId = m_originalPrimaryGroupId; m_data.rolePresetId = data.rolePresetId; m_data.properties = data.properties; if (!m_mainHandler->db()->update(m_data)) { ERROR_LOG(m_logger)<< "Error updating Operator in database: " << m_mainHandler->db()->getLastError().text(); return Core::FunctionReplyObject(0, tr_lts("dds", "Error updating operator in database.")); } m_data.primaryGroupId = data.primaryGroupId; onPublishData(); return Core::FunctionReplyObject(m_data.id); } Core::FunctionReplyObject ObjectOperator::updateOperatorExercise(const Database::OpmOperatorExercise &data) { DEBUG_LOG(m_logger) << LOGFUNCTION << data.operatorId << " " << data.exerciseId; // insert can fail due to (deleted) exerciseId m_mainHandler->db()->setEmitMessageOnError(false); for (int i=0; i < m_dataExercise.size(); ++i) { DEBUG_LOG(m_logger) << "** m_dataExercise.at(" << i << "): " << m_dataExercise.at(i).exerciseId << "==" << data.exerciseId; if (m_dataExercise.at(i).exerciseId != data.exerciseId) continue; Database::OpmOperatorExercise mapping = m_dataExercise.at(i); mapping.hiddenParties = data.hiddenParties; mapping.visibleParties = data.visibleParties; mapping.properties = data.properties; m_dataExercise.replace(i, mapping); DEBUG_LOG(m_logger) << "** m_dataExercise.at(" << i << "): " << m_dataExercise.at(i).operatorId << ", " << m_dataExercise.at(i).exerciseId << ", " << m_dataExercise.at(i).visibleParties.toPgString() << ", " << m_dataExercise.at(i).hiddenParties.toPgString(); DEBUG_LOG(m_logger) << "** mapping: " << mapping.operatorId << ", " << mapping.exerciseId << ", " << mapping.visibleParties.toPgString() << ", " << mapping.hiddenParties.toPgString(); if (!m_mainHandler->db()->update(mapping)) ERROR_LOG(m_logger)<< "Error updating OperatorExecise in database: " << m_mainHandler->db()->getLastError().text(); } m_mainHandler->db()->setEmitMessageOnError(true); onPublishData(); return Core::FunctionReplyObject(m_data.id); } Core::FunctionReplyObject ObjectOperator::removeObject() { if (!m_mainHandler->db()->removeOpmOperator(m_data.id)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Operator with id %1 can not be removed.")).arg(m_data.id); if (!m_mainHandler->dts()->removeUserByKey(m_data.id)) return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Operator with id %1 can not be taken from DDS.")).arg(m_data.id); return Core::FunctionReplyObject(m_data.id); } Core::FunctionReplyObject ObjectOperator::setPrimaryGroupId(int primaryGroupId) { // Todo: Sanity: Check, if primaryGroupId is type OperatorGroup. m_data.primaryGroupId = primaryGroupId; return updateEffectiveAcls(calculateEffectiveAcls()); } bool ObjectOperator::saveSettings(const QByteArray &settings) { if (!m_settings.id) { QVector tmp; m_mainHandler->db()->selectByOperatorId(tmp, m_data.id); // nothing loaded -> insert new if (tmp.isEmpty()) { m_settings.operatorId = m_data.id; if (!m_mainHandler->db()->insert(m_settings)) return false; } else m_settings = tmp.first(); } m_settings.settings = settings; return m_mainHandler->db()->update(m_settings); } bool ObjectOperator::loadSettings(QByteArray &settings) { if (!m_settings.id) { QVector tmp; if (!m_mainHandler->db()->selectByOperatorId(tmp, m_data.id)) return false; if (!tmp.isEmpty()) m_settings = tmp.first(); m_settings.operatorId = m_data.id; } settings = m_settings.settings; return true; } void ObjectOperator::reloadAcls(bool force) { const QSet calculatedAcls = calculateEffectiveAcls(); // QStringList stringList; // for (int acl : calculatedAcls) // stringList << QString::number(acl); // DEBUG_LOG(m_logger) << "Effective ACLs for Operator " << m_data.name << "(id: " << m_data.id << "): " << stringList.join(QLatin1String(", ")); if (force || m_effectiveAcls != calculatedAcls) updateEffectiveAcls(calculatedAcls); } static inline void addValuesToSet(const QMultiMap &in, const int key, QSet &out) { auto it = in.find(key); while (it != in.end() && it.key() == key) { out += it.value(); ++it; } } QSet ObjectOperator::calculateEffectiveAcls() const { QMultiMap groupMap; QMultiMap allowMap; QMultiMap denyMap; auto cbGroup = [&groupMap] (const Database::OpmGroupGroup &group) { groupMap.insert(group.groupId, group.isMemberOfGroupId); }; m_mainHandler->db()->select(cbGroup); int i = 0; // Initial QList effectiveGroups(groupMap.values(m_data.primaryGroupId)); // Now rekursive while (i < effectiveGroups.size()) { const QList values = groupMap.values(effectiveGroups.at(i++)); for (int value : values) if (!effectiveGroups.contains(value)) effectiveGroups << value; } auto cbAllow = [&allowMap] (const Database::OpmAclAllow &all) { allowMap.insert(all.groupId, all.aclId); }; m_mainHandler->db()->select(cbAllow); auto cbDeny = [&denyMap] (const Database::OpmAclDeny &den) { denyMap.insert(den.groupId, den.aclId); }; m_mainHandler->db()->select(cbDeny); QSet allowances; QSet denials; for (int group : qAsConst(effectiveGroups)) { addValuesToSet(allowMap, group, allowances); addValuesToSet(denyMap, group, denials); } allowances -= denials; return allowances; } void ObjectOperator::onPublishData() { OperatorManagement::User op; op.id(m_data.id); op.name(m_data.name.toStdString()); op.description(m_data.description.toStdString()); op.primaryGroupId(m_data.primaryGroupId); op.rolePresetId(m_data.rolePresetId); op.effectiveAcls() = LtsUtils::convert>(m_effectiveAcls); auto vpbe = toDdsData(m_dataExercise); // Append Visible Parties Template (= exId == 0) QJsonArray adlerAllowedArray; for (int currentParty : m_data.visibleParties()) adlerAllowedArray.append(currentParty); QJsonObject adlerAllowedObject; adlerAllowedObject.insert(QStringLiteral("adlerAllowed"), adlerAllowedArray); QJsonDocument adlerAllowedDocument(adlerAllowedObject); vpbe.push_back(OperatorManagement::PartiesByExercise(0, m_data.visibleParties(), std::vector(), adlerAllowedDocument.toJson(QJsonDocument::Compact).toStdString())); op.visiblePartiesByExercise(vpbe); op.exerciseIds(m_exercises); op.image() = LtsUtils::convert>(m_data.image); op.workstationIp(m_data.workstationIp); op.workstationId(m_data.workstationId.toInt()); op.projectionPriority(m_data.projectionPriority); op.audioChannelPriority(m_data.audioChannelPriority); op.rolePresetId(m_data.rolePresetId); op.properties(m_data.properties.toStdString()); INFO_LOG(m_logger) << "Publish OpmOperator-data to dds (" << m_data.id << " rolePresetId =" << m_data.rolePresetId << ") ..."; if (!m_mainHandler->dts()->publish(op)) ERROR_LOG(m_logger) << "Error publishing OpmOperator-data to dds"; } std::vector ObjectOperator::toDdsData(const QVector &dbData) { std::vector ddsData; for (const Database::OpmOperatorExercise &ooe : dbData) { PartiesByExercise pbe; pbe.exerciseId(ooe.exerciseId); pbe.visibleParties(); pbe.hiddenParties(); std::vector visibleParty; for (const auto &elem : ooe.visibleParties()) { visibleParty.push_back(elem); } pbe.visibleParties().set(visibleParty); std::vector hiddenParty; for (const auto &elem : ooe.hiddenParties()) { hiddenParty.push_back(elem); } pbe.hiddenParties().set(hiddenParty); pbe.properties(ooe.properties.toStdString()); ddsData.push_back(pbe); } return ddsData; } } // Namespace OperatorManagement