init
This commit is contained in:
@@ -48,6 +48,9 @@ pub struct Model {
|
|||||||
on_delete = "Cascade"
|
on_delete = "Cascade"
|
||||||
)]
|
)]
|
||||||
pub user: HasOne<super::user::Entity>,
|
pub user: HasOne<super::user::Entity>,
|
||||||
|
|
||||||
|
#[sea_orm(has_many)]
|
||||||
|
pub computed_permissions: HasMany<super::computed_permission::Entity>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use crate::repositories::message::MessageRepository;
|
|||||||
use crate::repositories::role::RoleRepository;
|
use crate::repositories::role::RoleRepository;
|
||||||
use crate::repositories::server::ServerRepository;
|
use crate::repositories::server::ServerRepository;
|
||||||
use crate::repositories::server_item_order::ServerItemOrderRepository;
|
use crate::repositories::server_item_order::ServerItemOrderRepository;
|
||||||
|
use crate::repositories::server_tree::ServerTreeRepository;
|
||||||
use crate::repositories::user::UserRepository;
|
use crate::repositories::user::UserRepository;
|
||||||
use event_bus::EventBus;
|
|
||||||
use sea_orm::DatabaseConnection;
|
use sea_orm::DatabaseConnection;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ mod message;
|
|||||||
mod role;
|
mod role;
|
||||||
mod server;
|
mod server;
|
||||||
mod server_item_order;
|
mod server_item_order;
|
||||||
|
mod server_tree;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
mod user;
|
mod user;
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ pub struct Repositories {
|
|||||||
pub user: UserRepository,
|
pub user: UserRepository,
|
||||||
pub computed_permission: ComputedPermissionRepository,
|
pub computed_permission: ComputedPermissionRepository,
|
||||||
pub server_item_order: ServerItemOrderRepository,
|
pub server_item_order: ServerItemOrderRepository,
|
||||||
|
pub server_tree: ServerTreeRepository,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Repositories {
|
impl Repositories {
|
||||||
@@ -68,6 +70,9 @@ impl Repositories {
|
|||||||
server_item_order: ServerItemOrderRepository {
|
server_item_order: ServerItemOrderRepository {
|
||||||
context: context.clone(),
|
context: context.clone(),
|
||||||
},
|
},
|
||||||
|
server_tree: ServerTreeRepository {
|
||||||
|
context: context.clone(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
use crate::models::{category, channel, computed_permission, server_item_order};
|
||||||
|
use crate::permissions::ChannelPermission;
|
||||||
|
use crate::repositories::{AnyResult, RepositoryContext};
|
||||||
|
use sea_orm::{ColumnTrait, EntityTrait, JoinType, QueryFilter, QuerySelect};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ChannelWithPermissions {
|
||||||
|
pub channel: channel::Model,
|
||||||
|
pub permissions: ChannelPermission,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ServerTreeData {
|
||||||
|
pub orders: Vec<server_item_order::Model>,
|
||||||
|
pub categories: Vec<category::Model>,
|
||||||
|
pub channels: Vec<ChannelWithPermissions>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ServerTreeRepository {
|
||||||
|
pub context: Arc<RepositoryContext>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServerTreeRepository {
|
||||||
|
pub async fn get_for_user(&self, server_id: Uuid, user_id: Uuid) -> AnyResult<ServerTreeData> {
|
||||||
|
let (orders, categories, channel_rows) = tokio::try_join!(
|
||||||
|
async {
|
||||||
|
Ok::<_, anyhow::Error>(
|
||||||
|
server_item_order::Entity::find()
|
||||||
|
.filter(server_item_order::Column::ServerId.eq(server_id))
|
||||||
|
.all(&self.context.db)
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
async {
|
||||||
|
Ok::<_, anyhow::Error>(
|
||||||
|
category::Entity::find()
|
||||||
|
.filter(category::Column::ServerId.eq(server_id))
|
||||||
|
.all(&self.context.db)
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
self.find_channels_with_permissions(server_id, user_id),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let channels = channel_rows
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(channel, permission)| {
|
||||||
|
permission.map(|permission| ChannelWithPermissions {
|
||||||
|
channel,
|
||||||
|
permissions: ChannelPermission::from_bits_retain(permission.permissions as u64),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(ServerTreeData {
|
||||||
|
orders,
|
||||||
|
categories,
|
||||||
|
channels,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn find_channels_with_permissions(
|
||||||
|
&self,
|
||||||
|
server_id: Uuid,
|
||||||
|
user_id: Uuid,
|
||||||
|
) -> AnyResult<Vec<(channel::Model, Option<computed_permission::Model>)>> {
|
||||||
|
let rows = channel::Entity::find()
|
||||||
|
.join(
|
||||||
|
JoinType::InnerJoin,
|
||||||
|
channel::Relation::ComputedPermission.def(),
|
||||||
|
)
|
||||||
|
.filter(channel::Column::ServerId.eq(server_id))
|
||||||
|
.filter(computed_permission::Column::UserId.eq(user_id))
|
||||||
|
.filter(computed_permission::Column::ServerId.eq(server_id))
|
||||||
|
.filter(
|
||||||
|
computed_permission::Column::ScopeType
|
||||||
|
.eq(computed_permission::PermissionScopeType::Channel),
|
||||||
|
)
|
||||||
|
.select_also(computed_permission::Entity)
|
||||||
|
.all(&self.context.db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(rows)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user