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: i32,
67 github_email: Option<&str>,
68 github_user_created_at: DateTimeUtc,
69 initial_channel_id: Option<ChannelId>,
70 ) -> Result<()> {
71 self.transaction(|tx| async move {
72 let user = self
73 .get_or_create_user_by_github_account_tx(
74 github_login,
75 github_user_id,
76 github_email,
77 github_user_created_at.naive_utc(),
78 initial_channel_id,
79 &tx,
80 )
81 .await?;
82
83 contributor::Entity::insert(contributor::ActiveModel {
84 user_id: ActiveValue::Set(user.id),
85 signed_at: ActiveValue::NotSet,
86 })
87 .on_conflict(
88 OnConflict::column(contributor::Column::UserId)
89 .do_nothing()
90 .to_owned(),
91 )
92 .exec_without_returning(&*tx)
93 .await?;
94 Ok(())
95 })
96 .await
97 }
98}