forked from jmug/stoatchat
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use revolt_models::v0::{
|
use revolt_models::v0::{
|
||||||
AppendMessage, Channel, Emoji, FieldsChannel, FieldsMember, FieldsRole, FieldsServer,
|
AppendMessage, Channel, Emoji, FieldsChannel, FieldsMember, FieldsRole, FieldsServer,
|
||||||
FieldsUser, FieldsWebhook, MemberCompositeKey, Message, PartialChannel, PartialMember,
|
FieldsUser, FieldsWebhook, MemberCompositeKey, Message, PartialChannel, PartialMember,
|
||||||
PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook, Server, User,
|
PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook, Report, Server, User,
|
||||||
UserSettings, Webhook,
|
UserSettings, Webhook,
|
||||||
};
|
};
|
||||||
use revolt_result::Error;
|
use revolt_result::Error;
|
||||||
@@ -176,8 +176,8 @@ pub enum EventV1 {
|
|||||||
/// Delete emoji
|
/// Delete emoji
|
||||||
EmojiDelete { id: String },
|
EmojiDelete { id: String },
|
||||||
|
|
||||||
/*/// New report
|
/// New report
|
||||||
ReportCreate(Report), */
|
ReportCreate(Report),
|
||||||
/// New channel
|
/// New channel
|
||||||
ChannelCreate(Channel),
|
ChannelCreate(Channel),
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use iso8601_timestamp::Timestamp;
|
use revolt_models::v0::{ReportStatus, ReportedContent};
|
||||||
|
|
||||||
auto_derived!(
|
auto_derived!(
|
||||||
/// User-generated platform moderation report
|
/// User-generated platform moderation report
|
||||||
@@ -19,130 +19,4 @@ auto_derived!(
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub notes: String,
|
pub notes: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reason for reporting content (message or server)
|
|
||||||
pub enum ContentReportReason {
|
|
||||||
/// No reason has been specified
|
|
||||||
NoneSpecified,
|
|
||||||
|
|
||||||
/// Illegal content catch-all reason
|
|
||||||
Illegal,
|
|
||||||
|
|
||||||
/// Selling or facilitating use of drugs or other illegal goods
|
|
||||||
IllegalGoods,
|
|
||||||
|
|
||||||
/// Extortion or blackmail
|
|
||||||
IllegalExtortion,
|
|
||||||
|
|
||||||
/// Revenge or child pornography
|
|
||||||
IllegalPornography,
|
|
||||||
|
|
||||||
/// Illegal hacking activity
|
|
||||||
IllegalHacking,
|
|
||||||
|
|
||||||
/// Extreme violence, gore, or animal cruelty
|
|
||||||
/// With exception to violence potrayed in media / creative arts
|
|
||||||
ExtremeViolence,
|
|
||||||
|
|
||||||
/// Content that promotes harm to others / self
|
|
||||||
PromotesHarm,
|
|
||||||
|
|
||||||
/// Unsolicited advertisements
|
|
||||||
UnsolicitedSpam,
|
|
||||||
|
|
||||||
/// This is a raid
|
|
||||||
Raid,
|
|
||||||
|
|
||||||
/// Spam or platform abuse
|
|
||||||
SpamAbuse,
|
|
||||||
|
|
||||||
/// Scams or fraud
|
|
||||||
ScamsFraud,
|
|
||||||
|
|
||||||
/// Distribution of malware or malicious links
|
|
||||||
Malware,
|
|
||||||
|
|
||||||
/// Harassment or abuse targeted at another user
|
|
||||||
Harassment,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reason for reporting a user
|
|
||||||
pub enum UserReportReason {
|
|
||||||
/// No reason has been specified
|
|
||||||
NoneSpecified,
|
|
||||||
|
|
||||||
/// Unsolicited advertisements
|
|
||||||
UnsolicitedSpam,
|
|
||||||
|
|
||||||
/// User is sending spam or otherwise abusing the platform
|
|
||||||
SpamAbuse,
|
|
||||||
|
|
||||||
/// User's profile contains inappropriate content for a general audience
|
|
||||||
InappropriateProfile,
|
|
||||||
|
|
||||||
/// User is impersonating another user
|
|
||||||
Impersonation,
|
|
||||||
|
|
||||||
/// User is evading a ban
|
|
||||||
BanEvasion,
|
|
||||||
|
|
||||||
/// User is not of minimum age to use the platform
|
|
||||||
Underage,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The content being reported
|
|
||||||
#[serde(tag = "type")]
|
|
||||||
pub enum ReportedContent {
|
|
||||||
/// Report a message
|
|
||||||
Message {
|
|
||||||
/// ID of the message
|
|
||||||
id: String,
|
|
||||||
/// Reason for reporting message
|
|
||||||
report_reason: ContentReportReason,
|
|
||||||
},
|
|
||||||
/// Report a server
|
|
||||||
Server {
|
|
||||||
/// ID of the server
|
|
||||||
id: String,
|
|
||||||
/// Reason for reporting server
|
|
||||||
report_reason: ContentReportReason,
|
|
||||||
},
|
|
||||||
/// Report a user
|
|
||||||
User {
|
|
||||||
/// ID of the user
|
|
||||||
id: String,
|
|
||||||
/// Reason for reporting a user
|
|
||||||
report_reason: UserReportReason,
|
|
||||||
/// Message context
|
|
||||||
message_id: Option<String>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Status of the report
|
|
||||||
#[serde(tag = "status")]
|
|
||||||
pub enum ReportStatus {
|
|
||||||
/// Report is waiting for triage / action
|
|
||||||
Created {},
|
|
||||||
|
|
||||||
/// Report was rejected
|
|
||||||
Rejected {
|
|
||||||
rejection_reason: String,
|
|
||||||
closed_at: Option<Timestamp>,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Report was actioned and resolved
|
|
||||||
Resolved { closed_at: Option<Timestamp> },
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Just the status of the report
|
|
||||||
pub enum ReportStatusString {
|
|
||||||
/// Report is waiting for triage / action
|
|
||||||
Created,
|
|
||||||
|
|
||||||
/// Report was rejected
|
|
||||||
Rejected,
|
|
||||||
|
|
||||||
/// Report was actioned and resolved
|
|
||||||
Resolved,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use revolt_models::v0::{Message, Server, User};
|
use revolt_models::v0::MessageSort;
|
||||||
|
use revolt_result::Result;
|
||||||
|
|
||||||
|
use crate::{Database, Message, MessageFilter, MessageQuery, MessageTimePeriod, Server, User};
|
||||||
|
|
||||||
auto_derived!(
|
auto_derived!(
|
||||||
/// Snapshot of some content
|
/// Snapshot of some content
|
||||||
@@ -33,3 +36,86 @@ auto_derived!(
|
|||||||
User(User),
|
User(User),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl SnapshotContent {
|
||||||
|
/// Generate snapshot from a given message
|
||||||
|
pub async fn generate_from_message(
|
||||||
|
db: &Database,
|
||||||
|
message: Message,
|
||||||
|
) -> Result<(SnapshotContent, Vec<String>)> {
|
||||||
|
// Collect message attachments
|
||||||
|
let files = message
|
||||||
|
.attachments
|
||||||
|
.as_ref()
|
||||||
|
.map(|attachments| attachments.iter().map(|x| x.id.to_string()).collect())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// Collect prior context
|
||||||
|
let prior_context = db
|
||||||
|
.fetch_messages(MessageQuery {
|
||||||
|
filter: MessageFilter {
|
||||||
|
channel: Some(message.channel.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
limit: Some(15),
|
||||||
|
time_period: MessageTimePeriod::Absolute {
|
||||||
|
before: Some(message.id.to_string()),
|
||||||
|
after: None,
|
||||||
|
sort: Some(MessageSort::Latest),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Collect leading context
|
||||||
|
let leading_context = db
|
||||||
|
.fetch_messages(MessageQuery {
|
||||||
|
filter: MessageFilter {
|
||||||
|
channel: Some(message.channel.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
limit: Some(15),
|
||||||
|
time_period: MessageTimePeriod::Absolute {
|
||||||
|
before: None,
|
||||||
|
after: Some(message.id.to_string()),
|
||||||
|
sort: Some(MessageSort::Oldest),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
SnapshotContent::Message {
|
||||||
|
message,
|
||||||
|
prior_context: prior_context.into_iter().map(Into::into).collect(),
|
||||||
|
leading_context: leading_context.into_iter().map(Into::into).collect(),
|
||||||
|
},
|
||||||
|
files,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate snapshot from a given server
|
||||||
|
pub fn generate_from_server(server: Server) -> Result<(SnapshotContent, Vec<String>)> {
|
||||||
|
// Collect server's icon and banner
|
||||||
|
let files = [&server.icon, &server.banner]
|
||||||
|
.iter()
|
||||||
|
.filter_map(|x| x.as_ref().map(|x| x.id.to_string()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok((SnapshotContent::Server(server), files))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate snapshot from a given user
|
||||||
|
pub fn generate_from_user(user: User) -> Result<(SnapshotContent, Vec<String>)> {
|
||||||
|
// Collect user's avatar and profile background
|
||||||
|
let files = [
|
||||||
|
user.avatar.as_ref(),
|
||||||
|
user.profile
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|profile| profile.background.as_ref()),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.filter_map(|x| x.as_ref().map(|x| x.id.to_string()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok((SnapshotContent::User(user), files))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -445,6 +445,19 @@ impl From<Masquerade> for crate::Masquerade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::Report> for Report {
|
||||||
|
fn from(value: crate::Report) -> Self {
|
||||||
|
Report {
|
||||||
|
id: value.id,
|
||||||
|
author_id: value.author_id,
|
||||||
|
content: value.content,
|
||||||
|
additional_context: value.additional_context,
|
||||||
|
status: value.status,
|
||||||
|
notes: value.notes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<crate::ServerBan> for ServerBan {
|
impl From<crate::ServerBan> for ServerBan {
|
||||||
fn from(value: crate::ServerBan) -> Self {
|
fn from(value: crate::ServerBan) -> Self {
|
||||||
ServerBan {
|
ServerBan {
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ auto_derived!(
|
|||||||
|
|
||||||
/// Invite join response
|
/// Invite join response
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum InviteJoinResponse {
|
pub enum InviteJoinResponse {
|
||||||
Server {
|
Server {
|
||||||
/// Channels in the server
|
/// Channels in the server
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ mod embeds;
|
|||||||
mod emojis;
|
mod emojis;
|
||||||
mod files;
|
mod files;
|
||||||
mod messages;
|
mod messages;
|
||||||
|
mod safety_reports;
|
||||||
mod server_bans;
|
mod server_bans;
|
||||||
mod server_members;
|
mod server_members;
|
||||||
mod servers;
|
mod servers;
|
||||||
@@ -22,6 +23,7 @@ pub use embeds::*;
|
|||||||
pub use emojis::*;
|
pub use emojis::*;
|
||||||
pub use files::*;
|
pub use files::*;
|
||||||
pub use messages::*;
|
pub use messages::*;
|
||||||
|
pub use safety_reports::*;
|
||||||
pub use server_bans::*;
|
pub use server_bans::*;
|
||||||
pub use server_members::*;
|
pub use server_members::*;
|
||||||
pub use servers::*;
|
pub use servers::*;
|
||||||
|
|||||||
148
crates/core/models/src/v0/safety_reports.rs
Normal file
148
crates/core/models/src/v0/safety_reports.rs
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
use iso8601_timestamp::Timestamp;
|
||||||
|
|
||||||
|
auto_derived!(
|
||||||
|
/// User-generated platform moderation report
|
||||||
|
pub struct Report {
|
||||||
|
/// Unique Id
|
||||||
|
#[serde(rename = "_id")]
|
||||||
|
pub id: String,
|
||||||
|
/// Id of the user creating this report
|
||||||
|
pub author_id: String,
|
||||||
|
/// Reported content
|
||||||
|
pub content: ReportedContent,
|
||||||
|
/// Additional report context
|
||||||
|
pub additional_context: String,
|
||||||
|
/// Status of the report
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub status: ReportStatus,
|
||||||
|
/// Additional notes included on the report
|
||||||
|
#[serde(default)]
|
||||||
|
pub notes: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reason for reporting content (message or server)
|
||||||
|
pub enum ContentReportReason {
|
||||||
|
/// No reason has been specified
|
||||||
|
NoneSpecified,
|
||||||
|
|
||||||
|
/// Illegal content catch-all reason
|
||||||
|
Illegal,
|
||||||
|
|
||||||
|
/// Selling or facilitating use of drugs or other illegal goods
|
||||||
|
IllegalGoods,
|
||||||
|
|
||||||
|
/// Extortion or blackmail
|
||||||
|
IllegalExtortion,
|
||||||
|
|
||||||
|
/// Revenge or child pornography
|
||||||
|
IllegalPornography,
|
||||||
|
|
||||||
|
/// Illegal hacking activity
|
||||||
|
IllegalHacking,
|
||||||
|
|
||||||
|
/// Extreme violence, gore, or animal cruelty
|
||||||
|
/// With exception to violence potrayed in media / creative arts
|
||||||
|
ExtremeViolence,
|
||||||
|
|
||||||
|
/// Content that promotes harm to others / self
|
||||||
|
PromotesHarm,
|
||||||
|
|
||||||
|
/// Unsolicited advertisements
|
||||||
|
UnsolicitedSpam,
|
||||||
|
|
||||||
|
/// This is a raid
|
||||||
|
Raid,
|
||||||
|
|
||||||
|
/// Spam or platform abuse
|
||||||
|
SpamAbuse,
|
||||||
|
|
||||||
|
/// Scams or fraud
|
||||||
|
ScamsFraud,
|
||||||
|
|
||||||
|
/// Distribution of malware or malicious links
|
||||||
|
Malware,
|
||||||
|
|
||||||
|
/// Harassment or abuse targeted at another user
|
||||||
|
Harassment,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reason for reporting a user
|
||||||
|
pub enum UserReportReason {
|
||||||
|
/// No reason has been specified
|
||||||
|
NoneSpecified,
|
||||||
|
|
||||||
|
/// Unsolicited advertisements
|
||||||
|
UnsolicitedSpam,
|
||||||
|
|
||||||
|
/// User is sending spam or otherwise abusing the platform
|
||||||
|
SpamAbuse,
|
||||||
|
|
||||||
|
/// User's profile contains inappropriate content for a general audience
|
||||||
|
InappropriateProfile,
|
||||||
|
|
||||||
|
/// User is impersonating another user
|
||||||
|
Impersonation,
|
||||||
|
|
||||||
|
/// User is evading a ban
|
||||||
|
BanEvasion,
|
||||||
|
|
||||||
|
/// User is not of minimum age to use the platform
|
||||||
|
Underage,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The content being reported
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum ReportedContent {
|
||||||
|
/// Report a message
|
||||||
|
Message {
|
||||||
|
/// ID of the message
|
||||||
|
id: String,
|
||||||
|
/// Reason for reporting message
|
||||||
|
report_reason: ContentReportReason,
|
||||||
|
},
|
||||||
|
/// Report a server
|
||||||
|
Server {
|
||||||
|
/// ID of the server
|
||||||
|
id: String,
|
||||||
|
/// Reason for reporting server
|
||||||
|
report_reason: ContentReportReason,
|
||||||
|
},
|
||||||
|
/// Report a user
|
||||||
|
User {
|
||||||
|
/// ID of the user
|
||||||
|
id: String,
|
||||||
|
/// Reason for reporting a user
|
||||||
|
report_reason: UserReportReason,
|
||||||
|
/// Message context
|
||||||
|
message_id: Option<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Status of the report
|
||||||
|
#[serde(tag = "status")]
|
||||||
|
pub enum ReportStatus {
|
||||||
|
/// Report is waiting for triage / action
|
||||||
|
Created {},
|
||||||
|
|
||||||
|
/// Report was rejected
|
||||||
|
Rejected {
|
||||||
|
rejection_reason: String,
|
||||||
|
closed_at: Option<Timestamp>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Report was actioned and resolved
|
||||||
|
Resolved { closed_at: Option<Timestamp> },
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Just the status of the report
|
||||||
|
pub enum ReportStatusString {
|
||||||
|
/// Report is waiting for triage / action
|
||||||
|
Created,
|
||||||
|
|
||||||
|
/// Report was rejected
|
||||||
|
Rejected,
|
||||||
|
|
||||||
|
/// Report was actioned and resolved
|
||||||
|
Resolved,
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -97,10 +97,8 @@ impl PermissionValue {
|
|||||||
{
|
{
|
||||||
return Err(create_error!(CannotGiveMissingPermissions));
|
return Err(create_error!(CannotGiveMissingPermissions));
|
||||||
}
|
}
|
||||||
} else {
|
} else if !self.has(next_value.allows()) {
|
||||||
if !self.has(next_value.allows()) {
|
return Err(create_error!(CannotGiveMissingPermissions));
|
||||||
return Err(create_error!(CannotGiveMissingPermissions));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub async fn join(
|
|||||||
channel.add_user_to_group(db, &user, creator).await?;
|
channel.add_user_to_group(db, &user, creator).await?;
|
||||||
if let Channel::Group { recipients, .. } = &channel {
|
if let Channel::Group { recipients, .. } = &channel {
|
||||||
Ok(Json(InviteJoinResponse::Group {
|
Ok(Json(InviteJoinResponse::Group {
|
||||||
users: User::fetch_many_ids_as_mutuals(db, &user, &recipients).await?,
|
users: User::fetch_many_ids_as_mutuals(db, &user, recipients).await?,
|
||||||
channel: channel.into(),
|
channel: channel.into(),
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
use revolt_quark::events::client::EventV1;
|
use revolt_database::{events::client::EventV1, Database, Report, Snapshot, SnapshotContent, User};
|
||||||
use revolt_quark::models::report::{ReportStatus, ReportedContent};
|
use revolt_models::v0::{ReportStatus, ReportedContent};
|
||||||
use revolt_quark::models::snapshot::{Snapshot, SnapshotContent};
|
use revolt_result::{create_error, Result};
|
||||||
use revolt_quark::models::{Report, User};
|
|
||||||
use revolt_quark::{Db, Error, Result};
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use rocket::serde::json::Json;
|
use rocket::{serde::json::Json, State};
|
||||||
|
|
||||||
/// # Report Data
|
/// # Report Data
|
||||||
#[derive(Validate, Deserialize, JsonSchema)]
|
#[derive(Validate, Deserialize, JsonSchema)]
|
||||||
@@ -25,14 +23,21 @@ pub struct DataReportContent {
|
|||||||
/// Report a piece of content to the moderation team.
|
/// Report a piece of content to the moderation team.
|
||||||
#[openapi(tag = "User Safety")]
|
#[openapi(tag = "User Safety")]
|
||||||
#[post("/report", data = "<data>")]
|
#[post("/report", data = "<data>")]
|
||||||
pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>) -> Result<()> {
|
pub async fn report_content(
|
||||||
|
db: &State<Database>,
|
||||||
|
user: User,
|
||||||
|
data: Json<DataReportContent>,
|
||||||
|
) -> Result<()> {
|
||||||
let data = data.into_inner();
|
let data = data.into_inner();
|
||||||
data.validate()
|
data.validate().map_err(|error| {
|
||||||
.map_err(|error| Error::FailedValidation { error })?;
|
create_error!(FailedValidation {
|
||||||
|
error: error.to_string()
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
// Bots cannot create reports
|
// Bots cannot create reports
|
||||||
if user.bot.is_some() {
|
if user.bot.is_some() {
|
||||||
return Err(Error::IsBot);
|
return Err(create_error!(IsBot));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the content and create a snapshot of it
|
// Find the content and create a snapshot of it
|
||||||
@@ -43,7 +48,7 @@ pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>)
|
|||||||
|
|
||||||
// Users cannot report themselves
|
// Users cannot report themselves
|
||||||
if message.author == user.id {
|
if message.author == user.id {
|
||||||
return Err(Error::CannotReportYourself);
|
return Err(create_error!(CannotReportYourself));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (snapshot, files) = SnapshotContent::generate_from_message(db, message).await?;
|
let (snapshot, files) = SnapshotContent::generate_from_message(db, message).await?;
|
||||||
@@ -54,7 +59,7 @@ pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>)
|
|||||||
|
|
||||||
// Users cannot report their own server
|
// Users cannot report their own server
|
||||||
if server.owner == user.id {
|
if server.owner == user.id {
|
||||||
return Err(Error::CannotReportYourself);
|
return Err(create_error!(CannotReportYourself));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (snapshot, files) = SnapshotContent::generate_from_server(server)?;
|
let (snapshot, files) = SnapshotContent::generate_from_server(server)?;
|
||||||
@@ -65,7 +70,7 @@ pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>)
|
|||||||
|
|
||||||
// Users cannot report themselves
|
// Users cannot report themselves
|
||||||
if reported_user.id == user.id {
|
if reported_user.id == user.id {
|
||||||
return Err(Error::CannotReportYourself);
|
return Err(create_error!(CannotReportYourself));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if there is a message provided as context
|
// Determine if there is a message provided as context
|
||||||
@@ -122,7 +127,7 @@ pub async fn report_content(db: &Db, user: User, data: Json<DataReportContent>)
|
|||||||
|
|
||||||
db.insert_report(&report).await?;
|
db.insert_report(&report).await?;
|
||||||
|
|
||||||
EventV1::ReportCreate(report).global().await;
|
EventV1::ReportCreate(report.into()).global().await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub async fn ban(
|
|||||||
|
|
||||||
// If member exists, check privileges against them
|
// If member exists, check privileges against them
|
||||||
if let Ok(member) = target.as_member(db, &server.id).await {
|
if let Ok(member) = target.as_member(db, &server.id).await {
|
||||||
if member.get_ranking(&query.server_ref().as_ref().unwrap())
|
if member.get_ranking(query.server_ref().as_ref().unwrap())
|
||||||
<= query.get_member_rank().unwrap_or(i64::MIN)
|
<= query.get_member_rank().unwrap_or(i64::MIN)
|
||||||
{
|
{
|
||||||
return Err(create_error!(NotElevated));
|
return Err(create_error!(NotElevated));
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub async fn create(
|
|||||||
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
|
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
|
||||||
calculate_server_permissions(&mut query)
|
calculate_server_permissions(&mut query)
|
||||||
.await
|
.await
|
||||||
.throw_if_lacking_channel_permission(ChannelPermission::ManageRole);
|
.throw_if_lacking_channel_permission(ChannelPermission::ManageRole)?;
|
||||||
|
|
||||||
let config = config().await;
|
let config = config().await;
|
||||||
if server.roles.len() >= config.features.limits.default.server_roles {
|
if server.roles.len() >= config.features.limits.default.server_roles {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ pub async fn delete(
|
|||||||
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
|
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
|
||||||
calculate_server_permissions(&mut query)
|
calculate_server_permissions(&mut query)
|
||||||
.await
|
.await
|
||||||
.throw_if_lacking_channel_permission(ChannelPermission::ManageRole);
|
.throw_if_lacking_channel_permission(ChannelPermission::ManageRole)?;
|
||||||
|
|
||||||
let member_rank = query.get_member_rank().unwrap_or(i64::MIN);
|
let member_rank = query.get_member_rank().unwrap_or(i64::MIN);
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub async fn edit(
|
|||||||
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
|
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
|
||||||
calculate_server_permissions(&mut query)
|
calculate_server_permissions(&mut query)
|
||||||
.await
|
.await
|
||||||
.throw_if_lacking_channel_permission(ChannelPermission::ManageRole);
|
.throw_if_lacking_channel_permission(ChannelPermission::ManageRole)?;
|
||||||
|
|
||||||
let member_rank = query.get_member_rank().unwrap_or(i64::MIN);
|
let member_rank = query.get_member_rank().unwrap_or(i64::MIN);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user