diff --git a/src/account.cpp b/src/account.cpp index 8098a88115d66821f3eef0f57a413c2be79f7ab1..a0ccd40e699894cbcd08faba98cf03915f766133 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -395,6 +395,10 @@ CredentialModel* Account::credentialModel() const { if (!d_ptr->m_pCredentials) { d_ptr->m_pCredentials = new CredentialModel(const_cast<Account*>(this)); + connect(d_ptr->m_pCredentials, &CredentialModel::primaryCredentialChanged,[this]() { + Account* a = const_cast<Account*>(this); + emit a->changed(a); + }); } return d_ptr->m_pCredentials; } @@ -617,8 +621,8 @@ QString Account::password() const { switch (protocol()) { case Account::Protocol::SIP: - if (credentialModel()->rowCount()) - return credentialModel()->data(credentialModel()->index(0,0),CredentialModel::Role::PASSWORD).toString(); + if (credentialModel()->primaryCredential(Credential::Type::SIP)) + return credentialModel()->primaryCredential(Credential::Type::SIP)->password(); break; case Account::Protocol::IAX: return d_ptr->accountDetail(DRing::Account::ConfProperties::PASSWORD); @@ -1417,8 +1421,10 @@ void Account::setPassword(const QString& detail) { switch (protocol()) { case Account::Protocol::SIP: - if (credentialModel()->rowCount()) - credentialModel()->setData(credentialModel()->index(0,0),detail,CredentialModel::Role::PASSWORD); + if (credentialModel()->primaryCredential(Credential::Type::SIP)) { + credentialModel()->primaryCredential(Credential::Type::SIP)->setPassword(detail); + credentialModel() << CredentialModel::EditAction::MODIFY; + } else { const QModelIndex idx = credentialModel()->addCredentials(Credential::Type::SIP); credentialModel()->setData(idx,detail,CredentialModel::Role::PASSWORD); diff --git a/src/account.h b/src/account.h index 8598fbfc5d3b7f2e3f0b32f3f0421843d25ee3f2..d13c96e2bd5f10fbbcd551b9824e63b0f75a33fe 100644 --- a/src/account.h +++ b/src/account.h @@ -89,6 +89,7 @@ class LIB_EXPORT Account : public ItemBase { friend class ContactMethod; friend class Certificate; friend class NetworkInterfaceModelPrivate; + friend class CredentialModelPrivate; //Properties Q_PROPERTY(QByteArray id READ id ) diff --git a/src/credential.cpp b/src/credential.cpp index 506299aacf75732c6973b6859108213f1a1157f8..69aedbb7d56cd51d7ae3a842326213b88fc3e5f2 100644 --- a/src/credential.cpp +++ b/src/credential.cpp @@ -58,16 +58,22 @@ FlagPack<Credential::Type> Credential::type() const void Credential::setRealm(const QString& value) { d_ptr->m_Realm = value; + emit realmChanged(d_ptr->m_Realm); + emit changed(); } void Credential::setUsername(const QString& value) { d_ptr->m_Username = value; + emit usernameChanged(d_ptr->m_Username); + emit changed(); } void Credential::setPassword(const QString& value) { d_ptr->m_Password = value; + emit passwordChanged(d_ptr->m_Password); + emit changed(); } void Credential::setType(const FlagPack<Type>& value) diff --git a/src/credential.h b/src/credential.h index 0beb88f9fdf29d82945e0bc82afed77065531a27..78557378a7ee7b8f0f8ce2cfec166d1e9dfb5717 100644 --- a/src/credential.h +++ b/src/credential.h @@ -17,20 +17,28 @@ ***************************************************************************/ #pragma once +#include <QtCore/QObject> #include <typedefs.h> struct CredentialPrivate; ///A set of credential to be used by an account -class LIB_EXPORT Credential final +class LIB_EXPORT Credential final : public QObject { + Q_OBJECT public: enum class Type { SIP , STUN, - TURN //Does this exist? + TURN, //Does this exist? + COUNT__ }; + //Property + Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) + Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) + Q_PROPERTY(QString realm READ realm WRITE setRealm NOTIFY realmChanged ) + //Constructor explicit Credential(const FlagPack<Credential::Type>& t); ~Credential(); @@ -47,6 +55,12 @@ public: void setPassword(const QString& value ); void setType (const FlagPack<Type>& value ); +Q_SIGNALS: + void changed(); + void usernameChanged(const QString&); + void passwordChanged(const QString&); + void realmChanged (const QString&); + private: CredentialPrivate* d_ptr; }; diff --git a/src/credentialmodel.cpp b/src/credentialmodel.cpp index fac046a95ae4891d98f92ca40cf47e60d59d0aa0..9ff4c7d8ab99c871ecadd27301aae08b7a961fef 100644 --- a/src/credentialmodel.cpp +++ b/src/credentialmodel.cpp @@ -24,6 +24,7 @@ //Ring #include <account.h> #include <private/matrixutils.h> +#include <private/account_p.h> //Dring #include "dbus/configurationmanager.h" @@ -54,7 +55,7 @@ struct CredentialNode final }; void free_node(CredentialNode* n); -class CredentialModelPrivate +class CredentialModelPrivate final { public: @@ -305,9 +306,11 @@ CredentialNode* CredentialModelPrivate::getCategory(Credential::Type type) m_pTurnCat = createCat(QStringLiteral("TURN")); return m_pTurnCat; case Credential::Type::STUN: - if (m_pStunCat) + if (!m_pStunCat) m_pStunCat = createCat(QStringLiteral("STUN")); return m_pStunCat; + case Credential::Type::COUNT__: + break; } return nullptr; @@ -328,6 +331,17 @@ QModelIndex CredentialModel::addCredentials(Credential::Type type) node->m_Index = par->m_uContent.m_Category.m_lChildren->size(); par->m_uContent.m_Category.m_lChildren->append(node); + connect(node->m_uContent.m_Cred.m_pCredential, &Credential::changed,[this, node, par, type]() { + const QModelIndex parIdx = index(par->m_Index,0); + const QModelIndex idx = index(node->m_Index,0,parIdx); + emit dataChanged(idx, idx); + + if (!node->m_Index) { + Credential* c = node->m_uContent.m_Cred.m_pCredential; + emit primaryCredentialChanged(type, c); + } + }); + endInsertRows(); this << EditAction::MODIFY; @@ -373,26 +387,40 @@ void CredentialModelPrivate::clear() void CredentialModelPrivate::save() { ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance(); - VectorMapStringString toReturn; - for (int i=0; i < q_ptr->rowCount();i++) { - const QModelIndex& idx = q_ptr->index(i,0); - MapStringString credentialData; - QString user = q_ptr->data(idx,CredentialModel::Role::NAME).toString(); - QString realm = q_ptr->data(idx,CredentialModel::Role::REALM).toString(); - if (user.isEmpty()) { - user = m_pAccount->username(); - q_ptr->setData(idx,user,CredentialModel::Role::NAME); + + //SIP creds + if (m_pSipCat) { + VectorMapStringString toReturn; + + foreach (CredentialNode* n, *m_pSipCat->m_uContent.m_Category.m_lChildren) { + Credential* cred = n->m_uContent.m_Cred.m_pCredential; + + if (cred->username().isEmpty()) + cred->setUsername(m_pAccount->username()); + + if (cred->realm().isEmpty()) + cred->setRealm(QStringLiteral("*")); + + toReturn << MapStringString { + { DRing::Account::ConfProperties::USERNAME, cred->username() }, + { DRing::Account::ConfProperties::PASSWORD, cred->password() }, + { DRing::Account::ConfProperties::REALM , cred->realm () }, + }; } - if (realm.isEmpty()) { - realm = '*'; - q_ptr->setData(idx,realm,CredentialModel::Role::REALM); + configurationManager.setCredentials(m_pAccount->id(),toReturn); + } + + //TURN creds + if (m_pTurnCat) { + foreach (CredentialNode* n, *m_pSipCat->m_uContent.m_Category.m_lChildren) { + Credential* cred = n->m_uContent.m_Cred.m_pCredential; + + m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TURN::SERVER_UNAME , cred->username()); + m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TURN::SERVER_PWD , cred->password()); + m_pAccount->d_ptr->setAccountProperty(DRing::Account::ConfProperties::TURN::SERVER_REALM , cred->realm ()); } - credentialData[ DRing::Account::ConfProperties::USERNAME ] = user; - credentialData[ DRing::Account::ConfProperties::PASSWORD ] = q_ptr->data(idx,CredentialModel::Role::PASSWORD).toString(); - credentialData[ DRing::Account::ConfProperties::REALM ] = realm; - toReturn << credentialData; } - configurationManager.setCredentials(m_pAccount->id(),toReturn); + m_EditState = CredentialModel::EditState::READY; } @@ -402,7 +430,10 @@ void CredentialModelPrivate::reload() if (!m_pAccount->isNew()) { clear(); m_EditState = CredentialModel::EditState::LOADING; + ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance(); + + //SIP const VectorMapStringString credentials = configurationManager.getCredentials(m_pAccount->id()); for (int i=0; i < credentials.size(); i++) { const QModelIndex& idx = q_ptr->addCredentials(Credential::Type::SIP); @@ -410,6 +441,18 @@ void CredentialModelPrivate::reload() q_ptr->setData(idx,credentials[i][ DRing::Account::ConfProperties::PASSWORD ],CredentialModel::Role::PASSWORD); q_ptr->setData(idx,credentials[i][ DRing::Account::ConfProperties::REALM ],CredentialModel::Role::REALM ); } + + //TURN + const QModelIndex& idx = q_ptr->addCredentials(Credential::Type::TURN); + const QString usern = m_pAccount->d_ptr->accountDetail(DRing::Account::ConfProperties::TURN::SERVER_UNAME); + const QString passw = m_pAccount->d_ptr->accountDetail(DRing::Account::ConfProperties::TURN::SERVER_PWD ); + const QString realm = m_pAccount->d_ptr->accountDetail(DRing::Account::ConfProperties::TURN::SERVER_REALM); + + if (!(usern.isEmpty() && passw.isEmpty() && realm.isEmpty())) { + q_ptr->setData(idx, usern, CredentialModel::Role::NAME ); + q_ptr->setData(idx, passw, CredentialModel::Role::PASSWORD); + q_ptr->setData(idx, realm, CredentialModel::Role::REALM ); + } } m_EditState = CredentialModel::EditState::READY; } @@ -449,3 +492,25 @@ bool CredentialModel::performAction(const CredentialModel::EditAction action) d_ptr->performAction(action); return curState != d_ptr->m_EditState; } + +Credential* CredentialModel::primaryCredential(Credential::Type type) const +{ + switch(type) { + case Credential::Type::STUN: + if (d_ptr->m_pStunCat && d_ptr->m_pStunCat->m_uContent.m_Category.m_lChildren->size()) + return d_ptr->m_pStunCat->m_uContent.m_Category.m_lChildren->first()->m_uContent.m_Cred.m_pCredential; + break; + case Credential::Type::TURN: + if (d_ptr->m_pTurnCat && d_ptr->m_pTurnCat->m_uContent.m_Category.m_lChildren->size()) + return d_ptr->m_pTurnCat->m_uContent.m_Category.m_lChildren->first()->m_uContent.m_Cred.m_pCredential; + break; + case Credential::Type::SIP: + if (d_ptr->m_pSipCat && d_ptr->m_pSipCat->m_uContent.m_Category.m_lChildren->size()) + return d_ptr->m_pSipCat->m_uContent.m_Category.m_lChildren->first()->m_uContent.m_Cred.m_pCredential; + break; + case Credential::Type::COUNT__: + break; + } + + return nullptr; +} diff --git a/src/credentialmodel.h b/src/credentialmodel.h index 625e57ff2bee362b71d75db1a185150740db8d54..8d99fc2b4ca1029312cfc36b0d23072c58663ce7 100644 --- a/src/credentialmodel.h +++ b/src/credentialmodel.h @@ -23,6 +23,7 @@ //Qt #include <QtCore/QString> +class QItemSelectionModel; //Ring #include <credential.h> @@ -83,10 +84,14 @@ public: //Getter CredentialModel::EditState editState() const; + Credential* primaryCredential(Credential::Type type = Credential::Type::SIP) const; //Operator CredentialModel* operator<<(CredentialModel::EditAction& action); +Q_SIGNALS: + void primaryCredentialChanged(Credential::Type type, Credential* c); + private: QScopedPointer<CredentialModelPrivate> d_ptr; Q_DECLARE_PRIVATE(CredentialModel) diff --git a/src/private/account_p.h b/src/private/account_p.h index 44fbc5aff086b356c26060ee404fce8e4ecf138d..afa3f50e9e6ef79eacb5d17e9d47685e22dd3071 100644 --- a/src/private/account_p.h +++ b/src/private/account_p.h @@ -64,6 +64,7 @@ public: friend class ContactMethod; friend class Certificate; friend class NetworkInterfaceModelPrivate; + friend class CredentialModelPrivate; //Constructor explicit AccountPrivate(Account* acc);