feat: Working server/comment routes
This commit is contained in:
44
crates/delta/src/routes/admin/comments/comment_create.rs
Normal file
44
crates/delta/src/routes/admin/comments/comment_create.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use revolt_database::{AdminAuthorization, AdminComment, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Create a comment on an object or case. Requires Comments permission.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post("/comments", data = "<body>")]
|
||||
pub async fn admin_comment_create(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
body: Json<v0::AdminCommentCreate>,
|
||||
) -> Result<Json<v0::AdminComment>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::Comments) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "Comments".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let comment = AdminComment::new(
|
||||
&body.object_id,
|
||||
&user.id,
|
||||
&body.content,
|
||||
body.case_id.as_deref(),
|
||||
);
|
||||
db.admin_comment_insert(comment.clone()).await?;
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::CommentCreate,
|
||||
None,
|
||||
Some(&body.object_id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(comment.into()))
|
||||
}
|
||||
56
crates/delta/src/routes/admin/comments/comment_edit.rs
Normal file
56
crates/delta/src/routes/admin/comments/comment_edit.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use iso8601_timestamp::Timestamp;
|
||||
use revolt_database::{
|
||||
util::reference::Reference, AdminAuthorization, Database, PartialAdminComment,
|
||||
};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Create a comment on an object or case. Requires Comments permission.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[patch("/comments/<id>", data = "<body>")]
|
||||
pub async fn admin_comment_edit(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
body: Json<v0::AdminCommentEdit>,
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::Comments) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "Comments".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let existing = db.admin_comment_fetch(&id.id).await?;
|
||||
if existing.user_id != user.id {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "CannotEditOthersComment".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let partial = PartialAdminComment {
|
||||
content: Some(body.content.clone()),
|
||||
edited_at: Some(Timestamp::now_utc().format_short().to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
db.admin_comment_update(&id.id, &partial).await?;
|
||||
|
||||
let context = format!("comment id {:}, object id {:}", &id.id, &existing.object_id);
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::CommentEdit,
|
||||
None,
|
||||
Some(&existing.object_id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
43
crates/delta/src/routes/admin/comments/comment_fetch_case.rs
Normal file
43
crates/delta/src/routes/admin/comments/comment_fetch_case.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Fetch all comments related to a case. id should be the 7 character short code. Requires Comments permission.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[get("/comments/case/<id>")]
|
||||
pub async fn admin_comment_fetch_case(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
) -> Result<Json<Vec<v0::AdminComment>>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::Comments) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "Comments".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let comments: Vec<v0::AdminComment> = db
|
||||
.admin_comment_fetch_object_comments(&id.id)
|
||||
.await?
|
||||
.iter()
|
||||
.map(|f| f.clone().into())
|
||||
.collect();
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::CommentFetchForObject,
|
||||
Some(&id.id),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(comments))
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Fetch comments on an object. Requires Comments permission.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[get("/comments/object/<id>")]
|
||||
pub async fn admin_comment_fetch_object(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
) -> Result<Json<Vec<v0::AdminComment>>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::Comments) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "Comments".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let comments: Vec<v0::AdminComment> = db
|
||||
.admin_comment_fetch_object_comments(&id.id)
|
||||
.await?
|
||||
.iter()
|
||||
.map(|f| f.clone().into())
|
||||
.collect();
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::CommentFetchForObject,
|
||||
None,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(comments))
|
||||
}
|
||||
4
crates/delta/src/routes/admin/comments/mod.rs
Normal file
4
crates/delta/src/routes/admin/comments/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod comment_create;
|
||||
pub mod comment_edit;
|
||||
pub mod comment_fetch_case;
|
||||
pub mod comment_fetch_object;
|
||||
@@ -18,7 +18,9 @@ pub async fn admin_create_token(
|
||||
&auth.on_behalf_of,
|
||||
v0::AdminUserPermissionFlags::CreateTokens,
|
||||
) {
|
||||
return Err(create_error!(NotFound));
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "CreateTokens".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
if body.expiry > Timestamp::now_utc() + Duration::days(30) {
|
||||
|
||||
@@ -15,7 +15,9 @@ pub async fn admin_create_user(
|
||||
) -> Result<Json<v0::AdminUser>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageAdminUsers) {
|
||||
return Err(create_error!(NotFound));
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageAdminUsers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO: technically there's a privilege escalation here since anyone with the manageAdminUsers permission can assign whatever permissions they want.
|
||||
|
||||
@@ -17,7 +17,9 @@ pub async fn admin_edit_user(
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageAdminUsers) {
|
||||
return Err(create_error!(NotFound));
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageAdminUsers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
// TODO: technically there's a privilege escalation here since anyone with the manageAdminUsers permission can assign whatever permissions they want.
|
||||
|
||||
@@ -19,7 +19,9 @@ pub async fn admin_revoke_token(
|
||||
&auth.on_behalf_of,
|
||||
v0::AdminUserPermissionFlags::CreateTokens,
|
||||
) {
|
||||
return Err(create_error!(NotFound));
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "CreateTokens".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let token = token.as_admin_token(db).await?;
|
||||
|
||||
@@ -3,24 +3,38 @@ use rocket::Route;
|
||||
|
||||
mod accounts;
|
||||
mod cases;
|
||||
mod comments;
|
||||
mod meta;
|
||||
mod reports;
|
||||
mod roles;
|
||||
mod search;
|
||||
mod servers;
|
||||
mod users;
|
||||
|
||||
mod object_edit_note;
|
||||
mod object_get_note;
|
||||
mod util;
|
||||
|
||||
pub fn routes() -> (Vec<Route>, OpenApi) {
|
||||
openapi_get_routes_spec![
|
||||
object_edit_note::admin_object_edit_note,
|
||||
object_get_note::admin_object_get_note,
|
||||
meta::create_user::admin_create_user,
|
||||
meta::edit_user::admin_edit_user,
|
||||
meta::fetch_users::admin_fetch_users,
|
||||
meta::create_token::admin_create_token,
|
||||
meta::revoke_token::admin_revoke_token
|
||||
meta::revoke_token::admin_revoke_token,
|
||||
comments::comment_create::admin_comment_create,
|
||||
comments::comment_edit::admin_comment_edit,
|
||||
comments::comment_fetch_case::admin_comment_fetch_case,
|
||||
comments::comment_fetch_object::admin_comment_fetch_object,
|
||||
servers::fetch::server_get::admin_server_get,
|
||||
servers::fetch::server_get_participants::admin_server_get_participants,
|
||||
servers::fetch::server_get_all_members::admin_server_get_members,
|
||||
servers::actions::server_add_members::admin_server_add_member,
|
||||
servers::actions::server_ban_members::admin_server_ban_member,
|
||||
servers::actions::server_unban_members::admin_server_unban_member,
|
||||
servers::actions::server_change_owner::admin_server_change_owner,
|
||||
servers::actions::server_create_invite::admin_server_create_invite,
|
||||
servers::actions::server_delete_invites::admin_server_delete_invites,
|
||||
servers::actions::server_delete::admin_server_delete,
|
||||
servers::actions::server_edit::admin_server_edit,
|
||||
servers::actions::server_remove_members::admin_server_remove_members
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, AdminObjectNote, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{flatten_authorized_user, user_has_permission};
|
||||
|
||||
/// Edit an object note. Requires ObjectNotes permission.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post("/notes/<object>", data = "<body>")]
|
||||
pub async fn admin_object_edit_note(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
object: Reference,
|
||||
body: Json<v0::AdminObjectNoteEdit>,
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ObjectNotes) {
|
||||
return Err(create_error!(NotFound));
|
||||
}
|
||||
|
||||
// Unfortunately due to how our system works, we can't limit users to editing objects they have permissions for (eg users, servers, etc.).
|
||||
// Hence it being tied to its own permission
|
||||
db.admin_note_update(AdminObjectNote::new(&object.id, &user.id, &body.content))
|
||||
.await?;
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{flatten_authorized_user, user_has_permission};
|
||||
|
||||
/// Edit an object note. Requires ObjectNotes permission.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[get("/notes/<object>")]
|
||||
pub async fn admin_object_get_note(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
object: Reference,
|
||||
) -> Result<Json<v0::AdminObjectNote>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ObjectNotes) {
|
||||
return Err(create_error!(NotFound));
|
||||
}
|
||||
|
||||
// Unfortunately due to how our system works, we can't limit users to editing objects they have permissions for (eg users, servers, etc.).
|
||||
// Hence it being tied to its own permission
|
||||
Ok(Json(db.admin_note_fetch(&object.id).await?.into()))
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
pub mod server_add_members;
|
||||
pub mod server_ban_members;
|
||||
pub mod server_change_owner;
|
||||
pub mod server_create_invite;
|
||||
pub mod server_delete;
|
||||
pub mod server_delete_invites;
|
||||
pub mod server_edit;
|
||||
pub mod server_remove_members;
|
||||
pub mod server_unban_members;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database, Member};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// # Add server member
|
||||
///
|
||||
/// Add a user to a server, optionally disabling notifications
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post("/servers/<id>/members?<case>&<user_id>&<suppress_alerts>")]
|
||||
pub async fn admin_server_add_member(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
user_id: Reference,
|
||||
suppress_alerts: bool,
|
||||
) -> Result<Json<v0::MemberWithUserResponse>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let user = user_id.as_user(db).await?;
|
||||
let (member, _) = Member::create(db, &server, &user, None, !suppress_alerts).await?;
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerAddMember,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(v0::MemberWithUserResponse {
|
||||
user: user.into_self(false).await,
|
||||
member: member.into(),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database, ServerBan};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// # Ban a server member
|
||||
///
|
||||
/// Ban a member who is not the owner
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post(
|
||||
"/servers/<id>/ban?<case>&<user_id>&<suppress_alerts>",
|
||||
data = "<body>"
|
||||
)]
|
||||
pub async fn admin_server_ban_member(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
user_id: Reference,
|
||||
suppress_alerts: bool,
|
||||
body: Json<v0::DataBanCreate>,
|
||||
) -> Result<Json<v0::ServerBan>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let body = body.into_inner();
|
||||
body.validate().map_err(|error| {
|
||||
create_error!(FailedValidation {
|
||||
error: error.to_string()
|
||||
})
|
||||
})?;
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let target = user_id.as_user(db).await?;
|
||||
|
||||
if target.id == server.owner {
|
||||
return Err(create_error!(InvalidOperation));
|
||||
}
|
||||
|
||||
let resp = if let Ok(member) = user_id.as_member(db, &id.id).await {
|
||||
member
|
||||
.remove(
|
||||
db,
|
||||
&server,
|
||||
revolt_database::RemovalIntention::Ban,
|
||||
suppress_alerts,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(ServerBan::create(db, &server, &target.id, body.reason.clone()).await?)
|
||||
} else {
|
||||
Err(create_error!(NotAMember))
|
||||
}?;
|
||||
|
||||
let context = format!(
|
||||
"user id: {:}, server id: {:}, reason: {:}",
|
||||
&user_id.id,
|
||||
&id.id,
|
||||
body.reason
|
||||
.clone()
|
||||
.unwrap_or_else(|| "None Provided".to_string())
|
||||
);
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerBanMember,
|
||||
case,
|
||||
Some(&id.id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(resp.into()))
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database, PartialServer};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::State;
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// # Change Server Owner
|
||||
///
|
||||
/// Change the ownership of a server.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post("/servers/<id>/owner?<case>&<user_id>")]
|
||||
pub async fn admin_server_change_owner(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
user_id: Reference,
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let target = user_id.as_user(db).await?;
|
||||
|
||||
if target.id == server.owner {
|
||||
return Err(create_error!(InvalidOperation));
|
||||
}
|
||||
|
||||
let partial = PartialServer {
|
||||
owner: Some(target.id),
|
||||
..Default::default()
|
||||
};
|
||||
db.update_server(&server.id, &partial, vec![]).await?;
|
||||
|
||||
let context = format!("user id: {:}, server id: {:}", &user_id.id, &id.id);
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerChangeOwner,
|
||||
case,
|
||||
Some(&id.id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database, Invite};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// # Create Server Invite
|
||||
///
|
||||
/// Create an invite to a server. Optionally include a slug to create a vanity URL.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post("/servers/<id>/invites?<case>&<slug>&<channel_id>")]
|
||||
pub async fn admin_server_create_invite(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
channel_id: Reference,
|
||||
case: Option<&str>,
|
||||
slug: Option<&str>,
|
||||
) -> Result<Json<v0::Invite>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let channel = channel_id.as_channel(db).await?;
|
||||
let creator = db.fetch_user(&server.owner).await?;
|
||||
|
||||
let invite: Invite;
|
||||
|
||||
if let Some(slug) = slug {
|
||||
invite = Invite::Server {
|
||||
code: slug.to_string(),
|
||||
creator: creator.id.clone(),
|
||||
server: server.id.clone(),
|
||||
channel: channel.id().to_string(),
|
||||
};
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
db.insert_invite(&invite).await?;
|
||||
} else {
|
||||
invite = Invite::create_channel_invite(db, &creator, &channel).await?;
|
||||
}
|
||||
|
||||
let context = format!(
|
||||
"server id: {:}, invite slug: {:}, channel: {:}",
|
||||
&id.id,
|
||||
invite.code(),
|
||||
channel.id()
|
||||
);
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerCreateInvite,
|
||||
case,
|
||||
Some(&id.id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(invite.into()))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::State;
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Get a list of admin users. Any active user may use this endpoint.
|
||||
/// Typically the client should cache this data.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[delete("/servers/<id>?<case>")]
|
||||
pub async fn admin_server_delete(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
db.delete_server(&id.id).await?;
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerDelete,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::State;
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Delete Server Invite
|
||||
///
|
||||
/// Delete a server invite, or all of a server's invites.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[delete("/servers/<id>/invites?<case>&<slug>")]
|
||||
pub async fn admin_server_delete_invites(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
slug: Option<Reference>,
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(slug) = slug {
|
||||
let invite = slug.as_invite(db).await?;
|
||||
|
||||
db.delete_invite(&slug.id).await?;
|
||||
|
||||
let context = format!("server id: {:}, invite slug: {:}", &id.id, invite.code());
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerDeleteInvite,
|
||||
case,
|
||||
Some(&id.id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
let invites = db.fetch_invites_for_server(&id.id).await?;
|
||||
for invite in invites {
|
||||
db.delete_invite(invite.code()).await?;
|
||||
}
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerDeleteAllInvites,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
use validator::Validate;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// # Edit server
|
||||
///
|
||||
/// Edit any attributes of a server.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[patch("/servers/<id>?<case>", data = "<body>")]
|
||||
pub async fn admin_server_edit(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
body: Json<v0::DataEditServer>,
|
||||
) -> Result<Json<v0::Server>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let body = body.into_inner();
|
||||
body.validate().map_err(|error| {
|
||||
create_error!(FailedValidation {
|
||||
error: error.to_string()
|
||||
})
|
||||
})?;
|
||||
|
||||
let mut server = id.as_server(db).await?;
|
||||
let user = db.fetch_user(&server.owner).await?;
|
||||
crate::routes::servers::server_edit::edit_data(body, db, &mut server, &user).await?;
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerEdit,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(server.into()))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::State;
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// # Ban a server member
|
||||
///
|
||||
/// Ban a member who is not the owner
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post("/servers/<id>/remove?<case>&<user_id>&<suppress_alerts>")]
|
||||
pub async fn admin_server_remove_members(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
user_id: Vec<Reference>,
|
||||
suppress_alerts: bool,
|
||||
) -> Result<EmptyResponse> {
|
||||
let admin_user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(admin_user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
for uid in user_id {
|
||||
let target = uid.as_member(db, &id.id).await?;
|
||||
|
||||
if target.id.user == server.owner {
|
||||
return Err(create_error!(InvalidOperation));
|
||||
}
|
||||
|
||||
target
|
||||
.remove(
|
||||
db,
|
||||
&server,
|
||||
revolt_database::RemovalIntention::Kick,
|
||||
suppress_alerts,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let context = format!("user id: {:}, server id: {:}", &uid.id, &id.id);
|
||||
create_audit_action(
|
||||
db,
|
||||
&admin_user.id,
|
||||
v0::AdminAuditItemActions::ServerRemoveMember,
|
||||
case,
|
||||
Some(&id.id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
use rocket_empty::EmptyResponse;
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Get a list of admin users. Any active user may use this endpoint.
|
||||
/// Typically the client should cache this data.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[post(
|
||||
"/servers/<id>/unban?<case>&<user_id>&<suppress_alerts>",
|
||||
data = "<body>"
|
||||
)]
|
||||
pub async fn admin_server_unban_member(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
user_id: Reference,
|
||||
suppress_alerts: bool,
|
||||
body: Json<v0::DataBanCreate>,
|
||||
) -> Result<EmptyResponse> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let ban = db
|
||||
.fetch_ban(&id.id, &user_id.id)
|
||||
.await
|
||||
.map_err(|_| create_error!(NotFound))?;
|
||||
|
||||
db.delete_ban(&ban.id).await?;
|
||||
|
||||
let context = format!(
|
||||
"user id: {:}, server id: {:}, reason: {:}",
|
||||
&user_id.id,
|
||||
&id.id,
|
||||
body.reason
|
||||
.clone()
|
||||
.unwrap_or_else(|| "None Provided".to_string())
|
||||
);
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerUnbanMember,
|
||||
case,
|
||||
Some(&id.id),
|
||||
Some(&context),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod server_get;
|
||||
pub mod server_get_all_members;
|
||||
pub mod server_get_participants;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Get a list of admin users. Any active user may use this endpoint.
|
||||
/// Typically the client should cache this data.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[get("/servers/<id>?<case>")]
|
||||
pub async fn admin_server_get(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
) -> Result<Json<v0::AdminServerResponse>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let owner = db.fetch_user(&server.owner).await?.into_self(false).await;
|
||||
let comments: Vec<v0::AdminComment> = db
|
||||
.admin_comment_fetch_object_comments(&server.id)
|
||||
.await?
|
||||
.iter()
|
||||
.map(|f| f.clone().into())
|
||||
.collect();
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerFetch,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(v0::AdminServerResponse {
|
||||
server: server.into(),
|
||||
owner,
|
||||
comments,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
use futures::future::join_all;
|
||||
use iso8601_timestamp::Timestamp;
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Get a list of admin users. Any active user may use this endpoint.
|
||||
/// Typically the client should cache this data.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[get("/servers/<id>/members?<case>&<after>")]
|
||||
pub async fn admin_server_get_members(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
after: Option<usize>,
|
||||
) -> Result<Json<v0::AdminMemberWithUserAndOffsetResponse>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let members = db.fetch_server_members(&server.id, 100, after).await?;
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerFetchMembers,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let members_and_users = join_all(members.iter().map(|(u, m)| async move {
|
||||
let user: v0::User = u.clone().into_self(false).await;
|
||||
let member: v0::Member = m.clone().into();
|
||||
v0::MemberWithUserResponse { user, member }
|
||||
}))
|
||||
.await;
|
||||
|
||||
let mut resp = v0::AdminMemberWithUserAndOffsetResponse {
|
||||
after: None,
|
||||
users: vec![],
|
||||
};
|
||||
|
||||
if let Some(last) = members_and_users.last() {
|
||||
resp.after = Some(
|
||||
last.member
|
||||
.joined_at
|
||||
.duration_since(Timestamp::UNIX_EPOCH)
|
||||
.whole_milliseconds() as usize,
|
||||
);
|
||||
}
|
||||
|
||||
resp.users = members_and_users;
|
||||
|
||||
Ok(Json(resp))
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
use futures::future::join_all;
|
||||
use revolt_database::{util::reference::Reference, AdminAuthorization, Database};
|
||||
use revolt_models::v0::{self};
|
||||
use revolt_result::{create_error, Result};
|
||||
use rocket::{serde::json::Json, State};
|
||||
|
||||
use crate::routes::admin::util::{
|
||||
create_audit_action, flatten_authorized_user, user_has_permission,
|
||||
};
|
||||
|
||||
/// Get a list of admin users. Any active user may use this endpoint.
|
||||
/// Typically the client should cache this data.
|
||||
#[openapi(tag = "Admin")]
|
||||
#[get("/servers/<id>/participants?<case>")]
|
||||
pub async fn admin_server_get_participants(
|
||||
db: &State<Database>,
|
||||
auth: AdminAuthorization,
|
||||
id: Reference,
|
||||
case: Option<&str>,
|
||||
) -> Result<Json<Vec<(v0::User, Option<v0::Member>)>>> {
|
||||
let user = flatten_authorized_user(&auth);
|
||||
if !user_has_permission(user, v0::AdminUserPermissionFlags::ManageServers) {
|
||||
return Err(create_error!(MissingPermission {
|
||||
permission: "ManageServers".to_string()
|
||||
}));
|
||||
}
|
||||
|
||||
let server = id.as_server(db).await?;
|
||||
let participants = db.fetch_server_participants(&server.id).await?;
|
||||
|
||||
create_audit_action(
|
||||
db,
|
||||
&user.id,
|
||||
v0::AdminAuditItemActions::ServerFetchParticipants,
|
||||
case,
|
||||
Some(&id.id),
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
println!("{:?}", &participants);
|
||||
|
||||
let resp = join_all(participants.iter().map(|(u, m)| async move {
|
||||
let user: v0::User = u.clone().into_self(false).await;
|
||||
let member: Option<v0::Member> = m.clone().map(|mu| mu.into());
|
||||
(user, member)
|
||||
}))
|
||||
.await;
|
||||
|
||||
Ok(Json(resp))
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
mod actions;
|
||||
mod fetch;
|
||||
pub mod actions;
|
||||
pub mod fetch;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use revolt_database::{AdminAuthorization, AdminUser, AdminUserPermissionFlagsValue};
|
||||
use revolt_models::v0::AdminUserPermissionFlags;
|
||||
use revolt_database::{
|
||||
AdminAuditItem, AdminAuthorization, AdminComment, AdminUser, AdminUserPermissionFlagsValue,
|
||||
Database,
|
||||
};
|
||||
use revolt_models::v0::{AdminAuditItemActions, AdminUserPermissionFlags};
|
||||
use revolt_result::Result;
|
||||
|
||||
pub fn user_has_permission(user: &AdminUser, permission: AdminUserPermissionFlags) -> bool {
|
||||
let flags = AdminUserPermissionFlagsValue(user.permissions);
|
||||
@@ -7,9 +11,40 @@ pub fn user_has_permission(user: &AdminUser, permission: AdminUserPermissionFlag
|
||||
flags.has(permission)
|
||||
}
|
||||
|
||||
pub fn flatten_authorized_user<'a>(auth: &'a AdminAuthorization) -> &'a AdminUser {
|
||||
pub fn flatten_authorized_user(auth: &AdminAuthorization) -> &AdminUser {
|
||||
match auth {
|
||||
AdminAuthorization::AdminUser(admin_user) => &admin_user,
|
||||
AdminAuthorization::AdminUser(admin_user) => admin_user,
|
||||
AdminAuthorization::AdminMachine(admin_machine_token) => &admin_machine_token.on_behalf_of,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates audit logs, and if applicable, adds a comment to the referenced case.
|
||||
pub async fn create_audit_action(
|
||||
db: &Database,
|
||||
mod_id: &str,
|
||||
action: AdminAuditItemActions,
|
||||
short_case_id: Option<&str>,
|
||||
target_id: Option<&str>,
|
||||
context: Option<&str>,
|
||||
) -> Result<()> {
|
||||
let audit = AdminAuditItem::new(mod_id, action.clone(), short_case_id, target_id, context);
|
||||
db.admin_audit_insert(audit).await?;
|
||||
|
||||
if action.makes_comment() {
|
||||
if let Some(short_case_id) = short_case_id {
|
||||
if let Some(target_id) = target_id {
|
||||
let case = db.admin_case_fetch_from_shorthand(short_case_id).await?;
|
||||
db.admin_comment_insert(AdminComment::new_system_message(
|
||||
&case.id,
|
||||
mod_id,
|
||||
short_case_id,
|
||||
action,
|
||||
context,
|
||||
target_id,
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ pub async fn invite_bot(
|
||||
.await
|
||||
.throw_if_lacking_channel_permission(ChannelPermission::ManageServer)?;
|
||||
|
||||
Member::create(db, &server, &bot_user, None)
|
||||
Member::create(db, &server, &bot_user, None, true)
|
||||
.await
|
||||
.map(|_| EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ pub async fn join(
|
||||
match &invite {
|
||||
Invite::Server { server, .. } => {
|
||||
let server = db.fetch_server(server).await?;
|
||||
let (_, channels) = Member::create(db, &server, &user, None).await?;
|
||||
let (_, channels) = Member::create(db, &server, &user, None, true).await?;
|
||||
|
||||
Ok(Json(InviteJoinResponse::Server {
|
||||
channels: channels.into_iter().map(|c| c.into()).collect(),
|
||||
|
||||
@@ -21,7 +21,7 @@ mod roles_fetch;
|
||||
mod server_ack;
|
||||
mod server_create;
|
||||
mod server_delete;
|
||||
mod server_edit;
|
||||
pub mod server_edit;
|
||||
mod server_fetch;
|
||||
|
||||
pub fn routes() -> (Vec<Route>, OpenApi) {
|
||||
|
||||
@@ -30,7 +30,7 @@ pub async fn create_server(
|
||||
user.can_acquire_server(db).await?;
|
||||
|
||||
let (server, channels) = Server::create(db, data, &user, true).await?;
|
||||
let (_, channels) = Member::create(db, &server, &user, Some(channels)).await?;
|
||||
let (_, channels) = Member::create(db, &server, &user, Some(channels), true).await?;
|
||||
|
||||
Ok(Json(v0::CreateServerLegacyResponse {
|
||||
server: server.into(),
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||
|
||||
use revolt_database::{
|
||||
util::{permissions::DatabasePermissionQuery, reference::Reference},
|
||||
Database, File, PartialServer, User,
|
||||
Database, File, PartialServer, Server, User,
|
||||
};
|
||||
use revolt_models::v0;
|
||||
use revolt_permissions::{calculate_server_permissions, ChannelPermission};
|
||||
@@ -69,6 +69,16 @@ pub async fn edit(
|
||||
permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageChannel)?;
|
||||
}
|
||||
|
||||
edit_data(data, db, &mut server, &user).await?;
|
||||
Ok(Json(server.into()))
|
||||
}
|
||||
|
||||
pub async fn edit_data(
|
||||
data: v0::DataEditServer,
|
||||
db: &Database,
|
||||
server: &mut Server,
|
||||
user: &User,
|
||||
) -> Result<()> {
|
||||
let v0::DataEditServer {
|
||||
name,
|
||||
description,
|
||||
@@ -158,5 +168,5 @@ pub async fn edit(
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(server.into()))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ impl TestHarness {
|
||||
server: &Server,
|
||||
channels: Vec<Channel>,
|
||||
) -> (Channel, Member, Message) {
|
||||
let (member, channels) = Member::create(&self.db, server, user, Some(channels))
|
||||
let (member, channels) = Member::create(&self.db, server, user, Some(channels), true)
|
||||
.await
|
||||
.expect("Failed to create member");
|
||||
let channel = &channels[0];
|
||||
|
||||
Reference in New Issue
Block a user