fix: stacks manage page when user deletes profile
add: allow moderators to view deleted posts
This commit is contained in:
parent
4c26879d00
commit
81307752c2
14 changed files with 211 additions and 29 deletions
|
@ -69,7 +69,9 @@ macro_rules! auto_method {
|
|||
($name:ident()@$select_fn:ident -> $query:literal --name=$name_:literal --returns=$returns_:tt --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize) -> Result<$returns_> {
|
||||
if let Some(cached) = self.2.get(format!($cache_key_tmpl, id)).await {
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
if let Ok(c) = serde_json::from_str(&cached) {
|
||||
return Ok(c);
|
||||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
|
@ -183,7 +185,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident()@$select_fn:ident:$permission:ident -> $query:literal) => {
|
||||
pub async fn $name(&self, id: usize, user: User) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -213,7 +215,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident()@$select_fn:ident:$permission:ident -> $query:literal --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize, user: User) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -245,7 +247,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident($x:ty)@$select_fn:ident:$permission:ident -> $query:literal) => {
|
||||
pub async fn $name(&self, id: usize, user: User, x: $x) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -276,7 +278,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident($x:ty)@$select_fn:ident:$permission:ident -> $query:literal --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize, user: User, x: $x) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -309,7 +311,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident($x:ty)@$select_fn:ident:$permission:ident -> $query:literal --serde) => {
|
||||
pub async fn $name(&self, id: usize, user: User, x: $x) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -344,7 +346,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident($x:ty)@$select_fn:ident:$permission:ident -> $query:literal --serde --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize, user: User, x: $x) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -499,7 +501,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident()@$select_fn:ident:$permission:ident -> $query:literal --cache-key-tmpl=$cache_key_tmpl:ident) => {
|
||||
pub async fn $name(&self, id: usize, user: User) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -532,7 +534,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident($x:ty)@$select_fn:ident:$permission:ident -> $query:literal --cache-key-tmpl=$cache_key_tmpl:ident) => {
|
||||
pub async fn $name(&self, id: usize, user: User, x: $x) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
@ -611,7 +613,7 @@ macro_rules! auto_method {
|
|||
};
|
||||
|
||||
($name:ident($x:ty)@$select_fn:ident:$permission:ident -> $query:literal --serde --cache-key-tmpl=$cache_key_tmpl:ident) => {
|
||||
pub async fn $name(&self, id: usize, user: User, x: $x) -> Result<()> {
|
||||
pub async fn $name(&self, id: usize, user: &User, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
if user.id != y.owner {
|
||||
|
|
|
@ -12,5 +12,6 @@ CREATE TABLE IF NOT EXISTS posts (
|
|||
-- other counts
|
||||
comment_count INT NOT NULL,
|
||||
-- ...
|
||||
uploads TEXT NOT NULL
|
||||
uploads TEXT NOT NULL,
|
||||
is_deleted INT NOT NULL
|
||||
)
|
||||
|
|
|
@ -42,6 +42,7 @@ impl DataManager {
|
|||
comment_count: get!(x->9(i32)) as usize,
|
||||
// ...
|
||||
uploads: serde_json::from_str(&get!(x->10(String))).unwrap(),
|
||||
is_deleted: get!(x->11(i32)) as i8 == 1,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +196,8 @@ impl DataManager {
|
|||
|
||||
// check relationship
|
||||
if ua.settings.private_profile {
|
||||
// if someone were to look for places to optimize memory usage,
|
||||
// look no further than here
|
||||
if let Some(ua1) = user {
|
||||
if ua1.id == 0 {
|
||||
continue;
|
||||
|
@ -202,7 +205,10 @@ impl DataManager {
|
|||
|
||||
if let Some(is_following) = seen_user_follow_statuses.get(&(ua.id, ua1.id))
|
||||
{
|
||||
if !is_following && (ua.id != ua1.id) {
|
||||
if !is_following
|
||||
&& (ua.id != ua1.id)
|
||||
&& !ua1.permissions.check(FinePermission::MANAGE_POSTS)
|
||||
{
|
||||
// post owner is not following us
|
||||
continue;
|
||||
}
|
||||
|
@ -211,6 +217,7 @@ impl DataManager {
|
|||
.get_userfollow_by_initiator_receiver(ua.id, ua1.id)
|
||||
.await
|
||||
.is_err()
|
||||
&& !ua1.permissions.check(FinePermission::MANAGE_POSTS)
|
||||
{
|
||||
// post owner is not following us
|
||||
seen_user_follow_statuses.insert((ua.id, ua1.id), false);
|
||||
|
@ -1105,7 +1112,7 @@ impl DataManager {
|
|||
|
||||
let res = execute!(
|
||||
&conn,
|
||||
"INSERT INTO posts VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
|
||||
"INSERT INTO posts VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
|
||||
params![
|
||||
&(data.id as i64),
|
||||
&(data.created as i64),
|
||||
|
@ -1121,7 +1128,8 @@ impl DataManager {
|
|||
&0_i32,
|
||||
&0_i32,
|
||||
&0_i32,
|
||||
&serde_json::to_string(&data.uploads).unwrap()
|
||||
&serde_json::to_string(&data.uploads).unwrap(),
|
||||
&{ if data.is_deleted { 1 } else { 0 } }
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -1212,7 +1220,7 @@ impl DataManager {
|
|||
let question = self.get_question_by_id(y.context.answering).await?;
|
||||
|
||||
if question.is_global {
|
||||
self.incr_question_answer_count(y.context.answering).await?;
|
||||
self.decr_question_answer_count(y.context.answering).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1225,6 +1233,94 @@ impl DataManager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn fake_delete_post(&self, id: usize, user: User, is_deleted: bool) -> Result<()> {
|
||||
let y = self.get_post_by_id(id).await?;
|
||||
|
||||
let user_membership = self
|
||||
.get_membership_by_owner_community(user.id, y.community)
|
||||
.await?;
|
||||
|
||||
if (user.id != y.owner)
|
||||
&& !user_membership
|
||||
.role
|
||||
.check(CommunityPermission::MANAGE_POSTS)
|
||||
{
|
||||
if !user.permissions.check(FinePermission::MANAGE_POSTS) {
|
||||
return Err(Error::NotAllowed);
|
||||
} else {
|
||||
self.create_audit_log_entry(AuditLogEntry::new(
|
||||
user.id,
|
||||
format!("invoked `fake_delete_post` with x value `{id}`"),
|
||||
))
|
||||
.await?
|
||||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
||||
let res = execute!(
|
||||
&conn,
|
||||
"UPDATE posts SET is_deleted = $1 WHERE id = $2",
|
||||
params![if is_deleted { 1 } else { 0 }, &(id as i64)]
|
||||
);
|
||||
|
||||
if let Err(e) = res {
|
||||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.post:{}", id)).await;
|
||||
|
||||
if is_deleted {
|
||||
// decr parent comment count
|
||||
if let Some(replying_to) = y.replying_to {
|
||||
self.decr_post_comments(replying_to).await.unwrap();
|
||||
}
|
||||
|
||||
// decr user post count
|
||||
let owner = self.get_user_by_id(y.owner).await?;
|
||||
|
||||
if owner.post_count > 0 {
|
||||
self.decr_user_post_count(y.owner).await?;
|
||||
}
|
||||
|
||||
// decr question answer count
|
||||
if y.context.answering != 0 {
|
||||
let question = self.get_question_by_id(y.context.answering).await?;
|
||||
|
||||
if question.is_global {
|
||||
self.incr_question_answer_count(y.context.answering).await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// incr parent comment count
|
||||
if let Some(replying_to) = y.replying_to {
|
||||
self.incr_post_comments(replying_to).await.unwrap();
|
||||
}
|
||||
|
||||
// incr user post count
|
||||
let owner = self.get_user_by_id(y.owner).await?;
|
||||
|
||||
if owner.post_count > 0 {
|
||||
self.incr_user_post_count(y.owner).await?;
|
||||
}
|
||||
|
||||
// incr question answer count
|
||||
if y.context.answering != 0 {
|
||||
let question = self.get_question_by_id(y.context.answering).await?;
|
||||
|
||||
if question.is_global {
|
||||
self.decr_question_answer_count(y.context.answering).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_post_context(
|
||||
&self,
|
||||
id: usize,
|
||||
|
|
|
@ -238,6 +238,8 @@ pub struct Post {
|
|||
pub comment_count: usize,
|
||||
/// IDs of all uploads linked to this post.
|
||||
pub uploads: Vec<usize>,
|
||||
/// If the post was deleted.
|
||||
pub is_deleted: bool,
|
||||
}
|
||||
|
||||
impl Post {
|
||||
|
@ -260,6 +262,7 @@ impl Post {
|
|||
dislikes: 0,
|
||||
comment_count: 0,
|
||||
uploads: Vec::new(),
|
||||
is_deleted: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue