fix #LINQT-1799 secured status of conversation based on security level of all participants

fix manage participants
This commit is contained in:
Gaelle Braud 2025-08-05 12:20:07 +02:00
parent a7f3476568
commit da2ea7d114
9 changed files with 79 additions and 36 deletions

View file

@ -135,6 +135,12 @@ ChatCore::ChatCore(const std::shared_ptr<linphone::ChatRoom> &chatRoom) : QObjec
mEphemeralLifetime = chatRoom->ephemeralEnabled() ? chatRoom->getEphemeralLifetime() : 0;
mIsMuted = chatRoom->getMuted();
mParticipants = buildParticipants(chatRoom);
connect(this, &ChatCore::participantsChanged, this, [this] {
// refresh secured status of the chatroom
setIsSecured(computeSecuredStatus());
});
mIsSecured = computeSecuredStatus();
}
ChatCore::~ChatCore() {
@ -186,6 +192,7 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
});
mChatModelConnection->makeConnectToModel(
&ChatModel::deleted, [this]() { mChatModelConnection->invokeToCore([this]() { emit deleted(); }); });
mChatModelConnection->makeConnectToModel(
&ChatModel::stateChanged,
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom, linphone::ChatRoom::State newState) {
@ -196,6 +203,12 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
setIsReadOnly(isReadOnly);
});
});
mChatModelConnection->makeConnectToModel(
&ChatModel::conferenceJoined, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() { setParticipants(participants); });
});
// Events (excluding messages)
mChatModelConnection->makeConnectToModel(
@ -336,33 +349,24 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
mChatModelConnection->invokeToCore([this, subject]() { setTitle(subject); });
});
mChatModelConnection->makeConnectToModel(&ChatModel::participantAdded,
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() {
mParticipants = participants;
emit participantsChanged();
});
});
mChatModelConnection->makeConnectToModel(&ChatModel::participantRemoved,
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() {
mParticipants = participants;
emit participantsChanged();
});
});
mChatModelConnection->makeConnectToModel(&ChatModel::participantAdminStatusChanged,
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() {
mParticipants = participants;
emit participantsChanged();
});
});
mChatModelConnection->makeConnectToModel(
&ChatModel::participantAdded, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() { setParticipants(participants); });
});
mChatModelConnection->makeConnectToModel(
&ChatModel::participantRemoved, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() { setParticipants(participants); });
});
mChatModelConnection->makeConnectToModel(
&ChatModel::participantAdminStatusChanged, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) {
auto participants = buildParticipants(chatRoom);
mChatModelConnection->invokeToCore([this, participants]() { setParticipants(participants); });
});
mChatModelConnection->makeConnectToCore(&ChatCore::lRemoveParticipantAtIndex, [this](int index) {
mChatModelConnection->invokeToModel([this, index]() { mChatModel->removeParticipantAtIndex(index); });
});
@ -632,6 +636,25 @@ bool ChatCore::getMeAdmin() const {
return mMeAdmin;
}
bool ChatCore::isSecured() const {
return mIsSecured;
}
void ChatCore::setIsSecured(bool secured) {
if (mIsSecured != secured) {
mIsSecured = secured;
emit isSecuredChanged();
}
}
bool ChatCore::computeSecuredStatus() const {
if (mParticipants.size() == 0) return false;
for (auto &participant : mParticipants) {
if (participant->getSecurityLevel() != LinphoneEnums::SecurityLevel::EndToEndEncryptedAndVerified) return false;
}
return true;
}
QVariantList ChatCore::getParticipantsGui() const {
QVariantList result;
for (auto participantCore : mParticipants) {
@ -649,6 +672,12 @@ QStringList ChatCore::getParticipantsAddresses() const {
return result;
}
void ChatCore::setParticipants(QList<QSharedPointer<ParticipantCore>> participants) {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
mParticipants = participants;
emit participantsChanged();
}
QList<QSharedPointer<ParticipantCore>>
ChatCore::buildParticipants(const std::shared_ptr<linphone::ChatRoom> &chatRoom) const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));

View file

@ -56,6 +56,7 @@ public:
Q_PROPERTY(bool isGroupChat READ isGroupChat CONSTANT)
Q_PROPERTY(bool isEncrypted READ isEncrypted CONSTANT)
Q_PROPERTY(bool isReadOnly READ getIsReadOnly WRITE setIsReadOnly NOTIFY readOnlyChanged)
Q_PROPERTY(bool isSecured READ isSecured WRITE setIsSecured NOTIFY isSecuredChanged)
Q_PROPERTY(QString sendingText READ getSendingText WRITE setSendingText NOTIFY sendingTextChanged)
Q_PROPERTY(bool ephemeralEnabled READ isEphemeralEnabled WRITE lEnableEphemeral NOTIFY ephemeralEnabledChanged)
Q_PROPERTY(
@ -119,6 +120,10 @@ public:
bool getMeAdmin() const;
void setMeAdmin(bool admin);
bool isSecured() const;
void setIsSecured(bool secured);
bool computeSecuredStatus() const;
QList<QSharedPointer<EventLogCore>> getEventLogList() const;
void resetEventLogList(QList<QSharedPointer<EventLogCore>> list);
void appendEventLogToEventLogList(QSharedPointer<EventLogCore> event);
@ -137,6 +142,7 @@ public:
std::shared_ptr<ChatModel> getModel() const;
QSharedPointer<SafeConnection<ChatCore, ChatModel>> getChatModelConnection() const;
void setParticipants(QList<QSharedPointer<ParticipantCore>> participants);
QList<QSharedPointer<ParticipantCore>> buildParticipants(const std::shared_ptr<linphone::ChatRoom> &chatRoom) const;
QList<QSharedPointer<ParticipantCore>> getParticipants() const;
QVariantList getParticipantsGui() const;
@ -166,6 +172,7 @@ signals:
void meAdminChanged();
void participantsChanged();
void fileListChanged();
void isSecuredChanged();
void lDeleteMessage(ChatMessageGui *message);
void lDelete();
@ -203,6 +210,9 @@ private:
bool mIsEncrypted = false;
bool mIsReadOnly = false;
bool mEphemeralEnabled = false;
// ChatRoom is secured if all its participants are
// EndToEndEncryptedAndVerified friends
bool mIsSecured = false;
int mEphemeralLifetime = 0;
QList<QSharedPointer<ChatMessageContentCore>> mFileList;
bool mIsMuted = false;

View file

@ -53,6 +53,9 @@ ParticipantCore::ParticipantCore(const std::shared_ptr<linphone::Participant> &p
mCreationTime = QDateTime::fromSecsSinceEpoch(participant->getCreationTime());
mDisplayName = Utils::coreStringToAppString(participantAddress->getDisplayName());
if (mDisplayName.isEmpty()) mDisplayName = ToolModel::getDisplayName(participantAddress->clone());
auto isFriend = ToolModel::findFriendByAddress(participantAddress->clone());
mSecurityLevel =
isFriend ? LinphoneEnums::fromLinphone(isFriend->getSecurityLevel()) : LinphoneEnums::SecurityLevel::None;
for (auto &device : participant->getDevices()) {
auto name = Utils::coreStringToAppString(device->getName());
auto address = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly());
@ -76,7 +79,7 @@ void ParticipantCore::setSelf(QSharedPointer<ParticipantCore> me) {
connect(this, &ParticipantCore::sipAddressChanged, this, &ParticipantCore::updateIsMe);
}
int ParticipantCore::getSecurityLevel() const {
LinphoneEnums::SecurityLevel ParticipantCore::getSecurityLevel() const {
return mSecurityLevel;
}
@ -165,7 +168,7 @@ void ParticipantCore::setIsFocus(const bool &focus) {
}
}
void ParticipantCore::setSecurityLevel(int level) {
void ParticipantCore::setSecurityLevel(LinphoneEnums::SecurityLevel level) {
if (level != mSecurityLevel) {
mSecurityLevel = level;
emit securityLevelChanged();

View file

@ -45,7 +45,7 @@ class ParticipantCore : public QObject, public AbstractObject {
Q_PROPERTY(bool isMe READ isMe NOTIFY isMeChanged)
Q_PROPERTY(QDateTime creationTime READ getCreationTime CONSTANT)
Q_PROPERTY(bool focus READ isFocus CONSTANT)
Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
Q_PROPERTY(LinphoneEnums::SecurityLevel securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
Q_PROPERTY(int deviceCount READ getDeviceCount NOTIFY deviceCountChanged)
Q_PROPERTY(QList<QVariant> devices READ getParticipantDevices NOTIFY deviceChanged)
@ -62,7 +62,7 @@ public:
QDateTime getCreationTime() const;
bool isAdmin() const;
bool isFocus() const;
int getSecurityLevel() const;
LinphoneEnums::SecurityLevel getSecurityLevel() const;
int getDeviceCount() const;
bool isMe() const;
@ -75,7 +75,7 @@ public:
void setCreationTime(const QDateTime &date);
void setIsAdmin(const bool &status);
void setIsFocus(const bool &focus);
void setSecurityLevel(int level);
void setSecurityLevel(LinphoneEnums::SecurityLevel level);
QList<QVariant> getParticipantDevices();
@ -116,7 +116,7 @@ private:
QDateTime mCreationTime;
bool mAdminStatus;
bool mIsFocus;
int mSecurityLevel;
LinphoneEnums::SecurityLevel mSecurityLevel;
bool mIsMe;
DECLARE_ABSTRACT_OBJECT

View file

@ -28,7 +28,6 @@ ColumnLayout {
Text {
id: text
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
text: labelButton.label
font {
pixelSize: Typography.p1.pixelSize

View file

@ -176,7 +176,7 @@ ListView {
property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.peerAddress)
contact: contactObj?.value || null
displayNameVal: contact ? undefined : modelData.core.avatarUri
secured: modelData.core.isEncrypted
secured: modelData.core.isSecured
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp)
// isConference: modelData.core.isConference

View file

@ -93,6 +93,7 @@ FocusScope {
property var contactObj: mainItem.chat ? UtilsCpp.findFriendByAddress(mainItem.chat?.core.peerAddress) : null
contact: contactObj?.value || null
displayNameVal: contact ? "" : mainItem.chat?.core.avatarUri
secured: mainItem.chat && mainItem.chat.core.isSecured
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp)
}

View file

@ -25,6 +25,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
contact: contactObj?.value || null
displayNameVal: contact ? "" : mainItem.chatCore.avatarUri
secured: mainItem.chatGui && mainItem.chatGui.core.isSecured
Layout.preferredWidth: Math.round(100 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(100 * DefaultStyle.dp)
PopupButton {

View file

@ -36,7 +36,7 @@ Rectangle {
style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow
onClicked: {
mainItem.chatCore.participantsAddresses = manageParticipantsLayout.selectedParticipants
mainItem.chatCore.lSetParticipantsAddresses(manageParticipantsLayout.selectedParticipants)
mainItem.done()
}
}