contributors.rs

 1use super::*;
 2
 3#[derive(Debug)]
 4pub enum ContributorSelector {
 5    GitHubUserId { github_user_id: i32 },
 6    GitHubLogin { github_login: String },
 7}
 8
 9impl Database {
10    /// Retrieves the GitHub logins of all users who have signed the CLA.
11    pub async fn get_contributors(&self) -> Result<Vec<String>> {
12        self.transaction(|tx| async move {
13            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
14            enum QueryGithubLogin {
15                GithubLogin,
16            }
17
18            Ok(contributor::Entity::find()
19                .inner_join(user::Entity)
20                .order_by_asc(contributor::Column::SignedAt)
21                .select_only()
22                .column(user::Column::GithubLogin)
23                .into_values::<_, QueryGithubLogin>()
24                .all(&*tx)
25                .await?)
26        })
27        .await
28    }
29
30    /// Records that a given user has signed the CLA.
31    pub async fn get_contributor_sign_timestamp(
32        &self,
33        selector: &ContributorSelector,
34    ) -> Result<Option<DateTime>> {
35        self.transaction(|tx| async move {
36            let condition = match selector {
37                ContributorSelector::GitHubUserId { github_user_id } => {
38                    user::Column::GithubUserId.eq(*github_user_id)
39                }
40                ContributorSelector::GitHubLogin { github_login } => {
41                    user::Column::GithubLogin.eq(github_login)
42                }
43            };
44
45            if let Some(user) = user::Entity::find().filter(condition).one(&*tx).await? {
46                if user.admin {
47                    return Ok(Some(user.created_at));
48                }
49
50                if let Some(contributor) =
51                    contributor::Entity::find_by_id(user.id).one(&*tx).await?
52                {
53                    return Ok(Some(contributor.signed_at));
54                }
55            }
56
57            Ok(None)
58        })
59        .await
60    }
61
62    /// Records that a given user has signed the CLA.
63    pub async fn add_contributor(
64        &self,
65        github_login: &str,
66        github_user_id: Option<i32>,
67        github_email: Option<&str>,
68        initial_channel_id: Option<ChannelId>,
69    ) -> Result<()> {
70        self.transaction(|tx| async move {
71            let user = self
72                .get_or_create_user_by_github_account_tx(
73                    github_login,
74                    github_user_id,
75                    github_email,
76                    initial_channel_id,
77                    &tx,
78                )
79                .await?;
80
81            contributor::Entity::insert(contributor::ActiveModel {
82                user_id: ActiveValue::Set(user.id),
83                signed_at: ActiveValue::NotSet,
84            })
85            .on_conflict(
86                OnConflict::column(contributor::Column::UserId)
87                    .do_nothing()
88                    .to_owned(),
89            )
90            .exec_without_returning(&*tx)
91            .await?;
92            Ok(())
93        })
94        .await
95    }
96}