diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 7fa23697a..84483af2e 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -420,10 +420,14 @@ public: /** * @brief Update identity data (name, avatar...) * @jsonapi{development} - * @param[in] identityData updated identiy data - * @return false on error, true otherwise + * @param[in] id Id of the identity + * @param[in] name New name of the identity + * @param[in] avatar New avatar for the identity + * @param[in] pseudonimous Set to true to make the identity anonymous. If set to false, updating will require the profile passphrase. + * @param[in] pgpPassword Profile passphrase, if non pseudonymous. + * @return false on error, true otherwise */ - virtual bool updateIdentity(RsGxsIdGroup& identityData) = 0; + virtual bool updateIdentity( const RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) =0; /** * @brief Get identity details, from the cache @@ -637,9 +641,6 @@ public: virtual bool submitOpinion(uint32_t& token, const RsGxsId &id, bool absOpinion, int score) = 0; - RS_DEPRECATED - virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group) = 0; - RS_DEPRECATED virtual bool deleteIdentity(uint32_t& token, RsGxsIdGroup &group) = 0; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index b48a25abd..543a29f43 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -1042,37 +1042,87 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) return true; } -bool p3IdService::updateIdentity(RsGxsIdGroup& identityData) +bool p3IdService::updateIdentity( const RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) { + // 1 - get back the identity group + + std::vector idsInfo; + + if(!getIdentitiesInfo(std::set{ id }, idsInfo)) + return false; + + RsGxsIdGroup& group(idsInfo[0]); + + // 2 - update it with the new information + + group.mMeta.mGroupName = name; + group.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC ; + group.mImage = avatar; + + if(!pseudonimous) + { +#warning csoler 2020-01-21: Backward compatibility issue to fix here in v0.7.0 + + // This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE. + // In order to keep backward compatibility, we'll also add the new value + // When the ID is not PGP linked, the group flag cannot be let empty, so we use PUBLIC. + // + // The correct combination of flags should be: + // PGP-linked: GXS_SERV::FLAGS_PRIVACY_PUBLIC | RSGXSID_GROUPFLAG_REALID + // Anonymous : GXS_SERV::FLAGS_PRIVACY_PUBLIC + + group.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; // this is also equal to RSGXSID_GROUPFLAG_REALID_deprecated + group.mMeta.mGroupFlags |= RSGXSID_GROUPFLAG_REALID; + + // The current version should be able to produce new identities that old peers will accept as well. + // In the future, we need to: + // - set the current group flags here (see above) + // - replace all occurences of RSGXSID_GROUPFLAG_REALID_deprecated by RSGXSID_GROUPFLAG_REALID in the code. + } + else + group.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; + uint32_t token; - if(!updateGroup(token, identityData)) + bool ret = true; + + // Cache pgp passphrase to allow a proper re-signing of the group data + + if(!pseudonimous && !pgpPassword.empty()) + { + if(!rsNotify->cachePgpPassphrase(pgpPassword)) + { + RsErr() << __PRETTY_FUNCTION__ << " Failure caching password" << std::endl; + ret = false; + goto LabelUpdateIdentityCleanup; + } + + if(!rsNotify->setDisableAskPassword(true)) + { + RsErr() << __PRETTY_FUNCTION__ << " Failure disabling password user request" << std::endl; + ret = false; + goto LabelUpdateIdentityCleanup; + } + } + + if(!updateGroup(token, group)) { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group." - << std::endl; - return false; + std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group." << std::endl; + ret = false; + goto LabelUpdateIdentityCleanup; } if(waitToken(token) != RsTokenService::COMPLETE) { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." - << std::endl; - return false; + std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; + ret = false; + goto LabelUpdateIdentityCleanup; } - return true; -} +LabelUpdateIdentityCleanup: + if(!pseudonimous && !pgpPassword.empty()) + rsNotify->clearPgpPassphrase(); -bool p3IdService::updateIdentity(uint32_t& token, RsGxsIdGroup &group) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::updateIdentity()"; - std::cerr << std::endl; -#endif - group.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC ; - - updateGroup(token, group); - - return false; + return ret; } bool p3IdService::deleteIdentity(RsGxsId& id) diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 9f9e03d17..b9efe9888 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -261,10 +261,7 @@ public: virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) override; /// @see RsIdentity - bool updateIdentity(RsGxsIdGroup& identityData) override; - - RS_DEPRECATED - virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group) override; + bool updateIdentity( const RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) override; /// @see RsIdentity bool deleteIdentity(RsGxsId& id) override; diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 187cbfd1f..94d092faf 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -611,8 +611,31 @@ void IdEditDialog::updateId() else mEditGroup.mImage.clear(); - uint32_t dummyToken = 0; - rsIdentity->updateIdentity(mEditGroup); + RsGxsId keyId; + std::string gpg_password; + + if(!mEditGroup.mPgpId.isNull()) + { + std::string gpg_name = rsPeers->getGPGName(rsPeers->getGPGOwnId()); + bool cancelled; + + rsNotify->clearPgpPassphrase(); // just in case + + if(!NotifyQt::getInstance()->askForPassword(tr("Profile password needed.").toStdString(), + gpg_name + " (" + rsPeers->getOwnId().toStdString() + ")", + false, + gpg_password,cancelled)) + { + QMessageBox::critical(NULL,tr("Identity creation failed"),tr("Cannot create an identity linked to your profile without your profile password.")); + return; + } + } + + if(!rsIdentity->updateIdentity(RsGxsId(mEditGroup.mMeta.mGroupId),mEditGroup.mMeta.mGroupName,mEditGroup.mImage,mEditGroup.mPgpId.isNull(),gpg_password)) + { + QMessageBox::critical(NULL,tr("Identity update failed"),tr("Cannot update identity. Something went wrong. Check your profile password.")); + return; + } accept(); }