Prevent interactions with reposts
This commit is contained in:
parent
2fda205dbf
commit
78d66f8a06
4 changed files with 33 additions and 14 deletions
|
@ -283,7 +283,8 @@ pub async fn object_view(
|
||||||
internal_object_id: web::Path<Uuid>,
|
internal_object_id: web::Path<Uuid>,
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
let db_client = &**get_database_client(&db_pool).await?;
|
let db_client = &**get_database_client(&db_pool).await?;
|
||||||
// Try to find local post by ID, return 404 if not found
|
// Try to find local post by ID,
|
||||||
|
// return 404 if not found or if repost is found
|
||||||
let internal_object_id = internal_object_id.into_inner();
|
let internal_object_id = internal_object_id.into_inner();
|
||||||
let thread = get_thread(db_client, &internal_object_id, None).await?;
|
let thread = get_thread(db_client, &internal_object_id, None).await?;
|
||||||
let mut post = thread.iter()
|
let mut post = thread.iter()
|
||||||
|
|
|
@ -95,6 +95,9 @@ async fn create_status(
|
||||||
},
|
},
|
||||||
Err(other_error) => return Err(other_error.into()),
|
Err(other_error) => return Err(other_error.into()),
|
||||||
};
|
};
|
||||||
|
if in_reply_to.repost_of_id.is_some() {
|
||||||
|
return Err(ValidationError("can't reply to repost").into());
|
||||||
|
};
|
||||||
if in_reply_to.visibility != Visibility::Public &&
|
if in_reply_to.visibility != Visibility::Public &&
|
||||||
post_data.visibility != Visibility::Direct {
|
post_data.visibility != Visibility::Direct {
|
||||||
return Err(ValidationError("reply must have direct visibility").into());
|
return Err(ValidationError("reply must have direct visibility").into());
|
||||||
|
@ -224,7 +227,7 @@ async fn favourite(
|
||||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
let mut post = get_post_by_id(db_client, &status_id).await?;
|
let mut post = get_post_by_id(db_client, &status_id).await?;
|
||||||
if !post.is_public() {
|
if !post.is_public() || post.repost_of_id.is_some() {
|
||||||
return Err(HttpError::NotFoundError("post"));
|
return Err(HttpError::NotFoundError("post"));
|
||||||
};
|
};
|
||||||
let maybe_reaction_created = match create_reaction(
|
let maybe_reaction_created = match create_reaction(
|
||||||
|
@ -309,7 +312,7 @@ async fn reblog(
|
||||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
let mut post = get_post_by_id(db_client, &status_id).await?;
|
let mut post = get_post_by_id(db_client, &status_id).await?;
|
||||||
if !post.is_public() {
|
if !post.is_public() || post.repost_of_id.is_some() {
|
||||||
return Err(HttpError::NotFoundError("post"));
|
return Err(HttpError::NotFoundError("post"));
|
||||||
};
|
};
|
||||||
let repost_data = PostCreateData {
|
let repost_data = PostCreateData {
|
||||||
|
@ -386,7 +389,7 @@ async fn make_permanent(
|
||||||
if post.ipfs_cid.is_some() {
|
if post.ipfs_cid.is_some() {
|
||||||
return Err(HttpError::OperationError("post already saved to IPFS"));
|
return Err(HttpError::OperationError("post already saved to IPFS"));
|
||||||
};
|
};
|
||||||
if post.author.id != current_user.id || !post.is_public() {
|
if post.author.id != current_user.id || !post.is_public() || post.repost_of_id.is_some() {
|
||||||
// Users can only archive their own public posts
|
// Users can only archive their own public posts
|
||||||
return Err(HttpError::PermissionError);
|
return Err(HttpError::PermissionError);
|
||||||
};
|
};
|
||||||
|
@ -443,7 +446,7 @@ async fn get_signature(
|
||||||
let wallet_address = current_user.wallet_address
|
let wallet_address = current_user.wallet_address
|
||||||
.ok_or(HttpError::PermissionError)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let post = get_post_by_id(db_client, &status_id).await?;
|
let post = get_post_by_id(db_client, &status_id).await?;
|
||||||
if post.author.id != current_user.id || !post.is_public() {
|
if post.author.id != current_user.id || !post.is_public() || post.repost_of_id.is_some() {
|
||||||
// Users can only tokenize their own public posts
|
// Users can only tokenize their own public posts
|
||||||
return Err(HttpError::PermissionError);
|
return Err(HttpError::PermissionError);
|
||||||
};
|
};
|
||||||
|
@ -473,7 +476,7 @@ async fn token_minted(
|
||||||
if post.token_tx_id.is_some() {
|
if post.token_tx_id.is_some() {
|
||||||
return Err(HttpError::OperationError("transaction is already registered"));
|
return Err(HttpError::OperationError("transaction is already registered"));
|
||||||
};
|
};
|
||||||
if post.author.id != current_user.id || !post.is_public() {
|
if post.author.id != current_user.id || !post.is_public() || post.repost_of_id.is_some() {
|
||||||
return Err(HttpError::PermissionError);
|
return Err(HttpError::PermissionError);
|
||||||
};
|
};
|
||||||
post.token_tx_id = Some(transaction_data.into_inner().transaction_id);
|
post.token_tx_id = Some(transaction_data.into_inner().transaction_id);
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub async fn create_post(
|
||||||
let transaction = db_client.transaction().await?;
|
let transaction = db_client.transaction().await?;
|
||||||
let post_id = new_uuid();
|
let post_id = new_uuid();
|
||||||
let created_at = data.created_at.unwrap_or(Utc::now());
|
let created_at = data.created_at.unwrap_or(Utc::now());
|
||||||
|
// Replying to reposts is not allowed
|
||||||
// Reposting of other reposts or non-public posts is not allowed
|
// Reposting of other reposts or non-public posts is not allowed
|
||||||
let insert_statement = format!(
|
let insert_statement = format!(
|
||||||
"
|
"
|
||||||
|
@ -44,7 +45,12 @@ pub async fn create_post(
|
||||||
created_at
|
created_at
|
||||||
)
|
)
|
||||||
SELECT $1, $2, $3, $4, $5, $6, $7, $8
|
SELECT $1, $2, $3, $4, $5, $6, $7, $8
|
||||||
WHERE NOT EXISTS (
|
WHERE
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1 FROM post
|
||||||
|
WHERE post.id = $4 AND post.repost_of_id IS NOT NULL
|
||||||
|
)
|
||||||
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM post
|
SELECT 1 FROM post
|
||||||
WHERE post.id = $5 AND (
|
WHERE post.id = $5 AND (
|
||||||
post.repost_of_id IS NOT NULL
|
post.repost_of_id IS NOT NULL
|
||||||
|
@ -505,7 +511,9 @@ pub async fn get_thread(
|
||||||
WITH RECURSIVE
|
WITH RECURSIVE
|
||||||
ancestors (id, in_reply_to_id) AS (
|
ancestors (id, in_reply_to_id) AS (
|
||||||
SELECT post.id, post.in_reply_to_id FROM post
|
SELECT post.id, post.in_reply_to_id FROM post
|
||||||
WHERE post.id = $post_id AND {visibility_filter}
|
WHERE post.id = $post_id
|
||||||
|
AND post.repost_of_id IS NULL
|
||||||
|
AND {visibility_filter}
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT post.id, post.in_reply_to_id FROM post
|
SELECT post.id, post.in_reply_to_id FROM post
|
||||||
JOIN ancestors ON post.id = ancestors.in_reply_to_id
|
JOIN ancestors ON post.id = ancestors.in_reply_to_id
|
||||||
|
@ -610,6 +618,7 @@ pub async fn update_post(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
post: &Post,
|
post: &Post,
|
||||||
) -> Result<(), DatabaseError> {
|
) -> Result<(), DatabaseError> {
|
||||||
|
// Reposts can't be updated
|
||||||
let updated_count = db_client.execute(
|
let updated_count = db_client.execute(
|
||||||
"
|
"
|
||||||
UPDATE post
|
UPDATE post
|
||||||
|
@ -618,7 +627,7 @@ pub async fn update_post(
|
||||||
ipfs_cid = $2,
|
ipfs_cid = $2,
|
||||||
token_id = $3,
|
token_id = $3,
|
||||||
token_tx_id = $4
|
token_tx_id = $4
|
||||||
WHERE id = $5
|
WHERE id = $5 AND repost_of_id IS NULL
|
||||||
",
|
",
|
||||||
&[
|
&[
|
||||||
&post.content,
|
&post.content,
|
||||||
|
@ -643,7 +652,7 @@ pub async fn update_reply_count(
|
||||||
"
|
"
|
||||||
UPDATE post
|
UPDATE post
|
||||||
SET reply_count = reply_count + $1
|
SET reply_count = reply_count + $1
|
||||||
WHERE id = $2
|
WHERE id = $2 AND repost_of_id IS NULL
|
||||||
",
|
",
|
||||||
&[&change, &post_id],
|
&[&change, &post_id],
|
||||||
).await?;
|
).await?;
|
||||||
|
@ -662,7 +671,7 @@ pub async fn update_reaction_count(
|
||||||
"
|
"
|
||||||
UPDATE post
|
UPDATE post
|
||||||
SET reaction_count = reaction_count + $1
|
SET reaction_count = reaction_count + $1
|
||||||
WHERE id = $2
|
WHERE id = $2 AND repost_of_id IS NULL
|
||||||
",
|
",
|
||||||
&[&change, &post_id],
|
&[&change, &post_id],
|
||||||
).await?;
|
).await?;
|
||||||
|
@ -681,7 +690,7 @@ pub async fn update_repost_count(
|
||||||
"
|
"
|
||||||
UPDATE post
|
UPDATE post
|
||||||
SET repost_count = repost_count + $1
|
SET repost_count = repost_count + $1
|
||||||
WHERE id = $2
|
WHERE id = $2 AND repost_of_id IS NULL
|
||||||
",
|
",
|
||||||
&[&change, &post_id],
|
&[&change, &post_id],
|
||||||
).await?;
|
).await?;
|
||||||
|
|
|
@ -19,14 +19,20 @@ pub async fn create_reaction(
|
||||||
) -> Result<DbReaction, DatabaseError> {
|
) -> Result<DbReaction, DatabaseError> {
|
||||||
let transaction = db_client.transaction().await?;
|
let transaction = db_client.transaction().await?;
|
||||||
let reaction_id = new_uuid();
|
let reaction_id = new_uuid();
|
||||||
let row = transaction.query_one(
|
// Reactions to reposts are not allowed
|
||||||
|
let maybe_row = transaction.query_opt(
|
||||||
"
|
"
|
||||||
INSERT INTO post_reaction (id, author_id, post_id, activity_id)
|
INSERT INTO post_reaction (id, author_id, post_id, activity_id)
|
||||||
VALUES ($1, $2, $3, $4)
|
SELECT $1, $2, $3, $4
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM post
|
||||||
|
WHERE post.id = $3 AND post.repost_of_id IS NOT NULL
|
||||||
|
)
|
||||||
RETURNING post_reaction
|
RETURNING post_reaction
|
||||||
",
|
",
|
||||||
&[&reaction_id, &author_id, &post_id, &activity_id],
|
&[&reaction_id, &author_id, &post_id, &activity_id],
|
||||||
).await.map_err(catch_unique_violation("reaction"))?;
|
).await.map_err(catch_unique_violation("reaction"))?;
|
||||||
|
let row = maybe_row.ok_or(DatabaseError::NotFound("post"))?;
|
||||||
let reaction: DbReaction = row.try_get("post_reaction")?;
|
let reaction: DbReaction = row.try_get("post_reaction")?;
|
||||||
update_reaction_count(&transaction, post_id, 1).await?;
|
update_reaction_count(&transaction, post_id, 1).await?;
|
||||||
let post_author = get_post_author(&transaction, post_id).await?;
|
let post_author = get_post_author(&transaction, post_id).await?;
|
||||||
|
|
Loading…
Reference in a new issue