Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/libretroshare.pro
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,8 @@ message("In rnp_rnplib precompilation code")

win32-g++ {
LIBRNP_OUTPUT_LIBRARY = librnp.dll.a
# mem.cpp uses strlen which requires <cstring>; force-include it for all librnp TUs
LIBRNP_CMAKE_CXXFLAGS *= -include cstring
} else {
LIBRNP_OUTPUT_LIBRARY = librnp.a
}
Expand Down
17 changes: 15 additions & 2 deletions src/retroshare/rsposted.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "retroshare/rsgxscommon.h"
#include "retroshare/rsgxscircles.h"
#include "serialiser/rsserializable.h"
#include "serialiser/rstlvidset.h"

class RsPosted;

Expand All @@ -46,13 +47,23 @@ struct RsPostedGroup: public RsSerializable, RsGxsGenericGroupData
std::string mDescription;
RsGxsImage mGroupImage;

/** @brief List of board pinned posts, those are displayed on top
* @todo run away from TLV old serializables as those types are opaque to
* JSON API! */
RsTlvGxsMsgIdSet mPinnedPosts;

/// @see RsSerializable
virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mDescription);
RS_SERIAL_PROCESS(mGroupImage);

if( mPinnedPosts.ids.empty() && j == RsGenericSerializer::DESERIALIZE
&& ctx.mOffset == ctx.mSize )
return;
RS_SERIAL_PROCESS(mPinnedPosts);
}
};

Expand Down Expand Up @@ -280,7 +291,7 @@ class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService
virtual bool createPost(const RsPostedPost& post,RsGxsMessageId& post_id) =0;

/**
* @brief createPostV2. Create post. Blocking API
* @brief createPostV2. Create or edit a post. Blocking API
* @jsonapi{development}
* @param[in] boardId Id of the board where to post
* @param[in] title title of the post
Expand All @@ -290,6 +301,7 @@ class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService
* @param[in] image optional post image.
* @param[out] postId id of the post after it's been generated
* @param[out] error_message possible error message if the method returns false
* @param[in] origPostId if non-empty, this post replaces the original post with this Id.
* @return true if ok, false if an error occured (see error_message)
*/
virtual bool createPostV2(const RsGxsGroupId& boardId,
Expand All @@ -299,7 +311,8 @@ class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService
const RsGxsId& authorId,
const RsGxsImage& image,
RsGxsMessageId& postId,
std::string& error_message) =0;
std::string& error_message,
const RsGxsMessageId& origPostId = RsGxsMessageId()) =0;

/** @brief Add a comment on a post or on another comment. Blocking API.
* @jsonapi{development}
Expand Down
61 changes: 47 additions & 14 deletions src/rsitems/rsposteditems.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "rsitems/rsposteditems.h"
#include "serialiser/rstypeserializer.h"
#include "rsitems/rsposteditems.h"
#include "serialiser/rstypeserializer.h"
#include "serialiser/rstlvbase.h"



Expand All @@ -42,18 +43,47 @@ void RsGxsPostedPostItem::serial_process(RsGenericSerializer::SerializeJob j,RsG
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mImage,"mImage") ;
}

void RsGxsPostedGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mDescription,"mDescription") ;

if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize)
return ;

if((j == RsGenericSerializer::SIZE_ESTIMATE || j == RsGenericSerializer::SERIALIZE) && mGroupImage.empty())
return ;

RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mGroupImage,"mGroupImage") ;
}
void RsGxsPostedGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mDescription,"mDescription") ;

if(j == RsGenericSerializer::DESERIALIZE)
{
if(ctx.mOffset == ctx.mSize)
return;

if(ctx.mSize >= ctx.mOffset + TLV_HEADER_SIZE)
{
const uint16_t nextTlvType = GetTlvType(
ctx.mData + ctx.mOffset );
if(nextTlvType == TLV_TYPE_IMAGE)
RsTypeSerializer::serial_process<RsTlvItem>(
j,ctx,mGroupImage,"mGroupImage" );
}

if(ctx.mOffset == ctx.mSize)
return;

if(ctx.mSize >= ctx.mOffset + TLV_HEADER_SIZE)
{
const uint16_t nextTlvType = GetTlvType(
ctx.mData + ctx.mOffset );
if(nextTlvType == TLV_TYPE_GXSMSGIDSET)
RsTypeSerializer::serial_process<RsTlvItem>(
j,ctx,mPinnedPosts,"mPinnedPosts" );
}
return;
}

if(!mGroupImage.empty())
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mGroupImage,"mGroupImage") ;

if((j == RsGenericSerializer::SIZE_ESTIMATE
|| j == RsGenericSerializer::SERIALIZE)
&& mPinnedPosts.ids.empty()) return;

RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mPinnedPosts,"mPinnedPosts") ;
}

RsItem *RsGxsPostedSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const
{
Expand Down Expand Up @@ -119,13 +149,15 @@ void RsGxsPostedGroupItem::clear()
{
mDescription.clear();
mGroupImage.TlvClear();
mPinnedPosts.TlvClear();
}

bool RsGxsPostedGroupItem::fromPostedGroup(RsPostedGroup &group, bool moveImage)
{
clear();
meta = group.mMeta;
mDescription = group.mDescription;
mPinnedPosts = group.mPinnedPosts;

if (moveImage)
{
Expand All @@ -144,6 +176,7 @@ bool RsGxsPostedGroupItem::toPostedGroup(RsPostedGroup &group, bool moveImage)
{
group.mMeta = meta;
group.mDescription = mDescription;
group.mPinnedPosts = mPinnedPosts;
if (moveImage)
{
group.mGroupImage.take((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len);
Expand Down
2 changes: 2 additions & 0 deletions src/rsitems/rsposteditems.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "rsitems/rsgxscommentitems.h"
#include "rsitems/rsgxsitems.h"
#include "serialiser/rstlvimage.h"
#include "serialiser/rstlvidset.h"

#include "retroshare/rsposted.h"

Expand All @@ -48,6 +49,7 @@ class RsGxsPostedGroupItem : public RsGxsGrpItem

std::string mDescription;
RsTlvImage mGroupImage;
RsTlvGxsMsgIdSet mPinnedPosts;

};

Expand Down
35 changes: 34 additions & 1 deletion src/services/p3posted.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*******************************************************************************/
#include "services/p3posted.h"
#include "retroshare/rsgxscircles.h"
#include "retroshare/rsgxsflags.h"
#include "retroshare/rspeers.h"
#include "rsitems/rsposteditems.h"

Expand Down Expand Up @@ -730,7 +731,8 @@ bool p3Posted::createPostV2(const RsGxsGroupId& boardId,
const RsGxsId& authorId,
const RsGxsImage& image,
RsGxsMessageId& postId,
std::string& error_message)
std::string& error_message,
const RsGxsMessageId& origPostId)
{
// check boardId

Expand All @@ -752,13 +754,44 @@ bool p3Posted::createPostV2(const RsGxsGroupId& boardId,
return false;
}

// If editing an existing post, validate it exists and the author matches (unless admin)

if(!origPostId.isNull())
{
std::vector<RsPostedPost> orig_posts;
std::vector<RsGxsComment> orig_comments;
std::vector<RsGxsVote> orig_votes;

if(!getBoardContent(boardId, { origPostId }, orig_posts, orig_comments, orig_votes)
|| orig_posts.size() != 1)
{
error_message = "Original post " + origPostId.toStdString() + " not found in board " + boardId.toStdString();
RsErr() << error_message;
return false;
}

const RsGxsId& origAuthor = orig_posts[0].mMeta.mAuthorId;
bool isAdmin = IS_GROUP_ADMIN(groupsInfo[0].mMeta.mSubscribeFlags);

if(origAuthor != authorId && !isAdmin)
{
error_message = "You do not have permission to edit this post. "
"Only the post author or a board admin can edit posts.";
RsErr() << __PRETTY_FUNCTION__ << " Editor " << authorId
<< " is neither the original author " << origAuthor
<< " nor a board admin." << std::endl;
return false;
}
}

RsPostedPost post;
post.mMeta.mGroupId = boardId;
post.mLink = link.toString();
post.mImage = image;
post.mNotes = notes;
post.mMeta.mAuthorId = authorId;
post.mMeta.mMsgName = title;
post.mMeta.mOrigMsgId = origPostId;

// check size

Expand Down
3 changes: 2 additions & 1 deletion src/services/p3posted.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
const RsGxsId& authorId,
const RsGxsImage& image,
RsGxsMessageId& postId,
std::string& error_message) override;
std::string& error_message,
const RsGxsMessageId& origPostId = RsGxsMessageId()) override;

bool voteForPost(const RsGxsGroupId& boardId,
const RsGxsMessageId& postMsgId,
Expand Down
Loading