mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 21:47:02 +00:00
feat(servers): role and permission routes
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use revolt_quark::{Error, Result};
|
||||
use revolt_quark::{
|
||||
models::{server::PartialServer, Channel, User},
|
||||
perms, Db, Error, Ref, Result, ServerPermission,
|
||||
};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
use rocket::serde::json::{Json, Value};
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ulid::Ulid;
|
||||
use validator::Validate;
|
||||
@@ -33,9 +35,74 @@ pub struct Data {
|
||||
}
|
||||
|
||||
#[post("/<target>/channels", data = "<info>")]
|
||||
pub async fn req(
|
||||
/*_idempotency: IdempotencyKey, user: User, target: Ref,*/ target: String,
|
||||
info: Json<Data>,
|
||||
) -> Result<Value> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref, info: Json<Data>) -> Result<Json<Channel>> {
|
||||
let info = info.into_inner();
|
||||
info.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_channels()
|
||||
{
|
||||
return Err(Error::MissingPermission {
|
||||
permission: ServerPermission::ManageChannels as i32,
|
||||
});
|
||||
}
|
||||
|
||||
let id = Ulid::new().to_string();
|
||||
let mut channels = server.channels;
|
||||
channels.push(id.clone());
|
||||
|
||||
let Data {
|
||||
name,
|
||||
description,
|
||||
nsfw,
|
||||
channel_type,
|
||||
} = info;
|
||||
let channel = match channel_type {
|
||||
ChannelType::Text => Channel::TextChannel {
|
||||
id,
|
||||
server: server.id.clone(),
|
||||
|
||||
name,
|
||||
description,
|
||||
|
||||
icon: None,
|
||||
last_message_id: None,
|
||||
|
||||
default_permissions: None,
|
||||
role_permissions: HashMap::new(),
|
||||
|
||||
nsfw: nsfw.unwrap_or(false),
|
||||
},
|
||||
ChannelType::Voice => Channel::VoiceChannel {
|
||||
id,
|
||||
server: server.id.clone(),
|
||||
|
||||
name,
|
||||
description,
|
||||
icon: None,
|
||||
|
||||
default_permissions: None,
|
||||
role_permissions: HashMap::new(),
|
||||
|
||||
nsfw: nsfw.unwrap_or(false),
|
||||
},
|
||||
};
|
||||
|
||||
db.insert_channel(&channel).await?;
|
||||
db.update_server(
|
||||
&server.id,
|
||||
&PartialServer {
|
||||
channels: Some(channels),
|
||||
..Default::default()
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Json(channel))
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use revolt_quark::{Error, Result};
|
||||
use revolt_quark::{
|
||||
models::{Invite, User},
|
||||
perms, Db, Error, Ref, Result, ServerPermission,
|
||||
};
|
||||
|
||||
use futures::StreamExt;
|
||||
use mongodb::bson::{doc, from_document};
|
||||
use rocket::serde::json::Value;
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
@@ -14,6 +15,18 @@ pub struct ServerInvite {
|
||||
}
|
||||
|
||||
#[get("/<target>/invites")]
|
||||
pub async fn req(/*user: UserRef, target: Ref*/ target: String) -> Result<Value> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref) -> Result<Json<Vec<Invite>>> {
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_server()
|
||||
{
|
||||
return Err(Error::MissingPermission {
|
||||
permission: ServerPermission::ManageServer as i32,
|
||||
});
|
||||
}
|
||||
|
||||
db.fetch_invites_for_server(&server.id).await.map(Json)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use mongodb::bson::doc;
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use revolt_quark::{EmptyResponse, Result};
|
||||
use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Values {
|
||||
@@ -17,9 +17,30 @@ pub struct Data {
|
||||
|
||||
#[put("/<target>/permissions/<role_id>", data = "<data>", rank = 2)]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
db: &Db,
|
||||
user: User,
|
||||
target: Ref,
|
||||
role_id: String,
|
||||
data: Json<Data>,
|
||||
) -> Result<EmptyResponse> {
|
||||
todo!()
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_roles()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
|
||||
db.update_role_permission(
|
||||
&server.id,
|
||||
&role_id,
|
||||
&(
|
||||
data.permissions.server as i32,
|
||||
data.permissions.channel as i32,
|
||||
),
|
||||
)
|
||||
.await
|
||||
.map(|_| EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ use mongodb::bson::doc;
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use revolt_quark::{EmptyResponse, Result};
|
||||
use revolt_quark::{
|
||||
models::{server::PartialServer, User},
|
||||
perms, Db, EmptyResponse, Error, Ref, Result,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Values {
|
||||
@@ -16,9 +19,30 @@ pub struct Data {
|
||||
}
|
||||
|
||||
#[put("/<target>/permissions/default", data = "<data>", rank = 1)]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
data: Json<Data>,
|
||||
) -> Result<EmptyResponse> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<EmptyResponse> {
|
||||
let data = data.into_inner();
|
||||
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_roles()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
|
||||
db.update_server(
|
||||
&server.id,
|
||||
&PartialServer {
|
||||
default_permissions: Some((
|
||||
data.permissions.server as i32,
|
||||
data.permissions.channel as i32,
|
||||
)),
|
||||
..Default::default()
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
.await
|
||||
.map(|_| EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use revolt_quark::{Error, Result};
|
||||
use revolt_quark::{
|
||||
models::{server::Role, User},
|
||||
perms, Db, Error, Ref, Result, DEFAULT_PERMISSION_CHANNEL_SERVER, DEFAULT_SERVER_PERMISSION,
|
||||
};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
use rocket::serde::json::{Json, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ulid::Ulid;
|
||||
@@ -13,9 +15,35 @@ pub struct Data {
|
||||
}
|
||||
|
||||
#[post("/<target>/roles", data = "<data>")]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
data: Json<Data>,
|
||||
) -> Result<Value> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref, data: Json<Data>) -> Result<Value> {
|
||||
let data = data.into_inner();
|
||||
data.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_roles()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
|
||||
let role_id = Ulid::new().to_string();
|
||||
db.insert_role(
|
||||
&server.id,
|
||||
&role_id,
|
||||
&Role {
|
||||
name: data.name,
|
||||
permissions: (
|
||||
*DEFAULT_SERVER_PERMISSION as i32,
|
||||
*DEFAULT_PERMISSION_CHANNEL_SERVER as i32,
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(json!({ "id": role_id }))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
use revolt_quark::{EmptyResponse, Result};
|
||||
use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result};
|
||||
|
||||
#[delete("/<target>/roles/<role_id>")]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
role_id: String,
|
||||
) -> Result<EmptyResponse> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref, role_id: String) -> Result<EmptyResponse> {
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_roles()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
|
||||
db.delete_role(&server.id, &role_id)
|
||||
.await
|
||||
.map(|_| EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
use revolt_quark::{EmptyResponse, Result};
|
||||
use revolt_quark::{
|
||||
models::{
|
||||
server::{FieldsRole, PartialRole, Role},
|
||||
User,
|
||||
},
|
||||
perms, Db, Error, Ref, Result,
|
||||
};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
@@ -13,15 +18,66 @@ pub struct Data {
|
||||
colour: Option<String>,
|
||||
hoist: Option<bool>,
|
||||
rank: Option<i64>,
|
||||
// #[validate(length(min = 1))]
|
||||
// remove: Option<Vec<FieldsRole>>,
|
||||
#[validate(length(min = 1))]
|
||||
remove: Option<Vec<FieldsRole>>,
|
||||
}
|
||||
|
||||
#[patch("/<target>/roles/<role_id>", data = "<data>")]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
db: &Db,
|
||||
user: User,
|
||||
target: Ref,
|
||||
role_id: String,
|
||||
data: Json<Data>,
|
||||
) -> Result<EmptyResponse> {
|
||||
todo!()
|
||||
) -> Result<Json<Role>> {
|
||||
let data = data.into_inner();
|
||||
data.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
let mut server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_manage_roles()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
|
||||
if let Some(mut role) = server.roles.remove(&role_id) {
|
||||
let Data {
|
||||
name,
|
||||
colour,
|
||||
hoist,
|
||||
rank,
|
||||
remove,
|
||||
} = data;
|
||||
|
||||
let partial = PartialRole {
|
||||
name,
|
||||
colour,
|
||||
hoist,
|
||||
rank,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(remove) = &remove {
|
||||
for field in remove {
|
||||
role.remove(field);
|
||||
}
|
||||
}
|
||||
|
||||
db.update_role(
|
||||
&server.id,
|
||||
&role_id,
|
||||
&partial,
|
||||
remove.unwrap_or_else(Vec::new),
|
||||
)
|
||||
.await?;
|
||||
|
||||
role.apply_options(partial.clone());
|
||||
Ok(Json(role))
|
||||
} else {
|
||||
Err(Error::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
use revolt_quark::{EmptyResponse, Result};
|
||||
use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result};
|
||||
|
||||
#[put("/<target>/ack")]
|
||||
pub async fn req(/*user: UserRef, target: Ref*/ target: String) -> Result<EmptyResponse> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_view()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
|
||||
db.acknowledge_channels(&user.id, &server.channels)
|
||||
.await
|
||||
.map(|_| EmptyResponse)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use revolt_quark::{
|
||||
models::{Server, User},
|
||||
models::{Channel, Server, User},
|
||||
Db, Error, Result, DEFAULT_PERMISSION_CHANNEL_SERVER, DEFAULT_SERVER_PERMISSION,
|
||||
};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ulid::Ulid;
|
||||
@@ -38,11 +39,32 @@ pub async fn req(db: &Db, user: User, info: Json<Data>) -> Result<Json<Server>>
|
||||
description,
|
||||
nsfw,
|
||||
} = info;
|
||||
|
||||
|
||||
let channel_id = Ulid::new().to_string();
|
||||
let server_id = Ulid::new().to_string();
|
||||
|
||||
let channel = Channel::TextChannel {
|
||||
id: channel_id.clone(),
|
||||
server: server_id.clone(),
|
||||
|
||||
name: "General".into(),
|
||||
description: None,
|
||||
|
||||
icon: None,
|
||||
last_message_id: None,
|
||||
|
||||
default_permissions: None,
|
||||
role_permissions: HashMap::new(),
|
||||
|
||||
nsfw: nsfw.unwrap_or(false),
|
||||
};
|
||||
|
||||
let server = Server {
|
||||
id: Ulid::new().to_string(),
|
||||
id: server_id,
|
||||
owner: user.id,
|
||||
name,
|
||||
description,
|
||||
channels: vec![channel_id],
|
||||
nsfw: nsfw.unwrap_or(false),
|
||||
default_permissions: (
|
||||
*DEFAULT_SERVER_PERMISSION as i32,
|
||||
@@ -51,6 +73,7 @@ pub async fn req(db: &Db, user: User, info: Json<Data>) -> Result<Json<Server>>
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
db.insert_channel(&channel).await?;
|
||||
db.insert_server(&server).await?;
|
||||
Ok(Json(server))
|
||||
}
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result};
|
||||
use revolt_quark::{models::User, Db, EmptyResponse, Ref, Result};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
|
||||
#[delete("/<target>")]
|
||||
pub async fn req(db: &Db, user: User, target: Ref) -> Result<EmptyResponse> {
|
||||
let server = target.as_server(db).await?;
|
||||
if !perms(&user)
|
||||
.server(&server)
|
||||
.calc_server(db)
|
||||
.await
|
||||
.get_view()
|
||||
{
|
||||
return Err(Error::NotFound);
|
||||
}
|
||||
let member = db.fetch_member(&target.id, &user.id).await?;
|
||||
|
||||
if server.owner == user.id {
|
||||
db.delete_server(&server.id).await?;
|
||||
} else {
|
||||
db.delete_member(&server.id, &user.id).await?;
|
||||
db.delete_member(&member.id).await?;
|
||||
}
|
||||
|
||||
Ok(EmptyResponse)
|
||||
|
||||
Reference in New Issue
Block a user