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}