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