feat: rewrite requests to include events

This commit is contained in:
Paul Makles
2022-02-19 19:49:10 +00:00
parent 061af1f2c3
commit 489c2bdd87
25 changed files with 159 additions and 240 deletions

View File

@@ -12,7 +12,8 @@ pub async fn req(db: &Db, user: User, target: Ref, message: Ref) -> Result<Empty
return Err(Error::NotFound); return Err(Error::NotFound);
} }
db.acknowledge_message(channel.id(), &user.id, &message.id) channel
.ack(db, &user.id, &message.id)
.await .await
.map(|_| EmptyResponse) .map(|_| EmptyResponse)
} }

View File

@@ -12,63 +12,26 @@ pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
return Err(Error::NotFound); return Err(Error::NotFound);
} }
match channel { match &channel {
Channel::SavedMessages { .. } => Err(Error::NoEffect), Channel::SavedMessages { .. } => Err(Error::NoEffect),
Channel::DirectMessage { id, .. } => { Channel::DirectMessage { id, .. } => db
db.update_channel( .update_channel(
&id, id,
&PartialChannel { &PartialChannel {
active: Some(false), active: Some(false),
..Default::default() ..Default::default()
}, },
vec![], vec![],
) )
.await?; .await
.map(|_| EmptyResponse),
Ok(EmptyResponse) Channel::Group { .. } => channel
} .remove_user_from_group(db, &user.id)
Channel::Group { .await
id, .map(|_| EmptyResponse),
owner, Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => {
recipients,
..
} => {
if user.id == owner {
if let Some(new_owner) = recipients.iter().find(|x| *x != &user.id) {
db.update_channel(
&id,
&PartialChannel {
owner: Some(new_owner.into()),
..Default::default()
},
vec![],
)
.await?;
} else {
db.delete_channel(&id).await?;
return Ok(EmptyResponse);
}
}
db.remove_user_from_group(&id, &user.id).await?;
/*ClientboundNotification::ChannelGroupLeave {
id: id.clone(),
user: user.id.clone(),
}
.publish(id.clone());
Content::SystemMessage(SystemMessage::UserLeft { id: user.id })
.send_as_system(&target)
.await
.ok();*/
Ok(EmptyResponse)
}
Channel::TextChannel { id, .. } | Channel::VoiceChannel { id, .. } => {
if perm.get_manage_channel() { if perm.get_manage_channel() {
db.delete_channel(&id).await?; channel.delete(db).await.map(|_| EmptyResponse)
Ok(EmptyResponse)
} else { } else {
Err(Error::MissingPermission { Err(Error::MissingPermission {
permission: ChannelPermission::ManageChannel as i32, permission: ChannelPermission::ManageChannel as i32,

View File

@@ -124,7 +124,8 @@ pub async fn req(
partial.nsfw = Some(new_nsfw); partial.nsfw = Some(new_nsfw);
} }
db.update_channel(id, &partial, data.remove.unwrap_or_default()) channel
.update(db, partial, data.remove.unwrap_or_default())
.await?; .await?;
} }
_ => return Err(Error::InvalidOperation), _ => return Err(Error::InvalidOperation),

View File

@@ -17,11 +17,13 @@ pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyR
}); });
} }
match channel { match &channel {
Channel::Group { id, .. } => { Channel::Group { .. } => {
let user = member.as_user(db).await?; let member = member.as_user(db).await?;
db.add_user_to_group(&id, &user.id).await?; channel
Ok(EmptyResponse) .add_user_to_group(db, &member.id, &user.id)
.await
.map(|_| EmptyResponse)
} }
_ => Err(Error::InvalidOperation), _ => Err(Error::InvalidOperation),
} }

View File

@@ -64,6 +64,6 @@ pub async fn req(db: &Db, user: User, info: Json<Data>) -> Result<Json<Channel>>
nsfw: info.nsfw.unwrap_or(false), nsfw: info.nsfw.unwrap_or(false),
}; };
db.insert_channel(&group).await?; group.create(db).await?;
Ok(Json(group)) Ok(Json(group))
} }

View File

@@ -7,14 +7,11 @@ use revolt_quark::{
pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyResponse> { pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyResponse> {
let channel = target.as_channel(db).await?; let channel = target.as_channel(db).await?;
match channel { match &channel {
Channel::Group { Channel::Group {
id, owner, recipients, ..
owner,
recipients,
..
} => { } => {
if user.id != owner { if &user.id != owner {
return Err(Error::MissingPermission { permission: 0 }); return Err(Error::MissingPermission { permission: 0 });
} }
@@ -27,8 +24,10 @@ pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyR
return Err(Error::NotInGroup); return Err(Error::NotInGroup);
} }
db.remove_user_from_group(&id, &member.id).await?; channel
Ok(EmptyResponse) .remove_user_from_group(db, &member.id)
.await
.map(|_| EmptyResponse)
} }
_ => Err(Error::InvalidOperation), _ => Err(Error::InvalidOperation),
} }

View File

@@ -21,5 +21,5 @@ pub async fn req(db: &Db, user: User, target: Ref, msg: Ref) -> Result<EmptyResp
}); });
} }
db.delete_message(&message.id).await.map(|_| EmptyResponse) message.delete(db).await.map(|_| EmptyResponse)
} }

View File

@@ -48,8 +48,7 @@ pub async fn req(
// 1. Handle content update // 1. Handle content update
if let Some(content) = edit.content { if let Some(content) = edit.content {
message.content = Content::Text(content); partial.content = Some(Content::Text(content));
partial.content = Some(message.content.clone());
} }
// 2. Clear any auto generated embeds // 2. Clear any auto generated embeds
@@ -71,9 +70,8 @@ pub async fn req(
} }
} }
message.embeds = Some(new_embeds);
partial.embeds = message.embeds.clone(); partial.embeds = message.embeds.clone();
db.update_message(&message.id, &partial).await?; message.update(db, partial).await?;
Ok(Json(message)) Ok(Json(message))
} }

View File

@@ -152,6 +152,6 @@ pub async fn message_send(
// 6. Set content // 6. Set content
message.content = Content::Text(data.content); message.content = Content::Text(data.content);
db.insert_message(&message).await?; message.create(db).await?;
Ok(Json(message)) Ok(Json(message))
} }

View File

@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use revolt_quark::{ use revolt_quark::{
models::{Channel, User}, models::{Channel, User},
perms, ChannelPermission, Db, EmptyResponse, Error, Ref, Result, perms, ChannelPermission, Db, Error, Ref, Result,
}; };
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@@ -18,8 +18,8 @@ pub async fn req(
target: Ref, target: Ref,
role: String, role: String,
data: Json<Data>, data: Json<Data>,
) -> Result<EmptyResponse> { ) -> Result<Json<Channel>> {
let channel = target.as_channel(db).await?; let mut channel = target.as_channel(db).await?;
if !perms(&user) if !perms(&user)
.channel(&channel) .channel(&channel)
.calc_channel(db) .calc_channel(db)
@@ -31,13 +31,9 @@ pub async fn req(
}); });
} }
match channel { channel
Channel::TextChannel { id, .. } | Channel::VoiceChannel { id, .. } => { .set_role_permission(db, &role, data.permissions)
db.set_channel_role_permission(&id, &role, data.permissions) .await?;
.await?;
}
_ => return Err(Error::InvalidOperation),
}
Ok(EmptyResponse) Ok(Json(channel))
} }

View File

@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use revolt_quark::{ use revolt_quark::{
models::{channel::PartialChannel, Channel, User}, models::{channel::PartialChannel, Channel, User},
perms, ChannelPermission, Db, EmptyResponse, Error, Ref, Result, perms, ChannelPermission, Db, Error, Ref, Result,
}; };
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@@ -12,8 +12,8 @@ pub struct Data {
} }
#[put("/<target>/permissions/default", data = "<data>", rank = 1)] #[put("/<target>/permissions/default", data = "<data>", rank = 1)]
pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<EmptyResponse> { pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<Json<Channel>> {
let channel = target.as_channel(db).await?; let mut channel = target.as_channel(db).await?;
if !perms(&user) if !perms(&user)
.channel(&channel) .channel(&channel)
.calc_channel(db) .calc_channel(db)
@@ -25,31 +25,33 @@ pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<E
}); });
} }
match channel { match &channel {
Channel::Group { id, .. } => { Channel::Group { .. } => {
db.update_channel( channel
&id, .update(
&PartialChannel { db,
permissions: Some(data.permissions as i32), PartialChannel {
..Default::default() permissions: Some(data.permissions as i32),
}, ..Default::default()
vec![], },
) vec![],
.await?; )
.await?;
} }
Channel::TextChannel { id, .. } | Channel::VoiceChannel { id, .. } => { Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => {
db.update_channel( channel
&id, .update(
&PartialChannel { db,
default_permissions: Some(data.permissions as i32), PartialChannel {
..Default::default() default_permissions: Some(data.permissions as i32),
}, ..Default::default()
vec![], },
) vec![],
.await?; )
.await?;
} }
_ => return Err(Error::InvalidOperation), _ => return Err(Error::InvalidOperation),
} }
Ok(EmptyResponse) Ok(Json(channel))
} }

View File

@@ -40,7 +40,7 @@ pub async fn req(db: &Db, user: User, target: Ref, info: Json<Data>) -> Result<J
info.validate() info.validate()
.map_err(|error| Error::FailedValidation { error })?; .map_err(|error| Error::FailedValidation { error })?;
let server = target.as_server(db).await?; let mut server = target.as_server(db).await?;
if !perms(&user) if !perms(&user)
.server(&server) .server(&server)
.calc_server(db) .calc_server(db)
@@ -53,7 +53,7 @@ pub async fn req(db: &Db, user: User, target: Ref, info: Json<Data>) -> Result<J
} }
let id = Ulid::new().to_string(); let id = Ulid::new().to_string();
let mut channels = server.channels; let mut channels = server.channels.clone();
channels.push(id.clone()); channels.push(id.clone());
let Data { let Data {
@@ -93,16 +93,17 @@ pub async fn req(db: &Db, user: User, target: Ref, info: Json<Data>) -> Result<J
}, },
}; };
db.insert_channel(&channel).await?; channel.create(db).await?;
db.update_server( server
&server.id, .update(
&PartialServer { db,
channels: Some(channels), PartialServer {
..Default::default() channels: Some(channels),
}, ..Default::default()
vec![], },
) vec![],
.await?; )
.await?;
Ok(Json(channel)) Ok(Json(channel))
} }

View File

@@ -63,28 +63,15 @@ pub async fn req(
db.mark_attachment_as_deleted(&avatar.id).await?; db.mark_attachment_as_deleted(&avatar.id).await?;
} }
} }
for field in fields {
member.remove(field);
}
} }
// 2. Apply new avatar // 2. Apply new avatar
if let Some(avatar) = avatar { if let Some(avatar) = avatar {
partial.avatar = Some(File::use_avatar(db, &avatar, &user.id).await?); partial.avatar = Some(File::use_avatar(db, &avatar, &user.id).await?);
member.avatar = partial.avatar.clone();
} }
// 3. Copy over other fields member
if let Some(nickname) = &partial.nickname { .update(db, partial, remove.unwrap_or_default())
member.nickname.replace(nickname.clone());
}
if let Some(roles) = &partial.roles {
member.roles.replace(roles.clone());
}
db.update_member(&member.id, &partial, remove.unwrap_or_else(Vec::new))
.await?; .await?;
Ok(Json(member)) Ok(Json(member))

View File

@@ -17,5 +17,5 @@ pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result<EmptyR
let member = member.as_member(db, &server.id).await?; let member = member.as_member(db, &server.id).await?;
// ! FIXME: calculate permission against member // ! FIXME: calculate permission against member
db.delete_member(&member.id).await.map(|_| EmptyResponse) member.delete(db).await.map(|_| EmptyResponse)
} }

View File

@@ -1,7 +1,10 @@
use rocket::serde::json::Json; use rocket::serde::json::Json;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result}; use revolt_quark::{
models::{Server, User},
perms, Db, Error, Ref, Result,
};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Values { pub struct Values {
@@ -21,8 +24,8 @@ pub async fn req(
target: Ref, target: Ref,
role_id: String, role_id: String,
data: Json<Data>, data: Json<Data>,
) -> Result<EmptyResponse> { ) -> Result<Json<Server>> {
let server = target.as_server(db).await?; let mut server = target.as_server(db).await?;
if !perms(&user) if !perms(&user)
.server(&server) .server(&server)
.calc_server(db) .calc_server(db)
@@ -34,18 +37,16 @@ pub async fn req(
// ! FIXME: calculate permission against role // ! FIXME: calculate permission against role
if !server.roles.contains_key(&role_id) { server
return Err(Error::NotFound); .set_role_permission(
} db,
&role_id,
&(
data.permissions.server as i32,
data.permissions.channel as i32,
),
)
.await?;
db.update_role_permission( Ok(Json(server))
&server.id,
&role_id,
&(
data.permissions.server as i32,
data.permissions.channel as i32,
),
)
.await
.map(|_| EmptyResponse)
} }

View File

@@ -2,8 +2,8 @@ use rocket::serde::json::Json;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use revolt_quark::{ use revolt_quark::{
models::{server::PartialServer, User}, models::{server::PartialServer, Server, User},
perms, Db, EmptyResponse, Error, Ref, Result, perms, Db, Error, Ref, Result,
}; };
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@@ -18,10 +18,10 @@ pub struct Data {
} }
#[put("/<target>/permissions/default", data = "<data>", rank = 1)] #[put("/<target>/permissions/default", data = "<data>", rank = 1)]
pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<EmptyResponse> { pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<Json<Server>> {
let data = data.into_inner(); let data = data.into_inner();
let server = target.as_server(db).await?; let mut server = target.as_server(db).await?;
if !perms(&user) if !perms(&user)
.server(&server) .server(&server)
.calc_server(db) .calc_server(db)
@@ -31,17 +31,19 @@ pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<E
return Err(Error::NotFound); return Err(Error::NotFound);
} }
db.update_server( server
&server.id, .update(
&PartialServer { db,
default_permissions: Some(( PartialServer {
data.permissions.server as i32, default_permissions: Some((
data.permissions.channel as i32, data.permissions.server as i32,
)), data.permissions.channel as i32,
..Default::default() )),
}, ..Default::default()
vec![], },
) vec![],
.await )
.map(|_| EmptyResponse) .await?;
Ok(Json(server))
} }

View File

@@ -5,7 +5,6 @@ use revolt_quark::{
use rocket::serde::json::{Json, Value}; use rocket::serde::json::{Json, Value};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ulid::Ulid;
use validator::Validate; use validator::Validate;
#[derive(Validate, Serialize, Deserialize)] #[derive(Validate, Serialize, Deserialize)]
@@ -30,20 +29,16 @@ pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<V
return Err(Error::NotFound); return Err(Error::NotFound);
} }
let role_id = Ulid::new().to_string(); let role = Role {
db.insert_role( name: data.name,
&server.id, permissions: (
&role_id, *DEFAULT_SERVER_PERMISSION as i32,
&Role { *DEFAULT_PERMISSION_CHANNEL_SERVER as i32,
name: data.name, ),
permissions: ( ..Default::default()
*DEFAULT_SERVER_PERMISSION as i32, };
*DEFAULT_PERMISSION_CHANNEL_SERVER as i32,
),
..Default::default()
},
)
.await?;
Ok(json!({ "id": role_id })) Ok(json!({
"id": role.create(db, &server.id).await?
}))
} }

View File

@@ -2,7 +2,7 @@ use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result};
#[delete("/<target>/roles/<role_id>")] #[delete("/<target>/roles/<role_id>")]
pub async fn req(db: &Db, user: User, target: Ref, role_id: String) -> Result<EmptyResponse> { pub async fn req(db: &Db, user: User, target: Ref, role_id: String) -> Result<EmptyResponse> {
let server = target.as_server(db).await?; let mut server = target.as_server(db).await?;
if !perms(&user) if !perms(&user)
.server(&server) .server(&server)
.calc_server(db) .calc_server(db)
@@ -14,7 +14,11 @@ pub async fn req(db: &Db, user: User, target: Ref, role_id: String) -> Result<Em
// ! FIXME: check perms against role // ! FIXME: check perms against role
db.delete_role(&server.id, &role_id) if let Some(role) = server.roles.remove(&role_id) {
.await role.delete(db, &server.id, &role_id)
.map(|_| EmptyResponse) .await
.map(|_| EmptyResponse)
} else {
Err(Error::NotFound)
}
} }

View File

@@ -61,21 +61,15 @@ pub async fn req(
..Default::default() ..Default::default()
}; };
if let Some(remove) = &remove { role.update(
for field in remove { db,
role.remove(field);
}
}
db.update_role(
&server.id, &server.id,
&role_id, &role_id,
&partial, partial,
remove.unwrap_or_else(Vec::new), remove.unwrap_or_default(),
) )
.await?; .await?;
role.apply_options(partial.clone());
Ok(Json(role)) Ok(Json(role))
} else { } else {
Err(Error::NotFound) Err(Error::NotFound)

View File

@@ -82,7 +82,9 @@ pub async fn req(db: &Db, user: User, info: Json<Data>) -> Result<Json<Server>>
}; };
db.insert_channel(&channel).await?; db.insert_channel(&channel).await?;
db.insert_server(&server).await?;
db.insert_member(&member).await?; server.create(db).await?;
member.create(db).await?;
Ok(Json(server)) Ok(Json(server))
} }

View File

@@ -6,10 +6,9 @@ pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
let member = db.fetch_member(&target.id, &user.id).await?; let member = db.fetch_member(&target.id, &user.id).await?;
if server.owner == user.id { if server.owner == user.id {
db.delete_server(&server.id).await?; server.delete(db).await
} else { } else {
db.delete_member(&member.id).await?; member.delete(db).await
} }
.map(|_| EmptyResponse)
Ok(EmptyResponse)
} }

View File

@@ -109,10 +109,6 @@ pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<J
db.mark_attachment_as_deleted(&icon.id).await?; db.mark_attachment_as_deleted(&icon.id).await?;
} }
} }
for field in fields {
server.remove(field);
}
} }
// 2. Apply new icon // 2. Apply new icon
@@ -127,19 +123,7 @@ pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<J
server.banner = partial.banner.clone(); server.banner = partial.banner.clone();
} }
// 4. Pass-through and validate changes // 4. Validate changes
if let Some(name) = &partial.name {
server.name = name.clone();
}
if let Some(description) = &partial.description {
server.description.replace(description.clone());
}
if let Some(categories) = &partial.categories {
server.categories.replace(categories.clone());
}
if let Some(system_messages) = &partial.system_messages { if let Some(system_messages) = &partial.system_messages {
let channels = system_messages.clone().into_channel_ids(); let channels = system_messages.clone().into_channel_ids();
if !db if !db
@@ -148,19 +132,11 @@ pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<J
{ {
return Err(Error::NotFound); return Err(Error::NotFound);
} }
server.system_messages.replace(system_messages.clone());
} }
if let Some(analytics) = &partial.analytics { server
server.analytics = *analytics; .update(db, partial, remove.unwrap_or_default())
}
if let Some(nsfw) = &partial.nsfw {
server.nsfw = *nsfw;
}
db.update_server(&server.id, &partial, remove.unwrap_or_else(Vec::new))
.await?; .await?;
Ok(Json(server)) Ok(Json(server))
} }

View File

@@ -1,4 +1,5 @@
use revolt_quark::models::User; use revolt_quark::models::User;
use revolt_quark::r#impl::generic::users::user_settings::UserSettingsImpl;
use revolt_quark::{Db, EmptyResponse, Result}; use revolt_quark::{Db, EmptyResponse, Result};
use chrono::prelude::*; use chrono::prelude::*;
@@ -32,7 +33,5 @@ pub async fn req(db: &Db, user: User, data: Json<Data>, options: Options) -> Res
settings.insert(key, (timestamp, data)); settings.insert(key, (timestamp, data));
} }
db.set_user_settings(&user.id, &settings) settings.set(db, &user.id).await.map(|_| EmptyResponse)
.await
.map(|_| EmptyResponse)
} }

View File

@@ -72,7 +72,6 @@ pub async fn req(db: &State<Database>, mut user: User, data: Json<Data>) -> Resu
// 2. Apply new avatar // 2. Apply new avatar
if let Some(avatar) = data.avatar { if let Some(avatar) = data.avatar {
partial.avatar = Some(File::use_avatar(db, &avatar, &user.id).await?); partial.avatar = Some(File::use_avatar(db, &avatar, &user.id).await?);
user.avatar = partial.avatar.clone();
} }
// 3. Apply new status // 3. Apply new status
@@ -87,7 +86,6 @@ pub async fn req(db: &State<Database>, mut user: User, data: Json<Data>) -> Resu
} }
partial.status = Some(new_status); partial.status = Some(new_status);
user.status = partial.status.clone();
} }
// 4. Apply new profile // 4. Apply new profile
@@ -102,10 +100,9 @@ pub async fn req(db: &State<Database>, mut user: User, data: Json<Data>) -> Resu
} }
partial.profile = Some(new_profile); partial.profile = Some(new_profile);
user.profile = partial.profile.clone();
} }
db.update_user(&user.id, &partial, data.remove.unwrap_or_default()) user.update(db, partial, data.remove.unwrap_or_default())
.await?; .await?;
Ok(Json(user.foreign())) Ok(Json(user.foreign()))

View File

@@ -27,7 +27,7 @@ pub async fn req(db: &State<Database>, user: User, target: Ref) -> Result<Json<C
last_message_id: None, last_message_id: None,
}; };
db.insert_channel(&new_channel).await?; new_channel.create(db).await?;
Ok(Json(new_channel)) Ok(Json(new_channel))
} else { } else {
Error::from_permission(UserPermission::SendMessage) Error::from_permission(UserPermission::SendMessage)