hosted_projects.rs

 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}