forked from jmug/stoatchat
Compare commits
9
Commits
20220715-1
...
20220902-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
deffe663cb | ||
|
|
e7f6433d77 | ||
|
|
345e4d5f13 | ||
|
|
81fc3e7760 | ||
|
|
ca8d2e6118 | ||
|
|
c1227e8e33 | ||
|
|
0e0c6f2c3a | ||
|
|
fa82be74b5 | ||
|
|
8491ced13d |
Generated
+4
-3
@@ -1454,12 +1454,12 @@ checksum = "90f97a5f38dd3ccfbe7aa80f4a0c00930f21b922c74195be0201c51028f22dcf"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.8.2"
|
version = "1.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
|
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 1.1.0",
|
"autocfg 1.1.0",
|
||||||
"hashbrown 0.11.2",
|
"hashbrown 0.12.1",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2783,6 +2783,7 @@ dependencies = [
|
|||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
"impl_ops",
|
"impl_ops",
|
||||||
|
"indexmap",
|
||||||
"iso8601-timestamp",
|
"iso8601-timestamp",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"linkify 0.8.1",
|
"linkify 0.8.1",
|
||||||
|
|||||||
@@ -2,13 +2,27 @@ use revolt_quark::{
|
|||||||
models::{channel::PartialChannel, Channel, User},
|
models::{channel::PartialChannel, Channel, User},
|
||||||
perms, Db, EmptyResponse, Error, Permission, Ref, Result,
|
perms, Db, EmptyResponse, Error, Permission, Ref, Result,
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use validator::Validate;
|
||||||
|
|
||||||
|
/// # Query Parameters
|
||||||
|
#[derive(Validate, Serialize, Deserialize, JsonSchema, FromForm)]
|
||||||
|
pub struct OptionsChannelDelete {
|
||||||
|
/// Whether to not send a leave message
|
||||||
|
leave_silently: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
/// # Close Channel
|
/// # Close Channel
|
||||||
///
|
///
|
||||||
/// Deletes a server channel, leaves a group or closes a group.
|
/// Deletes a server channel, leaves a group or closes a group.
|
||||||
#[openapi(tag = "Channel Information")]
|
#[openapi(tag = "Channel Information")]
|
||||||
#[delete("/<target>")]
|
#[delete("/<target>?<options..>")]
|
||||||
pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
|
pub async fn req(
|
||||||
|
db: &Db,
|
||||||
|
user: User,
|
||||||
|
target: Ref,
|
||||||
|
options: OptionsChannelDelete,
|
||||||
|
) -> Result<EmptyResponse> {
|
||||||
let mut channel = target.as_channel(db).await?;
|
let mut channel = target.as_channel(db).await?;
|
||||||
let mut perms = perms(&user).channel(&channel);
|
let mut perms = perms(&user).channel(&channel);
|
||||||
perms.throw_permission(db, Permission::ViewChannel).await?;
|
perms.throw_permission(db, Permission::ViewChannel).await?;
|
||||||
@@ -27,7 +41,12 @@ pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
|
|||||||
.await
|
.await
|
||||||
.map(|_| EmptyResponse),
|
.map(|_| EmptyResponse),
|
||||||
Channel::Group { .. } => channel
|
Channel::Group { .. } => channel
|
||||||
.remove_user_from_group(db, &user.id, None)
|
.remove_user_from_group(
|
||||||
|
db,
|
||||||
|
&user.id,
|
||||||
|
None,
|
||||||
|
options.leave_silently.unwrap_or_default(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.map(|_| EmptyResponse),
|
.map(|_| EmptyResponse),
|
||||||
Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => {
|
Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ pub struct DataEditChannel {
|
|||||||
icon: Option<String>,
|
icon: Option<String>,
|
||||||
/// Whether this channel is age-restricted
|
/// Whether this channel is age-restricted
|
||||||
nsfw: Option<bool>,
|
nsfw: Option<bool>,
|
||||||
|
/// Whether this channel is archived
|
||||||
|
archived: Option<bool>,
|
||||||
#[validate(length(min = 1))]
|
#[validate(length(min = 1))]
|
||||||
remove: Option<Vec<FieldsChannel>>,
|
remove: Option<Vec<FieldsChannel>>,
|
||||||
}
|
}
|
||||||
@@ -83,6 +85,7 @@ pub async fn req(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transfer ownership
|
// Transfer ownership
|
||||||
|
partial.owner = Some(new_owner.to_string());
|
||||||
let old_owner = std::mem::replace(owner, new_owner.to_string());
|
let old_owner = std::mem::replace(owner, new_owner.to_string());
|
||||||
|
|
||||||
// Notify clients
|
// Notify clients
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyR
|
|||||||
}
|
}
|
||||||
|
|
||||||
channel
|
channel
|
||||||
.remove_user_from_group(db, &member.id, Some(&user.id))
|
.remove_user_from_group(db, &member.id, Some(&user.id), false)
|
||||||
.await
|
.await
|
||||||
.map(|_| EmptyResponse)
|
.map(|_| EmptyResponse)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ pub async fn message_send(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. Ensure interactions information is correct
|
// 3. Ensure interactions information is correct
|
||||||
message.interactions.validate(db).await?;
|
message.interactions.validate(db, &mut permissions).await?;
|
||||||
|
|
||||||
// 4. Verify replies are valid.
|
// 4. Verify replies are valid.
|
||||||
let mut replies = HashSet::new();
|
let mut replies = HashSet::new();
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ pub async fn create_emoji(
|
|||||||
// Check that there are no more than 100 emoji
|
// Check that there are no more than 100 emoji
|
||||||
// ! FIXME: hardcoded upper limit
|
// ! FIXME: hardcoded upper limit
|
||||||
let emojis = db.fetch_emoji_by_parent_id(&server.id).await?;
|
let emojis = db.fetch_emoji_by_parent_id(&server.id).await?;
|
||||||
if emojis.len() > 100 {
|
if emojis.len() > 99 {
|
||||||
return Err(Error::TooManyEmoji);
|
return Err(Error::TooManyEmoji);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,16 @@ pub async fn req(
|
|||||||
required.push(Permission::AssignRoles);
|
required.push(Permission::AssignRoles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if data.timeout.is_some()
|
||||||
|
|| data
|
||||||
|
.remove
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| x.contains(&FieldsMember::Timeout))
|
||||||
|
.unwrap_or_default()
|
||||||
|
{
|
||||||
|
required.push(Permission::TimeoutMembers);
|
||||||
|
}
|
||||||
|
|
||||||
for permission in required {
|
for permission in required {
|
||||||
permissions.throw_permission(db, permission).await?;
|
permissions.throw_permission(db, permission).await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyR
|
|||||||
}
|
}
|
||||||
|
|
||||||
server
|
server
|
||||||
.remove_member(db, member, RemovalIntention::Kick)
|
.remove_member(db, member, RemovalIntention::Kick, false)
|
||||||
.await
|
.await
|
||||||
.map(|_| EmptyResponse)
|
.map(|_| EmptyResponse)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,27 @@ use revolt_quark::{
|
|||||||
models::{server_member::RemovalIntention, User},
|
models::{server_member::RemovalIntention, User},
|
||||||
Db, EmptyResponse, Ref, Result,
|
Db, EmptyResponse, Ref, Result,
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use validator::Validate;
|
||||||
|
|
||||||
|
/// # Query Parameters
|
||||||
|
#[derive(Validate, Serialize, Deserialize, JsonSchema, FromForm)]
|
||||||
|
pub struct OptionsServerDelete {
|
||||||
|
/// Whether to not send a leave message
|
||||||
|
leave_silently: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
/// # Delete / Leave Server
|
/// # Delete / Leave Server
|
||||||
///
|
///
|
||||||
/// Deletes a server if owner otherwise leaves.
|
/// Deletes a server if owner otherwise leaves.
|
||||||
#[openapi(tag = "Server Information")]
|
#[openapi(tag = "Server Information")]
|
||||||
#[delete("/<target>")]
|
#[delete("/<target>?<options..>")]
|
||||||
pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
|
pub async fn req(
|
||||||
|
db: &Db,
|
||||||
|
user: User,
|
||||||
|
target: Ref,
|
||||||
|
options: OptionsServerDelete,
|
||||||
|
) -> Result<EmptyResponse> {
|
||||||
let server = target.as_server(db).await?;
|
let server = target.as_server(db).await?;
|
||||||
let member = db.fetch_member(&target.id, &user.id).await?;
|
let member = db.fetch_member(&target.id, &user.id).await?;
|
||||||
|
|
||||||
@@ -16,7 +30,12 @@ pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
|
|||||||
server.delete(db).await
|
server.delete(db).await
|
||||||
} else {
|
} else {
|
||||||
server
|
server
|
||||||
.remove_member(db, member, RemovalIntention::Leave)
|
.remove_member(
|
||||||
|
db,
|
||||||
|
member,
|
||||||
|
RemovalIntention::Leave,
|
||||||
|
options.leave_silently.unwrap_or_default(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
.map(|_| EmptyResponse)
|
.map(|_| EmptyResponse)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use revolt_quark::{
|
use revolt_quark::{
|
||||||
models::{
|
models::{
|
||||||
server::{Category, FieldsServer, PartialServer, SystemMessageChannels},
|
server::{Category, FieldsServer, PartialServer, SystemMessageChannels},
|
||||||
@@ -135,29 +137,43 @@ pub async fn req(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Apply new icon
|
// 2. Validate changes
|
||||||
|
let mut unknown_channels = HashSet::new();
|
||||||
|
if let Some(system_messages) = &partial.system_messages {
|
||||||
|
unknown_channels = system_messages.clone().into_channel_ids();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(categories) = &partial.categories {
|
||||||
|
let mut channel_ids = HashSet::new();
|
||||||
|
for category in categories {
|
||||||
|
for channel in &category.channels {
|
||||||
|
if channel_ids.contains(channel) {
|
||||||
|
return Err(Error::InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_ids.insert(channel.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unknown_channels.extend(channel_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !db.check_channels_exist(&unknown_channels).await? {
|
||||||
|
return Err(Error::NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Apply new icon
|
||||||
if let Some(icon) = icon {
|
if let Some(icon) = icon {
|
||||||
partial.icon = Some(File::use_server_icon(db, &icon, &server.id).await?);
|
partial.icon = Some(File::use_server_icon(db, &icon, &server.id).await?);
|
||||||
server.icon = partial.icon.clone();
|
server.icon = partial.icon.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Apply new banner
|
// 4. Apply new banner
|
||||||
if let Some(banner) = banner {
|
if let Some(banner) = banner {
|
||||||
partial.banner = Some(File::use_banner(db, &banner, &server.id).await?);
|
partial.banner = Some(File::use_banner(db, &banner, &server.id).await?);
|
||||||
server.banner = partial.banner.clone();
|
server.banner = partial.banner.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Validate changes
|
|
||||||
if let Some(system_messages) = &partial.system_messages {
|
|
||||||
let channels = system_messages.clone().into_channel_ids();
|
|
||||||
if !db
|
|
||||||
.check_channels_exist(&channels.into_iter().collect())
|
|
||||||
.await?
|
|
||||||
{
|
|
||||||
return Err(Error::NotFound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server
|
server
|
||||||
.update(db, partial, remove.unwrap_or_default())
|
.update(db, partial, remove.unwrap_or_default())
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ regex = "1.5.5"
|
|||||||
nanoid = "0.4.0"
|
nanoid = "0.4.0"
|
||||||
linkify = "0.8.1"
|
linkify = "0.8.1"
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
|
indexmap = "1.9.1"
|
||||||
impl_ops = "0.1.1"
|
impl_ops = "0.1.1"
|
||||||
num_enum = "0.5.6"
|
num_enum = "0.5.6"
|
||||||
reqwest = "0.11.10"
|
reqwest = "0.11.10"
|
||||||
|
|||||||
@@ -286,6 +286,7 @@ impl Channel {
|
|||||||
db: &Database,
|
db: &Database,
|
||||||
user: &str,
|
user: &str,
|
||||||
by: Option<&str>,
|
by: Option<&str>,
|
||||||
|
silent: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match &self {
|
match &self {
|
||||||
Channel::Group {
|
Channel::Group {
|
||||||
@@ -329,20 +330,22 @@ impl Channel {
|
|||||||
.p(id.to_string())
|
.p(id.to_string())
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Some(by) = by {
|
if !silent {
|
||||||
SystemMessage::UserRemove {
|
if let Some(by) = by {
|
||||||
id: user.to_string(),
|
SystemMessage::UserRemove {
|
||||||
by: by.to_string(),
|
id: user.to_string(),
|
||||||
}
|
by: by.to_string(),
|
||||||
} else {
|
}
|
||||||
SystemMessage::UserLeft {
|
} else {
|
||||||
id: user.to_string(),
|
SystemMessage::UserLeft {
|
||||||
|
id: user.to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.into_message(id.to_string())
|
||||||
|
.create(db, self, None)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
.into_message(id.to_string())
|
|
||||||
.create(db, self, None)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,14 @@ use crate::{
|
|||||||
},
|
},
|
||||||
Channel, Emoji, Message, User,
|
Channel, Emoji, Message, User,
|
||||||
},
|
},
|
||||||
|
permissions::PermissionCalculator,
|
||||||
presence::presence_filter_online,
|
presence::presence_filter_online,
|
||||||
tasks::ack::AckEvent,
|
tasks::ack::AckEvent,
|
||||||
types::{
|
types::{
|
||||||
january::{Embed, Text},
|
january::{Embed, Text},
|
||||||
push::PushNotification,
|
push::PushNotification,
|
||||||
},
|
},
|
||||||
Database, Error, Result,
|
Database, Error, Permission, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
@@ -195,6 +196,11 @@ impl Message {
|
|||||||
|
|
||||||
/// Add a reaction to a message
|
/// Add a reaction to a message
|
||||||
pub async fn add_reaction(&self, db: &Database, user: &User, emoji: &str) -> Result<()> {
|
pub async fn add_reaction(&self, db: &Database, user: &User, emoji: &str) -> Result<()> {
|
||||||
|
// Check how many reactions are already on the message
|
||||||
|
if self.reactions.len() >= 20 {
|
||||||
|
return Err(Error::InvalidOperation);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the emoji is whitelisted
|
// Check if the emoji is whitelisted
|
||||||
if !self.interactions.can_use(emoji) {
|
if !self.interactions.can_use(emoji) {
|
||||||
return Err(Error::InvalidOperation);
|
return Err(Error::InvalidOperation);
|
||||||
@@ -401,8 +407,14 @@ impl BulkMessageResponse {
|
|||||||
|
|
||||||
impl Interactions {
|
impl Interactions {
|
||||||
/// Validate interactions info is correct
|
/// Validate interactions info is correct
|
||||||
pub async fn validate(&self, db: &Database) -> Result<()> {
|
pub async fn validate(
|
||||||
|
&self,
|
||||||
|
db: &Database,
|
||||||
|
permissions: &mut PermissionCalculator<'_>,
|
||||||
|
) -> Result<()> {
|
||||||
if let Some(reactions) = &self.reactions {
|
if let Some(reactions) = &self.reactions {
|
||||||
|
permissions.throw_permission(db, Permission::React).await?;
|
||||||
|
|
||||||
if reactions.len() > 20 {
|
if reactions.len() > 20 {
|
||||||
return Err(Error::InvalidOperation);
|
return Err(Error::InvalidOperation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use iso8601_timestamp::Timestamp;
|
use iso8601_timestamp::Timestamp;
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
|
|
||||||
@@ -254,6 +256,7 @@ impl Server {
|
|||||||
db: &Database,
|
db: &Database,
|
||||||
member: Member,
|
member: Member,
|
||||||
intention: RemovalIntention,
|
intention: RemovalIntention,
|
||||||
|
silent: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
db.delete_member(&member.id).await?;
|
db.delete_member(&member.id).await?;
|
||||||
|
|
||||||
@@ -264,20 +267,22 @@ impl Server {
|
|||||||
.p(member.id.server)
|
.p(member.id.server)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Some(id) = self.system_messages.as_ref().and_then(|x| match intention {
|
if !silent {
|
||||||
RemovalIntention::Leave => x.user_left.as_ref(),
|
if let Some(id) = self.system_messages.as_ref().and_then(|x| match intention {
|
||||||
RemovalIntention::Kick => x.user_kicked.as_ref(),
|
RemovalIntention::Leave => x.user_left.as_ref(),
|
||||||
RemovalIntention::Ban => x.user_banned.as_ref(),
|
RemovalIntention::Kick => x.user_kicked.as_ref(),
|
||||||
}) {
|
RemovalIntention::Ban => x.user_banned.as_ref(),
|
||||||
match intention {
|
}) {
|
||||||
RemovalIntention::Leave => SystemMessage::UserLeft { id: member.id.user },
|
match intention {
|
||||||
RemovalIntention::Kick => SystemMessage::UserKicked { id: member.id.user },
|
RemovalIntention::Leave => SystemMessage::UserLeft { id: member.id.user },
|
||||||
RemovalIntention::Ban => SystemMessage::UserBanned { id: member.id.user },
|
RemovalIntention::Kick => SystemMessage::UserKicked { id: member.id.user },
|
||||||
|
RemovalIntention::Ban => SystemMessage::UserBanned { id: member.id.user },
|
||||||
|
}
|
||||||
|
.into_message(id.to_string())
|
||||||
|
.create_no_web_push(db, id, false)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
.into_message(id.to_string())
|
|
||||||
.create_no_web_push(db, id, false)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -302,7 +307,7 @@ impl Server {
|
|||||||
member: Member,
|
member: Member,
|
||||||
reason: Option<String>,
|
reason: Option<String>,
|
||||||
) -> Result<ServerBan> {
|
) -> Result<ServerBan> {
|
||||||
self.remove_member(db, member.clone(), RemovalIntention::Ban)
|
self.remove_member(db, member.clone(), RemovalIntention::Ban, false)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.ban_user(db, member.id, reason).await
|
self.ban_user(db, member.id, reason).await
|
||||||
@@ -310,23 +315,23 @@ impl Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SystemMessageChannels {
|
impl SystemMessageChannels {
|
||||||
pub fn into_channel_ids(self) -> Vec<String> {
|
pub fn into_channel_ids(self) -> HashSet<String> {
|
||||||
let mut ids = vec![];
|
let mut ids = HashSet::new();
|
||||||
|
|
||||||
if let Some(id) = self.user_joined {
|
if let Some(id) = self.user_joined {
|
||||||
ids.push(id);
|
ids.insert(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = self.user_left {
|
if let Some(id) = self.user_left {
|
||||||
ids.push(id);
|
ids.insert(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = self.user_kicked {
|
if let Some(id) = self.user_kicked {
|
||||||
ids.push(id);
|
ids.insert(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = self.user_banned {
|
if let Some(id) = self.user_banned {
|
||||||
ids.push(id);
|
ids.insert(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ids
|
ids
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use crate::util::regex::RE_COLOUR;
|
use crate::util::regex::RE_COLOUR;
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
|
|
||||||
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
use iso8601_timestamp::Timestamp;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use iso8601_timestamp::Timestamp;
|
|
||||||
|
|
||||||
#[cfg(feature = "rocket_impl")]
|
#[cfg(feature = "rocket_impl")]
|
||||||
use rocket::FromFormField;
|
use rocket::FromFormField;
|
||||||
|
|
||||||
@@ -99,7 +98,7 @@ pub struct Masquerade {
|
|||||||
pub struct Interactions {
|
pub struct Interactions {
|
||||||
/// Reactions which should always appear and be distinct
|
/// Reactions which should always appear and be distinct
|
||||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||||
pub reactions: Option<HashSet<String>>,
|
pub reactions: Option<IndexSet<String>>,
|
||||||
/// Whether reactions should be restricted to the given list
|
/// Whether reactions should be restricted to the given list
|
||||||
#[serde(skip_serializing_if = "if_false", default)]
|
#[serde(skip_serializing_if = "if_false", default)]
|
||||||
pub restrict_reactions: bool,
|
pub restrict_reactions: bool,
|
||||||
@@ -145,8 +144,8 @@ pub struct Message {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub replies: Option<Vec<String>>,
|
pub replies: Option<Vec<String>>,
|
||||||
/// Hashmap of emoji IDs to array of user IDs
|
/// Hashmap of emoji IDs to array of user IDs
|
||||||
#[serde(skip_serializing_if = "HashMap::is_empty", default)]
|
#[serde(skip_serializing_if = "IndexMap::is_empty", default)]
|
||||||
pub reactions: HashMap<String, HashSet<String>>,
|
pub reactions: IndexMap<String, IndexSet<String>>,
|
||||||
/// Information about how this message should be interacted with
|
/// Information about how this message should be interacted with
|
||||||
#[serde(skip_serializing_if = "Interactions::is_default", default)]
|
#[serde(skip_serializing_if = "Interactions::is_default", default)]
|
||||||
pub interactions: Interactions,
|
pub interactions: Interactions,
|
||||||
|
|||||||
@@ -119,23 +119,28 @@ async fn calculate_channel_permission(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Channel::DirectMessage { recipients, .. } => {
|
Channel::DirectMessage { recipients, .. } => {
|
||||||
// 2. Fetch user.
|
// 2. Ensure we are a recipient.
|
||||||
let other_user = recipients
|
if recipients.contains(&data.perspective.id) {
|
||||||
.iter()
|
// 3. Fetch user.
|
||||||
.find(|x| x != &&data.perspective.id)
|
let other_user = recipients
|
||||||
.unwrap();
|
.iter()
|
||||||
|
.find(|x| x != &&data.perspective.id)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let user = db.fetch_user(other_user).await?;
|
let user = db.fetch_user(other_user).await?;
|
||||||
data.user.set(user);
|
data.user.set(user);
|
||||||
|
|
||||||
// 3. Calculate user permissions.
|
// 4. Calculate user permissions.
|
||||||
let perms = data.calc_user(db).await;
|
let perms = data.calc_user(db).await;
|
||||||
|
|
||||||
// 4. Check if the user can send messages.
|
// 5. Check if the user can send messages.
|
||||||
if perms.get_send_message() {
|
if perms.get_send_message() {
|
||||||
(*DEFAULT_PERMISSION_DIRECT_MESSAGE).into()
|
(*DEFAULT_PERMISSION_DIRECT_MESSAGE).into()
|
||||||
|
} else {
|
||||||
|
(*DEFAULT_PERMISSION_VIEW_ONLY).into()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
(*DEFAULT_PERMISSION_VIEW_ONLY).into()
|
0_u64.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Channel::Group {
|
Channel::Group {
|
||||||
|
|||||||
Reference in New Issue
Block a user