mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 13:36:59 +00:00
feat: add id field to role (#470)
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
],
|
||||
"roles": {
|
||||
"__ID:5__": {
|
||||
"_id": "__ID:5__",
|
||||
"name": "Moderator",
|
||||
"permissions": {
|
||||
"a": 545270208,
|
||||
@@ -55,6 +56,7 @@
|
||||
"rank": 1
|
||||
},
|
||||
"__ID:6__": {
|
||||
"_id": "__ID:6__",
|
||||
"name": "Owner",
|
||||
"permissions": {
|
||||
"a": 0,
|
||||
|
||||
@@ -25,7 +25,7 @@ struct MigrationInfo {
|
||||
revision: i32,
|
||||
}
|
||||
|
||||
pub const LATEST_REVISION: i32 = 49; // MUST BE +1 to last migration
|
||||
pub const LATEST_REVISION: i32 = 50; // MUST BE +1 to last migration
|
||||
|
||||
pub async fn migrate_database(db: &MongoDb) {
|
||||
let migrations = db.col::<Document>("migrations");
|
||||
@@ -1246,7 +1246,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 {
|
||||
.expect("Failed to update voice channels");
|
||||
};
|
||||
|
||||
if revision <= 48 {
|
||||
if revision <= 48 {
|
||||
info!("Running migration [revision 48 / 22-10-2025]: Add Video + Listen to default permissions");
|
||||
|
||||
db.col::<Document>("servers")
|
||||
@@ -1264,6 +1264,48 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 {
|
||||
.expect("Failed to update default_permissions");
|
||||
};
|
||||
|
||||
if revision <= 49 {
|
||||
info!("Running migration [revision 49 / 12-12-2025]: Add _id key to roles");
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
struct Server {
|
||||
#[serde(rename = "_id")]
|
||||
pub id: String,
|
||||
#[serde(default = "HashMap::<String, Document>::new")]
|
||||
pub roles: HashMap<String, Document>,
|
||||
}
|
||||
|
||||
let mut servers = db
|
||||
.db()
|
||||
.collection::<Server>("servers")
|
||||
.find(doc! {
|
||||
"roles": {
|
||||
"$exists": true,
|
||||
"$ne": {}
|
||||
}
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.map(|res| res.expect("Failed to decode Server { id, roles }"));
|
||||
|
||||
while let Some(server) = servers.next().await {
|
||||
let mut doc = doc! {};
|
||||
|
||||
for id in server.roles.keys() {
|
||||
doc.insert(
|
||||
format!("roles.{id}._id"),
|
||||
id,
|
||||
);
|
||||
}
|
||||
|
||||
db.db()
|
||||
.collection::<Server>("servers")
|
||||
.update_one(doc! { "_id": &server.id }, doc! { "$set": doc })
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
};
|
||||
|
||||
// Reminder to update LATEST_REVISION when adding new migrations.
|
||||
LATEST_REVISION.max(revision)
|
||||
}
|
||||
|
||||
@@ -68,6 +68,9 @@ auto_derived_partial!(
|
||||
auto_derived_partial!(
|
||||
/// Role
|
||||
pub struct Role {
|
||||
/// Unique Id
|
||||
#[serde(rename = "_id")]
|
||||
pub id: String,
|
||||
/// Role name
|
||||
pub name: String,
|
||||
/// Permissions available to this role
|
||||
@@ -246,7 +249,6 @@ impl Server {
|
||||
role.update(
|
||||
db,
|
||||
&self.id,
|
||||
role_id,
|
||||
PartialRole {
|
||||
permissions: Some(permissions),
|
||||
..Default::default()
|
||||
@@ -297,6 +299,7 @@ impl Role {
|
||||
/// Into optional struct
|
||||
pub fn into_optional(self) -> PartialRole {
|
||||
PartialRole {
|
||||
id: Some(self.id),
|
||||
name: Some(self.name),
|
||||
permissions: Some(self.permissions),
|
||||
colour: self.colour,
|
||||
@@ -306,20 +309,29 @@ impl Role {
|
||||
}
|
||||
|
||||
/// Create a role
|
||||
pub async fn create(&self, db: &Database, server_id: &str) -> Result<String> {
|
||||
let role_id = Ulid::new().to_string();
|
||||
db.insert_role(server_id, &role_id, self).await?;
|
||||
pub async fn create(db: &Database, server: &Server, name: String) -> Result<Self> {
|
||||
let role = Role {
|
||||
id: Ulid::new().to_string(),
|
||||
name,
|
||||
// Rank of the new role should be below the lowest role
|
||||
rank: server.roles.len() as i64,
|
||||
colour: None,
|
||||
hoist: false,
|
||||
permissions: Default::default(),
|
||||
};
|
||||
|
||||
db.insert_role(&server.id, &role).await?;
|
||||
|
||||
EventV1::ServerRoleUpdate {
|
||||
id: server_id.to_string(),
|
||||
role_id: role_id.to_string(),
|
||||
data: self.clone().into_optional().into(),
|
||||
id: server.id.clone(),
|
||||
role_id: role.id.clone(),
|
||||
data: role.clone().into_optional().into(),
|
||||
clear: vec![],
|
||||
}
|
||||
.p(server_id.to_string())
|
||||
.p(server.id.clone())
|
||||
.await;
|
||||
|
||||
Ok(role_id)
|
||||
Ok(role)
|
||||
}
|
||||
|
||||
/// Update server data
|
||||
@@ -327,7 +339,6 @@ impl Role {
|
||||
&mut self,
|
||||
db: &Database,
|
||||
server_id: &str,
|
||||
role_id: &str,
|
||||
partial: PartialRole,
|
||||
remove: Vec<FieldsRole>,
|
||||
) -> Result<()> {
|
||||
@@ -337,14 +348,14 @@ impl Role {
|
||||
|
||||
self.apply_options(partial.clone());
|
||||
|
||||
db.update_role(server_id, role_id, &partial, remove.clone())
|
||||
db.update_role(server_id, &self.id, &partial, remove.clone())
|
||||
.await?;
|
||||
|
||||
EventV1::ServerRoleUpdate {
|
||||
id: server_id.to_string(),
|
||||
role_id: role_id.to_string(),
|
||||
role_id: self.id.clone(),
|
||||
data: partial.into(),
|
||||
clear: vec![],
|
||||
clear: remove.into_iter().map(Into::into).collect(),
|
||||
}
|
||||
.p(server_id.to_string())
|
||||
.await;
|
||||
@@ -360,15 +371,15 @@ impl Role {
|
||||
}
|
||||
|
||||
/// Delete a role
|
||||
pub async fn delete(self, db: &Database, server_id: &str, role_id: &str) -> Result<()> {
|
||||
pub async fn delete(self, db: &Database, server_id: &str) -> Result<()> {
|
||||
EventV1::ServerRoleDelete {
|
||||
id: server_id.to_string(),
|
||||
role_id: role_id.to_string(),
|
||||
role_id: self.id.clone(),
|
||||
}
|
||||
.p(server_id.to_string())
|
||||
.await;
|
||||
|
||||
db.delete_role(server_id, role_id).await
|
||||
db.delete_role(server_id, &self.id).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ pub trait AbstractServers: Sync + Send {
|
||||
async fn delete_server(&self, id: &str) -> Result<()>;
|
||||
|
||||
/// Insert a new role into server object
|
||||
async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()>;
|
||||
async fn insert_role(&self, server_id: &str, role: &Role) -> Result<()>;
|
||||
|
||||
/// Update an existing role on a server
|
||||
async fn update_role(
|
||||
|
||||
@@ -69,7 +69,7 @@ impl AbstractServers for MongoDb {
|
||||
}
|
||||
|
||||
/// Insert a new role into server object
|
||||
async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()> {
|
||||
async fn insert_role(&self, server_id: &str, role: &Role) -> Result<()> {
|
||||
self.col::<Document>(COL)
|
||||
.update_one(
|
||||
doc! {
|
||||
@@ -77,7 +77,7 @@ impl AbstractServers for MongoDb {
|
||||
},
|
||||
doc! {
|
||||
"$set": {
|
||||
"roles.".to_owned() + role_id: to_document(role)
|
||||
"roles.".to_owned() + &role.id: to_document(role)
|
||||
.map_err(|_| create_database_error!("to_document", "role"))?
|
||||
}
|
||||
},
|
||||
|
||||
@@ -72,10 +72,10 @@ impl AbstractServers for ReferenceDb {
|
||||
}
|
||||
|
||||
/// Insert a new role into server object
|
||||
async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()> {
|
||||
async fn insert_role(&self, server_id: &str, role: &Role) -> Result<()> {
|
||||
let mut servers = self.servers.lock().await;
|
||||
if let Some(server) = servers.get_mut(server_id) {
|
||||
server.roles.insert(role_id.to_string(), role.clone());
|
||||
server.roles.insert(role.id.clone(), role.clone());
|
||||
Ok(())
|
||||
} else {
|
||||
Err(create_error!(NotFound))
|
||||
|
||||
@@ -896,6 +896,7 @@ impl From<SystemMessageChannels> for crate::SystemMessageChannels {
|
||||
impl From<crate::Role> for Role {
|
||||
fn from(value: crate::Role) -> Self {
|
||||
Role {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
permissions: value.permissions,
|
||||
colour: value.colour,
|
||||
@@ -908,6 +909,7 @@ impl From<crate::Role> for Role {
|
||||
impl From<Role> for crate::Role {
|
||||
fn from(value: Role) -> crate::Role {
|
||||
crate::Role {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
permissions: value.permissions,
|
||||
colour: value.colour,
|
||||
@@ -920,6 +922,7 @@ impl From<Role> for crate::Role {
|
||||
impl From<crate::PartialRole> for PartialRole {
|
||||
fn from(value: crate::PartialRole) -> Self {
|
||||
PartialRole {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
permissions: value.permissions,
|
||||
colour: value.colour,
|
||||
@@ -932,6 +935,7 @@ impl From<crate::PartialRole> for PartialRole {
|
||||
impl From<PartialRole> for crate::PartialRole {
|
||||
fn from(value: PartialRole) -> crate::PartialRole {
|
||||
crate::PartialRole {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
permissions: value.permissions,
|
||||
colour: value.colour,
|
||||
|
||||
Reference in New Issue
Block a user