From c3fa2c6c1c047e0d50152220584cf14e5e8650ca Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Tue, 29 Oct 2019 09:29:11 +0100 Subject: [PATCH] Implement rsIdentity link import/export --- libretroshare/src/retroshare/rsidentity.h | 90 +++++++++++++++------- libretroshare/src/services/p3idservice.cc | 91 ++++++++++++++++++++--- libretroshare/src/services/p3idservice.h | 30 +++++--- 3 files changed, 163 insertions(+), 48 deletions(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index cc5772e83..ddda6e65a 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -95,14 +95,17 @@ struct GxsReputation : RsSerializable int32_t mPeerOpinion; /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) + void serial_process( + RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override { RS_SERIAL_PROCESS(mOverallScore); RS_SERIAL_PROCESS(mIdScore); RS_SERIAL_PROCESS(mOwnOpinion); RS_SERIAL_PROCESS(mPeerOpinion); } + + ~GxsReputation() override; }; @@ -110,7 +113,6 @@ struct RsGxsIdGroup : RsSerializable { RsGxsIdGroup() : mLastUsageTS(0), mPgpKnown(false), mIsAContact(false) {} - virtual ~RsGxsIdGroup() {} RsGroupMetaData mMeta; @@ -149,6 +151,8 @@ struct RsGxsIdGroup : RsSerializable /// @see RsSerializable void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override; + + ~RsGxsIdGroup() override; }; // DATA TYPE FOR EXTERNAL INTERFACE. @@ -331,8 +335,9 @@ struct RsIdentityDetails : RsSerializable std::map mUseCases; /// @see RsSerializable - virtual void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) + virtual void serial_process( + RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override { RS_SERIAL_PROCESS(mId); RS_SERIAL_PROCESS(mNickname); @@ -344,6 +349,8 @@ struct RsIdentityDetails : RsSerializable RS_SERIAL_PROCESS(mLastUsageTS); RS_SERIAL_PROCESS(mUseCases); } + + ~RsIdentityDetails() override; }; @@ -434,26 +441,6 @@ struct RsIdentity : RsGxsIfaceHelper */ virtual bool isOwnId(const RsGxsId& id) = 0; - /** - * @brief Get base64 representation of an identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[out] base64String storage for the identity base64 - * @return false on error, true otherwise - */ - virtual bool identityToBase64( const RsGxsId& id, - std::string& base64String ) = 0; - - /** - * @brief Import identity from base64 representation - * @jsonapi{development} - * @param[in] base64String base64 representation of the identity to import - * @param[out] id storage for the identity id - * @return false on error, true otherwise - */ - virtual bool identityFromBase64( const std::string& base64String, - RsGxsId& id ) = 0; - /** * @brief Get identities summaries list. * @jsonapi{development} @@ -528,8 +515,55 @@ struct RsIdentity : RsGxsIfaceHelper */ virtual bool requestIdentity(const RsGxsId& id) = 0; + /// default base URL used for indentity links @see exportIdentityLink + static const std::string DEFAULT_IDENTITY_BASE_URL; - RS_DEPRECATED + /// Link query field used to store indentity name @see exportIdentityLink + static const std::string IDENTITY_URL_NAME_FIELD; + + /// Link query field used to store indentity id @see exportIdentityLink + static const std::string IDENTITY_URL_ID_FIELD; + + /// Link query field used to store indentity data @see exportIdentityLink + static const std::string IDENTITY_URL_DATA_FIELD; + + /** + * @brief Get link to a identity + * @jsonapi{development} + * @param[out] link storage for the generated link + * @param[in] id Id of the identity of which you want to generate a link + * @param[in] includeGxsData if true include the identity GXS group data so + * the receiver can make use of the identity even if she hasn't received it + * through GXS yet + * @param[in] baseUrl URL into which to sneak in the RetroShare link + * radix, this is primarly useful to induce applications into making the + * link clickable, or to disguise the RetroShare link into a + * "normal" looking web link. If empty the GXS data link will be outputted + * in plain base64 format. + * @param[out] errMsg optional storage for error message, meaningful only in + * case of failure + * @return false if something failed, true otherwhise + */ + virtual bool exportIdentityLink( + std::string& link, const RsGxsId& id, + bool includeGxsData = true, + const std::string& baseUrl = RsIdentity::DEFAULT_IDENTITY_BASE_URL, + std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; + + /** + * @brief Import identity from full link + * @param[in] link identity link either in radix or link format + * @param[out] id optional storage for parsed identity + * @param[out] errMsg optional storage for error message, meaningful only in + * case of failure + * @return false if some error occurred, true otherwise + */ + virtual bool importIdentityLink( + const std::string& link, + RsGxsId& id = RS_DEFAULT_STORAGE_PARAM(RsGxsId), + std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; + + RS_DEPRECATED_FOR(exportIdentityLink) virtual bool getGroupSerializedData( const uint32_t& token, std::map& serialized_groups ) = 0; @@ -547,10 +581,10 @@ struct RsIdentity : RsGxsIfaceHelper RS_DEPRECATED virtual uint32_t nbRegularContacts() =0; - RS_DEPRECATED_FOR(identityToBase64) + RS_DEPRECATED_FOR(exportIdentityLink) virtual bool serialiseIdentityToMemory( const RsGxsId& id, std::string& radix_string ) = 0; - RS_DEPRECATED_FOR(identityFromBase64) + RS_DEPRECATED_FOR(importIdentityLink) virtual bool deserialiseIdentityFromMemory( const std::string& radix_string, RsGxsId* id = nullptr ) = 0; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index dc2d53cb3..0821f3286 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -817,10 +817,6 @@ bool p3IdService::isKnownId(const RsGxsId& id) std::find(mOwnIds.begin(), mOwnIds.end(),id) != mOwnIds.end(); } -bool p3IdService::identityToBase64( const RsGxsId& id, - std::string& base64String ) -{ return serialiseIdentityToMemory(id, base64String); } - bool p3IdService::serialiseIdentityToMemory( const RsGxsId& id, std::string& radix_string ) { @@ -882,10 +878,6 @@ void p3IdService::handle_get_serialized_grp(uint32_t token) mSerialisedIdentities[RsGxsId(id)] = s ; } -bool p3IdService::identityFromBase64( - const std::string& base64String, RsGxsId& id ) -{ return deserialiseIdentityFromMemory(base64String, &id); } - bool p3IdService::deserialiseIdentityFromMemory(const std::string& radix_string, RsGxsId* id /* = nullptr */) { @@ -4717,15 +4709,89 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel* } } +/*static*/ const std::string RsIdentity::DEFAULT_IDENTITY_BASE_URL = + "retroshare:///identities"; +/*static*/ const std::string RsIdentity::IDENTITY_URL_NAME_FIELD = "identityName"; +/*static*/ const std::string RsIdentity::IDENTITY_URL_ID_FIELD = "identityId"; +/*static*/ const std::string RsIdentity::IDENTITY_URL_DATA_FIELD = "identityData"; + +bool p3IdService::exportIdentityLink( + std::string& link, const RsGxsId& id, bool includeGxsData, + const std::string& baseUrl, std::string& errMsg ) +{ + constexpr auto fname = __PRETTY_FUNCTION__; + const auto failure = [&](const std::string& err) + { + errMsg = err; + RsErr() << fname << " " << err << std::endl; + return false; + }; + + if(id.isNull()) return failure("id cannot be null"); + + const bool outputRadix = baseUrl.empty(); + if(outputRadix && !includeGxsData) return + failure("includeGxsData must be true if format requested is base64"); + + if( includeGxsData && + !RsGenExchange::exportGroupBase64( + link, reinterpret_cast(id), errMsg ) ) + return failure(errMsg); + + if(outputRadix) return true; + + std::vector idsInfo; + if( !getIdentitiesInfo(std::set({id}), idsInfo ) + || idsInfo.empty() ) + return failure("failure retrieving identity information"); + + RsUrl inviteUrl(baseUrl); + inviteUrl.setQueryKV(IDENTITY_URL_ID_FIELD, id.toStdString()); + inviteUrl.setQueryKV(IDENTITY_URL_NAME_FIELD, idsInfo[0].mMeta.mGroupName); + if(includeGxsData) inviteUrl.setQueryKV(IDENTITY_URL_DATA_FIELD, link); + + link = inviteUrl.toString(); + return true; +} + +bool p3IdService::importIdentityLink( + const std::string& link, RsGxsId& id, std::string& errMsg ) +{ + constexpr auto fname = __PRETTY_FUNCTION__; + const auto failure = [&](const std::string& err) + { + errMsg = err; + RsErr() << fname << " " << err << std::endl; + return false; + }; + + if(link.empty()) return failure("link is empty"); + + const std::string* radixPtr(&link); + + RsUrl url(link); + const auto& query = url.query(); + const auto qIt = query.find(IDENTITY_URL_DATA_FIELD); + if(qIt != query.end()) radixPtr = &qIt->second; + + if(radixPtr->empty()) return failure(IDENTITY_URL_DATA_FIELD + " is empty"); + + if(!RsGenExchange::importGroupBase64( + *radixPtr, reinterpret_cast(id), errMsg )) + return failure(errMsg); + + return true; +} + + void RsGxsIdGroup::serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) { RS_SERIAL_PROCESS(mMeta); RS_SERIAL_PROCESS(mPgpIdHash); - //RS_SERIAL_PROCESS(mPgpIdSign); - RS_SERIAL_PROCESS(mRecognTags); - //RS_SERIAL_PROCESS(mImage); + RS_SERIAL_PROCESS(mPgpIdSign); + RS_SERIAL_PROCESS(mImage); RS_SERIAL_PROCESS(mLastUsageTS); RS_SERIAL_PROCESS(mPgpKnown); RS_SERIAL_PROCESS(mIsAContact); @@ -4798,3 +4864,6 @@ RsIdentityUsage::RsIdentityUsage() : RsIdentity::~RsIdentity() = default; RsReputationInfo::~RsReputationInfo() = default; RsGixs::~RsGixs() = default; +RsIdentityDetails::~RsIdentityDetails() = default; +GxsReputation::~GxsReputation() = default; +RsGxsIdGroup::~RsGxsIdGroup() = default; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 0b8f433b6..26121cd8a 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -293,13 +293,32 @@ public: /// @see RsIdentity bool getOwnPseudonimousIds(std::vector& ids) override; + /// @see RsIdentity bool getOwnIds( std::list &ownIds, bool signed_only = false ) override; + /// @see RsIdentity bool isKnownId(const RsGxsId& id) override; + /// @see RsIdentity bool isOwnId(const RsGxsId& key_id) override; + /// @see RsIdentity + bool exportIdentityLink( + std::string& link, const RsGxsId& id, + bool includeGxsData = true, + const std::string& baseUrl = DEFAULT_IDENTITY_BASE_URL, + std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) + ) override; + + /// @see RsIdentity + bool importIdentityLink( + const std::string& link, + RsGxsId& id = RS_DEFAULT_STORAGE_PARAM(RsGxsId), + std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) + ) override; + + virtual bool signData( const uint8_t* data, uint32_t data_size, const RsGxsId& signer_id, @@ -354,17 +373,10 @@ public: const RsIdentityUsage &use_info ); virtual bool requestPrivateKey(const RsGxsId &id); - - /// @see RsIdentity - bool identityToBase64( const RsGxsId& id, - std::string& base64String ) override; - - /// @see RsIdentity - bool identityFromBase64( const std::string& base64String, - RsGxsId& id ) override; - + RS_DEPRECATED_FOR(exportIdentityLink) virtual bool serialiseIdentityToMemory(const RsGxsId& id, std::string& radix_string); + RS_DEPRECATED_FOR(importIdentityLink) virtual bool deserialiseIdentityFromMemory(const std::string& radix_string, RsGxsId* id = nullptr);