Compare commits

...
8 Commits
21 changed files with 106 additions and 146 deletions

No files matched your search

+1 -1
View File
@@ -34,7 +34,7 @@ services:
- minio - minio
entrypoint: > entrypoint: >
/bin/sh -c "while ! /usr/bin/mc ready minio; do /bin/sh -c "while ! /usr/bin/mc ready minio; do
/usr/bin/mc config host add minio http://minio:9000 minioautumn minioautumn; /usr/bin/mc alias set minio http://minio:9000 minioautumn minioautumn;
echo 'Waiting minio...' && sleep 1; echo 'Waiting minio...' && sleep 1;
done; /usr/bin/mc mb minio/revolt-uploads; exit 0;" done; /usr/bin/mc mb minio/revolt-uploads; exit 0;"
@@ -212,16 +212,34 @@ impl AbstractUsers for MongoDb {
partial: &PartialUser, partial: &PartialUser,
remove: Vec<FieldsUser>, remove: Vec<FieldsUser>,
) -> Result<()> { ) -> Result<()> {
query!( if remove.contains(&FieldsUser::StatusText) && partial.status.is_some() {
self, // stupid-ass workaround to fix mongo conflicting the same item
update_one_by_id, let _: Result<()> = query!(
COL, self,
id, update_one_by_id,
partial, COL,
remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(), id,
None PartialUser {
) ..Default::default()
.map(|_| ()) },
remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(),
None
)
.map(|_| ());
query!(self, update_one_by_id, COL, id, partial, vec![], None).map(|_| ())
} else {
query!(
self,
update_one_by_id,
COL,
id,
partial,
remove.iter().map(|x| x as &dyn IntoDocumentPath).collect(),
None
)
.map(|_| ())
}
} }
/// Set relationship with another user /// Set relationship with another user
+2 -2
View File
@@ -132,8 +132,8 @@ auto_derived!(
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 2048)))] #[cfg_attr(feature = "validator", validate(length(min = 1, max = 2048)))]
pub interactions_url: Option<String>, pub interactions_url: Option<String>,
/// Fields to remove from bot object /// Fields to remove from bot object
#[cfg_attr(feature = "validator", validate(length(min = 1)))] #[cfg_attr(feature = "serde", serde(default))]
pub remove: Option<Vec<FieldsBot>>, pub remove: Vec<FieldsBot>,
} }
/// Where we are inviting a bot to /// Where we are inviting a bot to
+1 -1
View File
@@ -207,7 +207,7 @@ auto_derived!(
/// Fields to remove from channel /// Fields to remove from channel
#[cfg_attr(feature = "serde", serde(default))] #[cfg_attr(feature = "serde", serde(default))]
pub remove: Option<Vec<FieldsChannel>>, pub remove: Vec<FieldsChannel>,
} }
/// Create new group /// Create new group
+1 -1
View File
@@ -215,7 +215,7 @@ auto_derived!(
#[derive(Default)] #[derive(Default)]
#[cfg_attr(feature = "validator", derive(Validate))] #[cfg_attr(feature = "validator", derive(Validate))]
pub struct SendableEmbed { pub struct SendableEmbed {
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))] #[cfg_attr(feature = "validator", validate(length(min = 1, max = 256)))]
pub icon_url: Option<String>, pub icon_url: Option<String>,
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 256)))] #[cfg_attr(feature = "validator", validate(length(min = 1, max = 256)))]
pub url: Option<String>, pub url: Option<String>,
+2 -2
View File
@@ -124,7 +124,7 @@ auto_derived!(
/// Timestamp this member is timed out until /// Timestamp this member is timed out until
pub timeout: Option<Timestamp>, pub timeout: Option<Timestamp>,
/// Fields to remove from channel object /// Fields to remove from channel object
#[cfg_attr(feature = "validator", validate(length(min = 1)))] #[cfg_attr(feature = "serde", serde(default))]
pub remove: Option<Vec<FieldsMember>>, pub remove: Vec<FieldsMember>,
} }
); );
+6 -4
View File
@@ -175,6 +175,8 @@ auto_derived!(
/// Ranking position /// Ranking position
/// ///
/// Smaller values take priority. /// Smaller values take priority.
///
/// **Removed** - no effect, use the edit server role positions route
pub rank: Option<i64>, pub rank: Option<i64>,
} }
@@ -247,8 +249,8 @@ auto_derived!(
pub analytics: Option<bool>, pub analytics: Option<bool>,
/// Fields to remove from server object /// Fields to remove from server object
#[cfg_attr(feature = "validator", validate(length(min = 1)))] #[cfg_attr(feature = "serde", serde(default))]
pub remove: Option<Vec<FieldsServer>>, pub remove: Vec<FieldsServer>,
} }
/// New role information /// New role information
@@ -270,8 +272,8 @@ auto_derived!(
/// **Removed** - no effect, use the edit server role positions route /// **Removed** - no effect, use the edit server role positions route
pub rank: Option<i64>, pub rank: Option<i64>,
/// Fields to remove from role object /// Fields to remove from role object
#[cfg_attr(feature = "validator", validate(length(min = 1)))] #[cfg_attr(feature = "serde", serde(default))]
pub remove: Option<Vec<FieldsRole>>, pub remove: Vec<FieldsRole>,
} }
/// New role permissions /// New role permissions
+2 -2
View File
@@ -245,8 +245,8 @@ auto_derived!(
pub flags: Option<i32>, pub flags: Option<i32>,
/// Fields to remove from user object /// Fields to remove from user object
#[cfg_attr(feature = "validator", validate(length(min = 1)))] #[cfg_attr(feature = "serde", serde(default))]
pub remove: Option<Vec<FieldsUser>>, pub remove: Vec<FieldsUser>,
} }
/// User flag reponse /// User flag reponse
+2 -3
View File
@@ -37,7 +37,7 @@ pub async fn edit_bot(
if data.public.is_none() if data.public.is_none()
&& data.analytics.is_none() && data.analytics.is_none()
&& data.interactions_url.is_none() && data.interactions_url.is_none()
&& data.remove.is_none() && data.remove.is_empty()
{ {
return Ok(Json(v0::BotWithUserResponse { return Ok(Json(v0::BotWithUserResponse {
bot: bot.into(), bot: bot.into(),
@@ -64,7 +64,6 @@ pub async fn edit_bot(
db, db,
partial, partial,
remove remove
.unwrap_or_default()
.into_iter() .into_iter()
.map(|v| v.into()) .map(|v| v.into())
.collect(), .collect(),
@@ -100,7 +99,7 @@ mod test {
.body( .body(
json!(v0::DataEditBot { json!(v0::DataEditBot {
public: Some(true), public: Some(true),
remove: Some(vec![FieldsBot::Token]), remove: vec![FieldsBot::Token],
..Default::default() ..Default::default()
}) })
.to_string(), .to_string(),
@@ -38,7 +38,7 @@ pub async fn edit(
&& data.icon.is_none() && data.icon.is_none()
&& data.nsfw.is_none() && data.nsfw.is_none()
&& data.owner.is_none() && data.owner.is_none()
&& data.remove.is_none() && data.remove.is_empty()
{ {
return Ok(Json(channel.into())); return Ok(Json(channel.into()));
} }
@@ -112,23 +112,21 @@ pub async fn edit(
nsfw, nsfw,
.. ..
} => { } => {
if let Some(fields) = &data.remove { if data.remove.contains(&v0::FieldsChannel::Icon) {
if fields.contains(&v0::FieldsChannel::Icon) { if let Some(icon) = &icon {
if let Some(icon) = &icon { db.mark_attachment_as_deleted(&icon.id).await?;
db.mark_attachment_as_deleted(&icon.id).await?;
}
} }
}
for field in fields { for field in &data.remove {
match field { match field {
v0::FieldsChannel::Description => { v0::FieldsChannel::Description => {
description.take(); description.take();
}
v0::FieldsChannel::Icon => {
icon.take();
}
_ => {}
} }
v0::FieldsChannel::Icon => {
icon.take();
}
_ => {}
} }
} }
@@ -214,11 +212,7 @@ pub async fn edit(
.update( .update(
db, db,
partial, partial,
data.remove data.remove.into_iter().map(|f| f.into()).collect(),
.unwrap_or_default()
.into_iter()
.map(|f| f.into())
.collect(),
) )
.await?; .await?;
} }
+1 -1
View File
@@ -50,7 +50,7 @@ pub fn routes() -> (Vec<Route>, OpenApi) {
group_remove_member::remove_member, group_remove_member::remove_member,
voice_join::call, voice_join::call,
permissions_set::set_role_permissions, permissions_set::set_role_permissions,
permissions_set_default::set_default_permissions, permissions_set_default::set_default_channel_permissions,
message_react::react_message, message_react::react_message,
message_unreact::unreact_message, message_unreact::unreact_message,
message_clear_reactions::clear_reactions, message_clear_reactions::clear_reactions,
@@ -14,7 +14,7 @@ use rocket::{serde::json::Json, State};
/// Channel must be a `Group`, `TextChannel` or `VoiceChannel`. /// Channel must be a `Group`, `TextChannel` or `VoiceChannel`.
#[openapi(tag = "Channel Permissions")] #[openapi(tag = "Channel Permissions")]
#[put("/<target>/permissions/default", data = "<data>", rank = 1)] #[put("/<target>/permissions/default", data = "<data>", rank = 1)]
pub async fn set_default_permissions( pub async fn set_default_channel_permissions(
db: &State<Database>, db: &State<Database>,
user: User, user: User,
target: Reference, target: Reference,
+8 -40
View File
@@ -39,13 +39,7 @@ pub async fn edit(
let permissions = calculate_server_permissions(&mut query).await; let permissions = calculate_server_permissions(&mut query).await;
// Check permissions in server // Check permissions in server
if data.nickname.is_some() if data.nickname.is_some() || data.remove.contains(&v0::FieldsMember::Nickname) {
|| data
.remove
.as_ref()
.map(|x| x.contains(&v0::FieldsMember::Nickname))
.unwrap_or_default()
{
if user.id == member.id.user { if user.id == member.id.user {
permissions.throw_if_lacking_channel_permission(ChannelPermission::ChangeNickname)?; permissions.throw_if_lacking_channel_permission(ChannelPermission::ChangeNickname)?;
} else { } else {
@@ -53,13 +47,7 @@ pub async fn edit(
} }
} }
if data.avatar.is_some() if data.avatar.is_some() || data.remove.contains(&v0::FieldsMember::Avatar) {
|| data
.remove
.as_ref()
.map(|x| x.contains(&v0::FieldsMember::Avatar))
.unwrap_or_default()
{
if user.id == member.id.user { if user.id == member.id.user {
permissions.throw_if_lacking_channel_permission(ChannelPermission::ChangeAvatar)?; permissions.throw_if_lacking_channel_permission(ChannelPermission::ChangeAvatar)?;
} else { } else {
@@ -67,23 +55,11 @@ pub async fn edit(
} }
} }
if data.roles.is_some() if data.roles.is_some() || data.remove.contains(&v0::FieldsMember::Roles) {
|| data
.remove
.as_ref()
.map(|x| x.contains(&v0::FieldsMember::Roles))
.unwrap_or_default()
{
permissions.throw_if_lacking_channel_permission(ChannelPermission::AssignRoles)?; permissions.throw_if_lacking_channel_permission(ChannelPermission::AssignRoles)?;
} }
if data.timeout.is_some() if data.timeout.is_some() || data.remove.contains(&v0::FieldsMember::Timeout) {
|| data
.remove
.as_ref()
.map(|x| x.contains(&v0::FieldsMember::Timeout))
.unwrap_or_default()
{
if data.timeout.is_some() && member.id.user == user.id { if data.timeout.is_some() && member.id.user == user.id {
return Err(create_error!(CannotTimeoutYourself)); return Err(create_error!(CannotTimeoutYourself));
} }
@@ -136,11 +112,9 @@ pub async fn edit(
}; };
// 1. Remove fields from object // 1. Remove fields from object
if let Some(fields) = &remove { if remove.contains(&v0::FieldsMember::Avatar) {
if fields.contains(&v0::FieldsMember::Avatar) { if let Some(avatar) = &member.avatar {
if let Some(avatar) = &member.avatar { db.mark_attachment_as_deleted(&avatar.id).await?;
db.mark_attachment_as_deleted(&avatar.id).await?;
}
} }
} }
@@ -150,13 +124,7 @@ pub async fn edit(
} }
member member
.update( .update(db, partial, remove.into_iter().map(Into::into).collect())
db,
partial,
remove
.map(|v| v.into_iter().map(Into::into).collect())
.unwrap_or_default(),
)
.await?; .await?;
Ok(Json(member.into())) Ok(Json(member.into()))
+2 -2
View File
@@ -17,8 +17,8 @@ mod permissions_set_default;
mod roles_create; mod roles_create;
mod roles_delete; mod roles_delete;
mod roles_edit; mod roles_edit;
mod roles_fetch;
mod roles_edit_positions; mod roles_edit_positions;
mod roles_fetch;
mod server_ack; mod server_ack;
mod server_create; mod server_create;
mod server_delete; mod server_delete;
@@ -47,7 +47,7 @@ pub fn routes() -> (Vec<Route>, OpenApi) {
roles_fetch::fetch, roles_fetch::fetch,
roles_delete::delete, roles_delete::delete,
permissions_set::set_role_permission, permissions_set::set_role_permission,
permissions_set_default::set_default_permissions, permissions_set_default::set_default_server_permissions,
emoji_list::list_emoji, emoji_list::list_emoji,
roles_edit_positions::edit_role_ranks roles_edit_positions::edit_role_ranks
] ]
@@ -14,7 +14,7 @@ use rocket::{serde::json::Json, State};
/// Sets permissions for the default role in this server. /// Sets permissions for the default role in this server.
#[openapi(tag = "Server Permissions")] #[openapi(tag = "Server Permissions")]
#[put("/<target>/permissions/default", data = "<data>", rank = 1)] #[put("/<target>/permissions/default", data = "<data>", rank = 1)]
pub async fn set_default_permissions( pub async fn set_default_server_permissions(
db: &State<Database>, db: &State<Database>,
user: User, user: User,
target: Reference, target: Reference,
@@ -40,20 +40,10 @@ pub async fn create(
})); }));
}; };
let member_rank = query.get_member_rank();
let rank = if let Some(given_rank) = data.rank {
if given_rank <= member_rank.unwrap_or(i64::MIN) {
return Err(create_error!(NotElevated));
}
given_rank
} else {
member_rank.unwrap_or(0).saturating_add(1)
};
let role = Role { let role = Role {
name: data.name, name: data.name,
rank, // Rank of the new role should be below the lowest role
rank: server.roles.len() as i64,
colour: None, colour: None,
hoist: false, hoist: false,
permissions: Default::default(), permissions: Default::default(),
@@ -61,9 +61,7 @@ pub async fn edit(
&server.id, &server.id,
&role_id, &role_id,
partial, partial,
remove remove.into_iter().map(Into::into).collect(),
.map(|v| v.into_iter().map(Into::into).collect())
.unwrap_or_default(),
) )
.await?; .await?;
+10 -18
View File
@@ -43,7 +43,7 @@ pub async fn edit(
&& data.flags.is_none() && data.flags.is_none()
&& data.analytics.is_none() && data.analytics.is_none()
&& data.discoverable.is_none() && data.discoverable.is_none()
&& data.remove.is_none() && data.remove.is_empty()
{ {
return Ok(Json(server.into())); return Ok(Json(server.into()));
} else if data.name.is_some() } else if data.name.is_some()
@@ -52,7 +52,7 @@ pub async fn edit(
|| data.banner.is_some() || data.banner.is_some()
|| data.system_messages.is_some() || data.system_messages.is_some()
|| data.analytics.is_some() || data.analytics.is_some()
|| data.remove.is_some() || !data.remove.is_empty()
{ {
permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageServer)?; permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageServer)?;
} }
@@ -96,17 +96,15 @@ pub async fn edit(
}; };
// 1. Remove fields from object // 1. Remove fields from object
if let Some(fields) = &remove { if remove.contains(&v0::FieldsServer::Banner) {
if fields.contains(&v0::FieldsServer::Banner) { if let Some(banner) = &server.banner {
if let Some(banner) = &server.banner { db.mark_attachment_as_deleted(&banner.id).await?;
db.mark_attachment_as_deleted(&banner.id).await?;
}
} }
}
if fields.contains(&v0::FieldsServer::Icon) { if remove.contains(&v0::FieldsServer::Icon) {
if let Some(icon) = &server.icon { if let Some(icon) = &server.icon {
db.mark_attachment_as_deleted(&icon.id).await?; db.mark_attachment_as_deleted(&icon.id).await?;
}
} }
} }
@@ -149,13 +147,7 @@ pub async fn edit(
} }
server server
.update( .update(db, partial, remove.into_iter().map(Into::into).collect())
db,
partial,
remove
.map(|v| v.into_iter().map(Into::into).collect())
.unwrap_or_default(),
)
.await?; .await?;
Ok(Json(server.into())) Ok(Json(server.into()))
+16 -20
View File
@@ -53,31 +53,29 @@ pub async fn edit(
&& data.avatar.is_none() && data.avatar.is_none()
&& data.badges.is_none() && data.badges.is_none()
&& data.flags.is_none() && data.flags.is_none()
&& data.remove.is_none() && data.remove.is_empty()
{ {
return Ok(Json(user.into_self(false).await)); return Ok(Json(user.into_self(false).await));
} }
// 1. Remove fields from object // 1. Remove fields from object
if let Some(fields) = &data.remove { if data.remove.contains(&v0::FieldsUser::Avatar) {
if fields.contains(&v0::FieldsUser::Avatar) { if let Some(avatar) = &user.avatar {
if let Some(avatar) = &user.avatar { db.mark_attachment_as_deleted(&avatar.id).await?;
db.mark_attachment_as_deleted(&avatar.id).await?; }
}
if data.remove.contains(&v0::FieldsUser::ProfileBackground) {
if let Some(profile) = &user.profile {
if let Some(background) = &profile.background {
db.mark_attachment_as_deleted(&background.id).await?;
} }
} }
}
if fields.contains(&v0::FieldsUser::ProfileBackground) { for field in &data.remove {
if let Some(profile) = &user.profile { let field: FieldsUser = field.clone().into();
if let Some(background) = &profile.background { user.remove_field(&field);
db.mark_attachment_as_deleted(&background.id).await?;
}
}
}
for field in fields {
let field: FieldsUser = field.clone().into();
user.remove_field(&field);
}
} }
let mut partial: PartialUser = PartialUser { let mut partial: PartialUser = PartialUser {
@@ -124,9 +122,7 @@ pub async fn edit(
user.update( user.update(
db, db,
partial, partial,
data.remove data.remove.into_iter().map(Into::into).collect(),
.map(|v| v.into_iter().map(Into::into).collect())
.unwrap_or_default(),
) )
.await?; .await?;
+4 -1
View File
@@ -1,9 +1,12 @@
{ pkgs ? import <nixpkgs> {} }: {
pkgs ? import <nixpkgs> { },
}:
pkgs.mkShell rec { pkgs.mkShell rec {
buildInputs = [ buildInputs = [
# Tools # Tools
pkgs.git pkgs.git
pkgs.just
# Cargo # Cargo
pkgs.cargo pkgs.cargo
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
date=$(date +'%Y%m%d') date=$(date +'%Y%m%d')
incr=1 incr=1