Servers: Route for kicking a member.

This commit is contained in:
Paul
2021-06-06 15:22:23 +01:00
parent 1f1d9613e2
commit 782bfb7e03
7 changed files with 86 additions and 18 deletions

View File

@@ -258,4 +258,30 @@ impl Server {
Ok(())
}
pub async fn remove_member(&self, id: &str) -> Result<()> {
get_collection("server_members")
.delete_one(
doc! {
"_id": {
"server": &self.id,
"user": &id
}
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "delete_one",
with: "server_members",
})?;
ClientboundNotification::ServerMemberLeave {
id: self.id.clone(),
user: id.to_string()
}
.publish(self.id.clone());
Ok(())
}
}

View File

@@ -28,14 +28,14 @@ pub enum RelationshipStatus {
BlockedOther,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Relationship {
#[serde(rename = "_id")]
pub id: String,
pub status: RelationshipStatus,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Presence {
Online,
Idle,
@@ -43,7 +43,7 @@ pub enum Presence {
Invisible,
}
#[derive(Validate, Serialize, Deserialize, Debug)]
#[derive(Validate, Serialize, Deserialize, Debug, Clone)]
pub struct UserStatus {
#[validate(length(min = 1, max = 128))]
#[serde(skip_serializing_if = "Option::is_none")]
@@ -52,7 +52,7 @@ pub struct UserStatus {
pub presence: Option<Presence>,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct UserProfile {
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
@@ -72,7 +72,7 @@ pub enum Badges {
impl_op_ex_commutative!(+ |a: &i32, b: &Badges| -> i32 { *a | *b as i32 });
// When changing this struct, update notifications/payload.rs#80
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct User {
#[serde(rename = "_id")]
pub id: String,

View File

@@ -9,7 +9,8 @@ use std::ops;
#[repr(u32)]
pub enum ServerPermission {
View = 0b00000000000000000000000000000001, // 1
// 2 bits of space
ManageMembers = 0b00000000000000000000000000000010, // 2
ManageChannels = 0b00000000000000000000000000000100, // 4
ManageServer = 0b00000000000000000000000000001000, // 8
// 8 bits of space
ChangeNickname = 0b00000000000000000001000000000000, // 4096
@@ -26,6 +27,8 @@ bitfield! {
pub struct ServerPermissions(MSB0 [u32]);
u32;
pub get_view, _: 31;
pub get_manage_members, _: 30;
pub get_manage_channels, _: 29;
pub get_manage_server, _: 28;
pub get_change_nickname, _: 19;

View File

@@ -11,7 +11,7 @@ use crate::{
util::result::{Error, Result},
};
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "error")]
pub enum WebSocketError {
LabelMe,
@@ -29,7 +29,7 @@ pub enum ServerboundNotification {
EndTyping { channel: String },
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum RemoveUserField {
ProfileContent,
ProfileBackground,
@@ -37,26 +37,26 @@ pub enum RemoveUserField {
Avatar,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum RemoveChannelField {
Icon,
Description,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum RemoveServerField {
Icon,
Banner,
Description,
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum RemoveMemberField {
Nickname,
Avatar
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum ClientboundNotification {
Error(WebSocketError),
@@ -210,7 +210,7 @@ pub async fn prehandle_hook(notification: &ClientboundNotification) -> Result<()
Ok(())
}
pub fn posthandle_hook(notification: &ClientboundNotification) {
pub async fn posthandle_hook(notification: &ClientboundNotification) {
match &notification {
ClientboundNotification::ChannelDelete { id } => {
get_hive().hive.drop_topic(&id).ok();
@@ -218,7 +218,7 @@ pub fn posthandle_hook(notification: &ClientboundNotification) {
ClientboundNotification::ChannelGroupLeave { id, user } => {
get_hive()
.hive
.unsubscribe(&user.to_string(), &id.to_string())
.unsubscribe(user, id)
.ok();
}
ClientboundNotification::ServerDelete { id } => {
@@ -227,14 +227,23 @@ pub fn posthandle_hook(notification: &ClientboundNotification) {
ClientboundNotification::ServerMemberLeave { id, user } => {
get_hive()
.hive
.unsubscribe(&user.to_string(), &id.to_string())
.unsubscribe(user, id)
.ok();
if let Ok(server) = Ref::from_unchecked(id.clone()).fetch_server().await {
for channel in server.channels {
get_hive()
.hive
.unsubscribe(user, &channel)
.ok();
}
}
}
ClientboundNotification::UserRelationship { id, user, status } => {
if status == &RelationshipStatus::None {
get_hive()
.hive
.unsubscribe(&id.to_string(), &user.id.to_string())
.unsubscribe(id, &user.id)
.ok();
}
}

View File

@@ -13,8 +13,11 @@ static HIVE: OnceCell<Hive> = OnceCell::new();
pub async fn init_hive() {
let hive = MongodbPubSub::new(
|ids, notification| {
super::events::posthandle_hook(&notification);
|ids, notification: ClientboundNotification| {
let notif = notification.clone();
async_std::task::spawn(async move {
super::events::posthandle_hook(&notif).await;
});
if let Ok(data) = to_string(&notification) {
debug!("Pushing out notification. {}", data);

View File

@@ -0,0 +1,25 @@
use crate::database::*;
use crate::util::result::{Error, Result};
use mongodb::bson::doc;
#[delete("/<target>/members/<member>")]
pub async fn req(user: User, target: Ref, member: String) -> Result<()> {
let target = target.fetch_server().await?;
let perm = permissions::PermissionCalculator::new(&user)
.with_server(&target)
.for_server()
.await?;
if !perm.get_manage_members() {
return Err(Error::MissingPermission)
}
let member = Ref::from(member)?.fetch_member(&target.id).await?;
if member.id.user == user.id {
return Err(Error::InvalidOperation)
}
target.remove_member(&member.id.user).await
}

View File

@@ -8,6 +8,7 @@ mod server_edit;
mod channel_create;
mod member_fetch_all;
mod member_remove;
mod member_fetch;
mod member_edit;
@@ -21,6 +22,7 @@ pub fn routes() -> Vec<Route> {
server_edit::req,
channel_create::req,
member_fetch_all::req,
member_remove::req,
member_fetch::req,
member_edit::req,
invites_fetch::req