1use rpc::{proto, ErrorCode};
2
3use super::*;
4
5impl Database {
6 pub async fn get_hosted_projects(
7 &self,
8 channel_ids: &Vec<ChannelId>,
9 roles: &HashMap<ChannelId, ChannelRole>,
10 tx: &DatabaseTransaction,
11 ) -> Result<Vec<proto::HostedProject>> {
12 Ok(hosted_project::Entity::find()
13 .filter(hosted_project::Column::ChannelId.is_in(channel_ids.iter().map(|id| id.0)))
14 .all(tx)
15 .await?
16 .into_iter()
17 .flat_map(|project| {
18 if project.deleted_at.is_some() {
19 return None;
20 }
21 match project.visibility {
22 ChannelVisibility::Public => {}
23 ChannelVisibility::Members => {
24 let is_visible = roles
25 .get(&project.channel_id)
26 .map(|role| role.can_see_all_descendants())
27 .unwrap_or(false);
28 if !is_visible {
29 return None;
30 }
31 }
32 };
33 Some(proto::HostedProject {
34 id: project.id.to_proto(),
35 channel_id: project.channel_id.to_proto(),
36 name: project.name.clone(),
37 visibility: project.visibility.into(),
38 })
39 })
40 .collect())
41 }
42
43 pub async fn get_hosted_project(
44 &self,
45 hosted_project_id: HostedProjectId,
46 user_id: UserId,
47 tx: &DatabaseTransaction,
48 ) -> Result<(hosted_project::Model, ChannelRole)> {
49 let project = hosted_project::Entity::find_by_id(hosted_project_id)
50 .one(tx)
51 .await?
52 .ok_or_else(|| anyhow!(ErrorCode::NoSuchProject))?;
53 let channel = channel::Entity::find_by_id(project.channel_id)
54 .one(tx)
55 .await?
56 .ok_or_else(|| anyhow!(ErrorCode::NoSuchChannel))?;
57
58 let role = match project.visibility {
59 ChannelVisibility::Public => {
60 self.check_user_is_channel_participant(&channel, user_id, tx)
61 .await?
62 }
63 ChannelVisibility::Members => {
64 self.check_user_is_channel_member(&channel, user_id, tx)
65 .await?
66 }
67 };
68
69 Ok((project, role))
70 }
71
72 pub async fn is_hosted_project(&self, project_id: ProjectId) -> Result<bool> {
73 self.transaction(|tx| async move {
74 Ok(project::Entity::find_by_id(project_id)
75 .one(&*tx)
76 .await?
77 .map(|project| project.hosted_project_id.is_some())
78 .ok_or_else(|| anyhow!(ErrorCode::NoSuchProject))?)
79 })
80 .await
81 }
82}