mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
commit
d1b86400bc
@ -21,6 +21,7 @@
|
||||
* *
|
||||
*******************************************************************************/
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "pqi/pqihash.h"
|
||||
#include "rsgenexchange.h"
|
||||
@ -38,8 +39,7 @@
|
||||
#include "rsgxsutil.h"
|
||||
#include "rsserver/p3face.h"
|
||||
#include "retroshare/rsevents.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "util/radix64.h"
|
||||
|
||||
#define PUB_GRP_MASK 0x000f
|
||||
#define RESTR_GRP_MASK 0x00f0
|
||||
@ -3445,6 +3445,71 @@ bool RsGenExchange::localSearch( const std::string& matchString,
|
||||
return mNetService->search(matchString, results);
|
||||
}
|
||||
|
||||
bool RsGenExchange::exportGroupBase64(
|
||||
std::string& radix, const RsGxsGroupId& groupId, 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(groupId.isNull()) return failure("groupId cannot be null");
|
||||
|
||||
const std::list<RsGxsGroupId> groupIds({groupId});
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||
uint32_t token;
|
||||
mDataAccess->requestGroupInfo(
|
||||
token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds);
|
||||
RsTokenService::GxsRequestStatus wtStatus = mDataAccess->waitToken(token);
|
||||
if(wtStatus != RsTokenService::COMPLETE)
|
||||
return failure( "waitToken(...) failed with: " +
|
||||
std::to_string(wtStatus) );
|
||||
|
||||
uint8_t* buf = nullptr;
|
||||
uint32_t size;
|
||||
RsGxsGroupId grpId;
|
||||
if(!getSerializedGroupData(token, grpId, buf, size))
|
||||
return failure("failed retrieving GXS data");
|
||||
|
||||
Radix64::encode(buf, static_cast<int>(size), radix);
|
||||
free(buf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGenExchange::importGroupBase64(
|
||||
const std::string& radix, RsGxsGroupId& groupId,
|
||||
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(radix.empty()) return failure("radix is empty");
|
||||
|
||||
std::vector<uint8_t> mem = Radix64::decode(radix);
|
||||
if(mem.empty()) return failure("radix seems corrupted");
|
||||
|
||||
// On success this also import the group as pending validation
|
||||
if(!deserializeGroupData(
|
||||
mem.data(), static_cast<uint32_t>(mem.size()),
|
||||
reinterpret_cast<RsGxsGroupId*>(&groupId) ))
|
||||
return failure("failed deserializing group");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RsGxsChanges::RsGxsChanges() :
|
||||
RsEvent(RsEventType::GXS_CHANGES), mServiceType(RsServiceType::NONE),
|
||||
mService(nullptr) {}
|
||||
|
||||
RsGxsIface::~RsGxsIface() = default;
|
||||
RsGxsGroupSummary::~RsGxsGroupSummary() = default;
|
||||
|
@ -95,7 +95,8 @@ typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsGxsMsgItem*> > GxsMsgRelatedDa
|
||||
|
||||
class RsGixs;
|
||||
|
||||
class RsGenExchange : public RsNxsObserver, public RsTickingThread, public RsGxsIface
|
||||
class RsGenExchange : public RsNxsObserver, public RsTickingThread,
|
||||
public RsGxsIface
|
||||
{
|
||||
public:
|
||||
|
||||
@ -325,6 +326,19 @@ public:
|
||||
bool localSearch( const std::string& matchString,
|
||||
std::list<RsGxsGroupSummary>& results );
|
||||
|
||||
/// @see RsGxsIface
|
||||
bool exportGroupBase64(
|
||||
std::string& radix, const RsGxsGroupId& groupId,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// @see RsGxsIface
|
||||
bool importGroupBase64(
|
||||
const std::string& radix,
|
||||
RsGxsGroupId& groupId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
protected:
|
||||
|
||||
bool messagePublicationTest(const RsGxsMsgMetaData&) ;
|
||||
|
@ -404,6 +404,61 @@ public:
|
||||
const std::function<void (const RsGxsGroupSummary& result)>& multiCallback,
|
||||
rstime_t maxWait = 30 ) = 0;
|
||||
|
||||
/// default base URL used for channels links @see exportChannelLink
|
||||
static const std::string DEFAULT_CHANNEL_BASE_URL;
|
||||
|
||||
/// Link query field used to store channel name @see exportChannelLink
|
||||
static const std::string CHANNEL_URL_NAME_FIELD;
|
||||
|
||||
/// Link query field used to store channel id @see exportChannelLink
|
||||
static const std::string CHANNEL_URL_ID_FIELD;
|
||||
|
||||
/// Link query field used to store channel data @see exportChannelLink
|
||||
static const std::string CHANNEL_URL_DATA_FIELD;
|
||||
|
||||
/** Link query field used to store channel message title
|
||||
* @see exportChannelLink */
|
||||
static const std::string CHANNEL_URL_MSG_TITLE_FIELD;
|
||||
|
||||
/// Link query field used to store channel message id @see exportChannelLink
|
||||
static const std::string CHANNEL_URL_MSG_ID_FIELD;
|
||||
|
||||
/**
|
||||
* @brief Get link to a channel
|
||||
* @jsonapi{development}
|
||||
* @param[out] link storage for the generated link
|
||||
* @param[in] chanId Id of the channel of which we want to generate a link
|
||||
* @param[in] includeGxsData if true include the channel GXS group data so
|
||||
* the receiver can subscribe to the channel 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 exportChannelLink(
|
||||
std::string& link, const RsGxsGroupId& chanId,
|
||||
bool includeGxsData = true,
|
||||
const std::string& baseUrl = RsGxsChannels::DEFAULT_CHANNEL_BASE_URL,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Import channel from full link
|
||||
* @param[in] link channel link either in radix or link format
|
||||
* @param[out] chanId optional storage for parsed channel id
|
||||
* @param[out] errMsg optional storage for error message, meaningful only in
|
||||
* case of failure
|
||||
* @return false if some error occurred, true otherwise
|
||||
*/
|
||||
virtual bool importChannelLink(
|
||||
const std::string& link,
|
||||
RsGxsGroupId& chanId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
|
||||
/* Following functions are deprecated as they expose internal functioning
|
||||
* semantic, instead of a safe to use API */
|
||||
|
@ -274,6 +274,54 @@ public:
|
||||
virtual bool cancelCircleMembership(
|
||||
const RsGxsId& ownGxsId, const RsGxsCircleId& circleId ) = 0;
|
||||
|
||||
/// default base URL used for circle links @see exportCircleLink
|
||||
static const std::string DEFAULT_CIRCLE_BASE_URL;
|
||||
|
||||
/// Circle link query field used to store circle name @see exportCircleLink
|
||||
static const std::string CIRCLE_URL_NAME_FIELD;
|
||||
|
||||
/// Circle link query field used to store circle id @see exportCircleLink
|
||||
static const std::string CIRCLE_URL_ID_FIELD;
|
||||
|
||||
/// Circle link query field used to store circle data @see exportCircleLink
|
||||
static const std::string CIRCLE_URL_DATA_FIELD;
|
||||
|
||||
/**
|
||||
* @brief Get link to a circle
|
||||
* @jsonapi{development}
|
||||
* @param[out] link storage for the generated link
|
||||
* @param[in] circleId Id of the circle of which we want to generate a link
|
||||
* @param[in] includeGxsData if true include the circle GXS group data so
|
||||
* the receiver can request circle membership even if the circle hasn't
|
||||
* propagated through GXS to her yet
|
||||
* @param[in] baseUrl URL into which to sneak in the RetroShare circle link
|
||||
* radix, this is primarly useful to induce applications into making the
|
||||
* link clickable, or to disguise the RetroShare circle link into a
|
||||
* "normal" looking web link. If empty the circle 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 exportCircleLink(
|
||||
std::string& link, const RsGxsCircleId& circleId,
|
||||
bool includeGxsData = true,
|
||||
const std::string& baseUrl = RsGxsCircles::DEFAULT_CIRCLE_BASE_URL,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Import circle from full link
|
||||
* @param[in] link circle link either in radix or link format
|
||||
* @param[out] circleId optional storage for parsed circle id
|
||||
* @param[out] errMsg optional storage for error message, meaningful only in
|
||||
* case of failure
|
||||
* @return false if some error occurred, true otherwise
|
||||
*/
|
||||
virtual bool importCircleLink(
|
||||
const std::string& link,
|
||||
RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR("getCirclesSummaries getCirclesInfo")
|
||||
virtual bool getGroupData(
|
||||
const uint32_t& token, std::vector<RsGxsCircleGroup>& groups ) = 0;
|
||||
|
@ -241,6 +241,62 @@ public:
|
||||
virtual bool subscribeToForum( const RsGxsGroupId& forumId,
|
||||
bool subscribe ) = 0;
|
||||
|
||||
/// default base URL used for forums links @see exportForumLink
|
||||
static const std::string DEFAULT_FORUM_BASE_URL;
|
||||
|
||||
/// Link query field used to store forum name @see exportForumLink
|
||||
static const std::string FORUM_URL_NAME_FIELD;
|
||||
|
||||
/// Link query field used to store forum id @see exportForumLink
|
||||
static const std::string FORUM_URL_ID_FIELD;
|
||||
|
||||
/// Link query field used to store forum data @see exportForumLink
|
||||
static const std::string FORUM_URL_DATA_FIELD;
|
||||
|
||||
/** Link query field used to store forum message title
|
||||
* @see exportChannelLink */
|
||||
static const std::string FORUM_URL_MSG_TITLE_FIELD;
|
||||
|
||||
/// Link query field used to store forum message id @see exportChannelLink
|
||||
static const std::string FORUM_URL_MSG_ID_FIELD;
|
||||
|
||||
/**
|
||||
* @brief Get link to a forum
|
||||
* @jsonapi{development}
|
||||
* @param[out] link storage for the generated link
|
||||
* @param[in] forumId Id of the forum of which we want to generate a link
|
||||
* @param[in] includeGxsData if true include the forum GXS group data so
|
||||
* the receiver can subscribe to the forum 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 exportForumLink(
|
||||
std::string& link, const RsGxsGroupId& forumId,
|
||||
bool includeGxsData = true,
|
||||
const std::string& baseUrl = RsGxsForums::DEFAULT_FORUM_BASE_URL,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Import forum from full link
|
||||
* @param[in] link forum link either in radix or URL format
|
||||
* @param[out] forumId optional storage for parsed forum id
|
||||
* @param[out] errMsg optional storage for error message, meaningful only in
|
||||
* case of failure
|
||||
* @return false if some error occurred, true otherwise
|
||||
*/
|
||||
virtual bool importForumLink(
|
||||
const std::string& link,
|
||||
RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create forum. Blocking API.
|
||||
* @jsonapi{development}
|
||||
|
@ -68,6 +68,8 @@ struct RsGxsGroupSummary : RsSerializable
|
||||
RS_SERIAL_PROCESS(mPopularity);
|
||||
RS_SERIAL_PROCESS(mSearchContext);
|
||||
}
|
||||
|
||||
~RsGxsGroupSummary();
|
||||
};
|
||||
|
||||
|
||||
@ -108,8 +110,6 @@ struct RsGxsChanges : RsEvent
|
||||
*/
|
||||
struct RsGxsIface
|
||||
{
|
||||
virtual ~RsGxsIface() {}
|
||||
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
@ -238,4 +238,32 @@ struct RsGxsIface
|
||||
|
||||
virtual RsReputationLevel minReputationForForwardingMessages(
|
||||
uint32_t group_sign_flags,uint32_t identity_flags ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Export group public data in base64 format
|
||||
* @jsonapi{development}
|
||||
* @param[out] radix storage for the generated base64 data
|
||||
* @param[in] groupId Id of the group of which to output the data
|
||||
* @param[out] errMsg optional storage for error message, meaningful only in
|
||||
* case of failure
|
||||
* @return false if something failed, true otherwhise
|
||||
*/
|
||||
virtual bool exportGroupBase64(
|
||||
std::string& radix, const RsGxsGroupId& groupId,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Import group public data from base64 string
|
||||
* @param[in] radix group invite in radix format
|
||||
* @param[out] groupId optional storage for imported group id
|
||||
* @param[out] errMsg optional storage for error message, meaningful only in
|
||||
* case of failure
|
||||
* @return false if some error occurred, true otherwise
|
||||
*/
|
||||
virtual bool importGroupBase64(
|
||||
const std::string& radix,
|
||||
RsGxsGroupId& groupId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||
|
||||
virtual ~RsGxsIface();
|
||||
};
|
||||
|
@ -296,47 +296,7 @@ protected:
|
||||
uint32_t token,
|
||||
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500),
|
||||
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2))
|
||||
{
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||
auto wkStartime = std::chrono::steady_clock::now();
|
||||
int maxWorkAroundCnt = 10;
|
||||
LLwaitTokenBeginLabel:
|
||||
#endif
|
||||
auto timeout = std::chrono::steady_clock::now() + maxWait;
|
||||
auto st = requestStatus(token);
|
||||
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
|
||||
&& std::chrono::steady_clock::now() < timeout )
|
||||
{
|
||||
std::this_thread::sleep_for(checkEvery);
|
||||
st = requestStatus(token);
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||
/* Work around for very slow/old android devices, we don't expect this
|
||||
* to be necessary on newer devices. If it take unreasonably long
|
||||
* something worser is already happening elsewere and we return anyway.
|
||||
*/
|
||||
if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE
|
||||
&& maxWorkAroundCnt-- > 0 )
|
||||
{
|
||||
maxWait *= 10;
|
||||
checkEvery *= 3;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Slow Android device "
|
||||
<< " workaround st: " << st
|
||||
<< " maxWorkAroundCnt: " << maxWorkAroundCnt
|
||||
<< " maxWait: " << maxWait.count()
|
||||
<< " checkEvery: " << checkEvery.count() << std::endl;
|
||||
goto LLwaitTokenBeginLabel;
|
||||
}
|
||||
std::cerr << __PRETTY_FUNCTION__ << " lasted: "
|
||||
<< std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - wkStartime ).count()
|
||||
<< "ms" << std::endl;
|
||||
|
||||
#endif
|
||||
|
||||
return st;
|
||||
}
|
||||
{ return mTokenService.waitToken(token, maxWait, checkEvery); }
|
||||
|
||||
private:
|
||||
RsGxsIface& mGxs;
|
||||
|
@ -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<RsIdentityUsage,rstime_t> 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<RsGxsId,std::string>& 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;
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2012-2012 by Robert Fernie, Chris Evi-Parker *
|
||||
* Copyright (C) 2012 Chris Evi-Parker *
|
||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
@ -19,8 +21,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
#ifndef RSTOKENSERVICE_H
|
||||
#define RSTOKENSERVICE_H
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
@ -28,6 +29,7 @@
|
||||
|
||||
#include "retroshare/rsgxsifacetypes.h"
|
||||
#include "util/rsdeprecate.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
// TODO CLEANUP: GXS_REQUEST_TYPE_* should be an inner enum of RsTokReqOptions
|
||||
#define GXS_REQUEST_TYPE_GROUP_DATA 0x00010000
|
||||
@ -113,7 +115,6 @@ struct RsTokReqOptions
|
||||
*/
|
||||
class RsTokenService
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
enum GxsRequestStatus : uint8_t
|
||||
@ -220,6 +221,59 @@ public:
|
||||
* @return false if unusuccessful in cancelling request, true if successful
|
||||
*/
|
||||
virtual bool cancelRequest(const uint32_t &token) = 0;
|
||||
};
|
||||
|
||||
#endif // RSTOKENSERVICE_H
|
||||
/**
|
||||
* Block caller while request is being processed.
|
||||
* Useful for blocking API implementation.
|
||||
* @param[in] token token associated to the request caller is waiting for
|
||||
* @param[in] maxWait maximum waiting time in milliseconds
|
||||
* @param[in] checkEvery time in millisecond between status checks
|
||||
*/
|
||||
RsTokenService::GxsRequestStatus waitToken(
|
||||
uint32_t token,
|
||||
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500),
|
||||
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2))
|
||||
{
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||
auto wkStartime = std::chrono::steady_clock::now();
|
||||
int maxWorkAroundCnt = 10;
|
||||
LLwaitTokenBeginLabel:
|
||||
#endif
|
||||
auto timeout = std::chrono::steady_clock::now() + maxWait;
|
||||
auto st = requestStatus(token);
|
||||
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
|
||||
&& std::chrono::steady_clock::now() < timeout )
|
||||
{
|
||||
std::this_thread::sleep_for(checkEvery);
|
||||
st = requestStatus(token);
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||
/* Work around for very slow/old android devices, we don't expect this
|
||||
* to be necessary on newer devices. If it take unreasonably long
|
||||
* something worser is already happening elsewere and we return anyway.
|
||||
*/
|
||||
if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE
|
||||
&& maxWorkAroundCnt-- > 0 )
|
||||
{
|
||||
maxWait *= 10;
|
||||
checkEvery *= 3;
|
||||
Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device "
|
||||
<< " workaround st: " << st
|
||||
<< " maxWorkAroundCnt: " << maxWorkAroundCnt
|
||||
<< " maxWait: " << maxWait.count()
|
||||
<< " checkEvery: " << checkEvery.count() << std::endl;
|
||||
goto LLwaitTokenBeginLabel;
|
||||
}
|
||||
Dbg3() << __PRETTY_FUNCTION__ << " lasted: "
|
||||
<< std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - wkStartime ).count()
|
||||
<< "ms" << std::endl;
|
||||
|
||||
#endif
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
||||
};
|
||||
|
@ -2466,6 +2466,85 @@ void p3GxsChannels::cleanTimedOutCallbacks()
|
||||
} // RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex)
|
||||
}
|
||||
|
||||
bool p3GxsChannels::exportChannelLink(
|
||||
std::string& link, const RsGxsGroupId& chanId, 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(chanId.isNull()) return failure("chanId 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, chanId, errMsg) )
|
||||
return failure(errMsg);
|
||||
|
||||
if(outputRadix) return true;
|
||||
|
||||
std::vector<RsGxsChannelGroup> chansInfo;
|
||||
if( !getChannelsInfo(std::list<RsGxsGroupId>({chanId}), chansInfo)
|
||||
|| chansInfo.empty() )
|
||||
return failure("failure retrieving channel information");
|
||||
|
||||
RsUrl inviteUrl(baseUrl);
|
||||
inviteUrl.setQueryKV(CHANNEL_URL_ID_FIELD, chanId.toStdString());
|
||||
inviteUrl.setQueryKV(CHANNEL_URL_NAME_FIELD, chansInfo[0].mMeta.mGroupName);
|
||||
if(includeGxsData) inviteUrl.setQueryKV(CHANNEL_URL_DATA_FIELD, link);
|
||||
|
||||
link = inviteUrl.toString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::importChannelLink(
|
||||
const std::string& link, RsGxsGroupId& chanId, 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(CHANNEL_URL_DATA_FIELD);
|
||||
if(qIt != query.end()) radixPtr = &qIt->second;
|
||||
|
||||
if(radixPtr->empty()) return failure(CHANNEL_URL_DATA_FIELD + " is empty");
|
||||
|
||||
if(!RsGenExchange::importGroupBase64(*radixPtr, chanId, errMsg))
|
||||
return failure(errMsg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/ const std::string RsGxsChannels::DEFAULT_CHANNEL_BASE_URL =
|
||||
"retroshare:///channels";
|
||||
/*static*/ const std::string RsGxsChannels::CHANNEL_URL_NAME_FIELD =
|
||||
"chanName";
|
||||
/*static*/ const std::string RsGxsChannels::CHANNEL_URL_ID_FIELD =
|
||||
"chanId";
|
||||
/*static*/ const std::string RsGxsChannels::CHANNEL_URL_DATA_FIELD =
|
||||
"chanData";
|
||||
/*static*/ const std::string RsGxsChannels::CHANNEL_URL_MSG_TITLE_FIELD =
|
||||
"chanMsgTitle";
|
||||
/*static*/ const std::string RsGxsChannels::CHANNEL_URL_MSG_ID_FIELD =
|
||||
"chanMsgId";
|
||||
|
||||
RsGxsChannelGroup::~RsGxsChannelGroup() = default;
|
||||
RsGxsChannelPost::~RsGxsChannelPost() = default;
|
||||
RsGxsChannels::~RsGxsChannels() = default;
|
||||
|
@ -246,9 +246,24 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
||||
bool subscribeToChannel( const RsGxsGroupId &groupId,
|
||||
bool subscribe ) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::setPostRead
|
||||
/// @see RsGxsChannels
|
||||
virtual bool markRead(const RsGxsGrpMsgIdPair& msgId, bool read);
|
||||
|
||||
/// @see RsGxsChannels
|
||||
bool exportChannelLink(
|
||||
std::string& link, const RsGxsGroupId& chanId,
|
||||
bool includeGxsData = true,
|
||||
const std::string& baseUrl = DEFAULT_CHANNEL_BASE_URL,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// @see RsGxsChannels
|
||||
bool importChannelLink(
|
||||
const std::string& link,
|
||||
RsGxsGroupId& chanId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
virtual bool shareChannelKeys(
|
||||
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers );
|
||||
|
||||
|
@ -339,6 +339,76 @@ bool p3GxsCircles::inviteIdsToCircle( const std::set<RsGxsId>& identities,
|
||||
return editCircle(circleGrp);
|
||||
}
|
||||
|
||||
bool p3GxsCircles::exportCircleLink(
|
||||
std::string& link, const RsGxsCircleId& circleId,
|
||||
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(circleId.isNull()) return failure("circleId cannot be null");
|
||||
|
||||
const bool outputRadix = baseUrl.empty();
|
||||
if(outputRadix && !includeGxsData) return
|
||||
failure("includeGxsData must be true if format requested is base64");
|
||||
|
||||
RsGxsGroupId&& groupId = static_cast<RsGxsGroupId>(circleId);
|
||||
if( includeGxsData &&
|
||||
!RsGenExchange::exportGroupBase64(link, groupId, errMsg) )
|
||||
return failure(errMsg);
|
||||
|
||||
if(outputRadix) return true;
|
||||
|
||||
std::vector<RsGxsCircleGroup> circlesInfo;
|
||||
if( !getCirclesInfo(
|
||||
std::list<RsGxsGroupId>({groupId}), circlesInfo )
|
||||
|| circlesInfo.empty() )
|
||||
return failure("failure retrieving circle information");
|
||||
|
||||
RsUrl inviteUrl(baseUrl);
|
||||
inviteUrl.setQueryKV(CIRCLE_URL_ID_FIELD, circleId.toStdString());
|
||||
inviteUrl.setQueryKV(CIRCLE_URL_NAME_FIELD, circlesInfo[0].mMeta.mGroupName);
|
||||
if(includeGxsData) inviteUrl.setQueryKV(CIRCLE_URL_DATA_FIELD, link);
|
||||
|
||||
link = inviteUrl.toString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsCircles::importCircleLink(
|
||||
const std::string& link, RsGxsCircleId& circleId,
|
||||
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(CIRCLE_URL_DATA_FIELD);
|
||||
if(qIt != query.end()) radixPtr = &qIt->second;
|
||||
|
||||
if(radixPtr->empty()) return failure(CIRCLE_URL_DATA_FIELD + " is empty");
|
||||
|
||||
if(!RsGenExchange::importGroupBase64(
|
||||
*radixPtr, reinterpret_cast<RsGxsGroupId&>(circleId), errMsg) )
|
||||
return failure(errMsg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t p3GxsCircles::circleAuthenPolicy()
|
||||
{
|
||||
uint32_t policy = 0;
|
||||
@ -454,7 +524,8 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
/******************* RsCircles Interface ***************************************/
|
||||
/********************************************************************************/
|
||||
|
||||
bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details)
|
||||
bool p3GxsCircles::getCircleDetails(
|
||||
const RsGxsCircleId& id, RsGxsCircleDetails& details)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_CIRCLES
|
||||
@ -2243,6 +2314,12 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
|
||||
return true ;
|
||||
}
|
||||
|
||||
/*static*/ const std::string RsGxsCircles::DEFAULT_CIRCLE_BASE_URL =
|
||||
"retroshare:///circles";
|
||||
/*static*/ const std::string RsGxsCircles::CIRCLE_URL_NAME_FIELD = "circleName";
|
||||
/*static*/ const std::string RsGxsCircles::CIRCLE_URL_ID_FIELD = "circleId";
|
||||
/*static*/ const std::string RsGxsCircles::CIRCLE_URL_DATA_FIELD = "circleData";
|
||||
|
||||
RsGxsCircles::~RsGxsCircles() = default;
|
||||
RsGxsCircleMsg::~RsGxsCircleMsg() = default;
|
||||
RsGxsCircleDetails::~RsGxsCircleDetails() = default;
|
||||
|
@ -169,14 +169,15 @@ class RsGxsCircleCache
|
||||
|
||||
class PgpAuxUtils;
|
||||
|
||||
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, public GxsTokenQueue, public RsTickEvent
|
||||
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
|
||||
public GxsTokenQueue, public RsTickEvent
|
||||
{
|
||||
public:
|
||||
p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes, p3IdService *identities, PgpAuxUtils *pgpUtils);
|
||||
p3GxsCircles(
|
||||
RsGeneralDataService* gds, RsNetworkExchangeService* nes,
|
||||
p3IdService* identities, PgpAuxUtils* pgpUtils );
|
||||
|
||||
virtual RsServiceInfo getServiceInfo();
|
||||
|
||||
/*********** External Interface ***************/
|
||||
RsServiceInfo getServiceInfo() override;
|
||||
|
||||
/// @see RsGxsCircles
|
||||
bool createCircle(
|
||||
@ -207,6 +208,21 @@ virtual RsServiceInfo getServiceInfo();
|
||||
bool inviteIdsToCircle( const std::set<RsGxsId>& identities,
|
||||
const RsGxsCircleId& circleId ) override;
|
||||
|
||||
/// @see RsGxsCircles
|
||||
bool exportCircleLink(
|
||||
std::string& link, const RsGxsCircleId& circleId,
|
||||
bool includeGxsData = true,
|
||||
const std::string& baseUrl = DEFAULT_CIRCLE_BASE_URL,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// @see RsGxsCircles
|
||||
bool importCircleLink(
|
||||
const std::string& link,
|
||||
RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details);
|
||||
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds);
|
||||
|
||||
|
@ -676,6 +676,72 @@ bool p3GxsForums::subscribeToForum(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsForums::exportForumLink(
|
||||
std::string& link, const RsGxsGroupId& forumId, 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(forumId.isNull()) return failure("forumId 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, forumId, errMsg) )
|
||||
return failure(errMsg);
|
||||
|
||||
if(outputRadix) return true;
|
||||
|
||||
std::vector<RsGxsForumGroup> forumsInfo;
|
||||
if( !getForumsInfo(std::list<RsGxsGroupId>({forumId}), forumsInfo)
|
||||
|| forumsInfo.empty() )
|
||||
return failure("failure retrieving forum information");
|
||||
|
||||
RsUrl inviteUrl(baseUrl);
|
||||
inviteUrl.setQueryKV(FORUM_URL_ID_FIELD, forumId.toStdString());
|
||||
inviteUrl.setQueryKV(FORUM_URL_NAME_FIELD, forumsInfo[0].mMeta.mGroupName);
|
||||
if(includeGxsData) inviteUrl.setQueryKV(FORUM_URL_DATA_FIELD, link);
|
||||
|
||||
link = inviteUrl.toString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsForums::importForumLink(
|
||||
const std::string& link, RsGxsGroupId& forumId, 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(FORUM_URL_DATA_FIELD);
|
||||
if(qIt != query.end()) radixPtr = &qIt->second;
|
||||
|
||||
if(radixPtr->empty()) return failure(FORUM_URL_DATA_FIELD + " is empty");
|
||||
|
||||
if(!RsGenExchange::importGroupBase64(*radixPtr, forumId, errMsg))
|
||||
return failure(errMsg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
|
||||
{
|
||||
std::cerr << "p3GxsForums::createGroup()" << std::endl;
|
||||
@ -1005,6 +1071,19 @@ bool RsGxsForumGroup::canEditPosts(const RsGxsId& id) const
|
||||
id == mMeta.mAuthorId;
|
||||
}
|
||||
|
||||
/*static*/ const std::string RsGxsForums::DEFAULT_FORUM_BASE_URL =
|
||||
"retroshare:///forums";
|
||||
/*static*/ const std::string RsGxsForums::FORUM_URL_NAME_FIELD =
|
||||
"forumName";
|
||||
/*static*/ const std::string RsGxsForums::FORUM_URL_ID_FIELD =
|
||||
"forumId";
|
||||
/*static*/ const std::string RsGxsForums::FORUM_URL_DATA_FIELD =
|
||||
"forumData";
|
||||
/*static*/ const std::string RsGxsForums::FORUM_URL_MSG_TITLE_FIELD =
|
||||
"forumMsgTitle";
|
||||
/*static*/ const std::string RsGxsForums::FORUM_URL_MSG_ID_FIELD =
|
||||
"forumMsgId";
|
||||
|
||||
RsGxsForumGroup::~RsGxsForumGroup() = default;
|
||||
RsGxsForumMsg::~RsGxsForumMsg() = default;
|
||||
RsGxsForums::~RsGxsForums() = default;
|
||||
|
@ -110,6 +110,21 @@ public:
|
||||
virtual bool subscribeToForum( const RsGxsGroupId& forumId,
|
||||
bool subscribe );
|
||||
|
||||
/// @see RsGxsForums
|
||||
bool exportForumLink(
|
||||
std::string& link, const RsGxsGroupId& forumId,
|
||||
bool includeGxsData = true,
|
||||
const std::string& baseUrl = DEFAULT_FORUM_BASE_URL,
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
/// @see RsGxsForums
|
||||
bool importForumLink(
|
||||
const std::string& link,
|
||||
RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||
) override;
|
||||
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups);
|
||||
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs);
|
||||
virtual bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas);
|
||||
|
@ -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<const RsGxsGroupId&>(id), errMsg ) )
|
||||
return failure(errMsg);
|
||||
|
||||
if(outputRadix) return true;
|
||||
|
||||
std::vector<RsGxsIdGroup> idsInfo;
|
||||
if( !getIdentitiesInfo(std::set<RsGxsId>({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<RsGxsGroupId&>(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;
|
||||
|
@ -293,13 +293,32 @@ public:
|
||||
/// @see RsIdentity
|
||||
bool getOwnPseudonimousIds(std::vector<RsGxsId>& ids) override;
|
||||
|
||||
/// @see RsIdentity
|
||||
bool getOwnIds(
|
||||
std::list<RsGxsId> &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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user