diff --git a/Cargo.lock b/Cargo.lock index df785345e5..516a21308f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1463,6 +1463,7 @@ dependencies = [ "base64 0.13.1", "call", "channel", + "chrono", "clap 3.2.25", "client", "clock", diff --git a/Cargo.toml b/Cargo.toml index 79d28821d4..eea2b4fb47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,6 +93,7 @@ resolver = "2" anyhow = { version = "1.0.57" } async-trait = { version = "0.1" } async-compression = { version = "0.4", features = ["gzip", "futures-io"] } +chrono = { version = "0.4", features = ["serde"] } ctor = "0.2.6" derive_more = { version = "0.99.17" } env_logger = { version = "0.9" } diff --git a/crates/assistant/Cargo.toml b/crates/assistant/Cargo.toml index 9588932c25..5380b91a9c 100644 --- a/crates/assistant/Cargo.toml +++ b/crates/assistant/Cargo.toml @@ -30,7 +30,7 @@ workspace = { path = "../workspace" } uuid.workspace = true log.workspace = true anyhow.workspace = true -chrono = { version = "0.4", features = ["serde"] } +chrono.workspace = true futures.workspace = true indoc.workspace = true isahc.workspace = true diff --git a/crates/collab/Cargo.toml b/crates/collab/Cargo.toml index e30622adc3..16ec9dbefd 100644 --- a/crates/collab/Cargo.toml +++ b/crates/collab/Cargo.toml @@ -27,6 +27,7 @@ axum = { version = "0.5", features = ["json", "headers", "ws"] } axum-extra = { version = "0.3", features = ["erased-json"] } base64 = "0.13" clap = { version = "3.1", features = ["derive"], optional = true } +chrono.workspace = true dashmap = "5.4" envy = "0.4.2" futures.workspace = true diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index 88c813ecc3..0eb82d29d2 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -14,6 +14,7 @@ use axum::{ Extension, Json, Router, }; use axum_extra::response::ErasedJson; +use chrono::SecondsFormat; use serde::{Deserialize, Serialize}; use std::sync::Arc; use tower::ServiceBuilder; @@ -26,6 +27,7 @@ pub fn routes(rpc_server: Arc, state: Arc) -> Router>) -> Result, +} + +async fn check_is_contributor( + Extension(app): Extension>, + Query(params): Query, +) -> Result> { + Ok(Json(CheckIsContributorResponse { + signed_at: app + .db + .get_contributor_sign_timestamp(params.github_user_id) + .await? + .map(|ts| ts.and_utc().to_rfc3339_opts(SecondsFormat::Millis, true)), + })) +} + async fn add_contributor( Json(params): Json, Extension(app): Extension>, diff --git a/crates/collab/src/db/queries/contributors.rs b/crates/collab/src/db/queries/contributors.rs index f0e352e2f2..3bf0d458b1 100644 --- a/crates/collab/src/db/queries/contributors.rs +++ b/crates/collab/src/db/queries/contributors.rs @@ -21,6 +21,28 @@ impl Database { .await } + /// Records that a given user has signed the CLA. + pub async fn get_contributor_sign_timestamp( + &self, + github_user_id: i32, + ) -> Result> { + self.transaction(|tx| async move { + let Some(user) = user::Entity::find() + .filter(user::Column::GithubUserId.eq(github_user_id)) + .one(&*tx) + .await? + else { + return Ok(None); + }; + let Some(contributor) = contributor::Entity::find_by_id(user.id).one(&*tx).await? + else { + return Ok(None); + }; + Ok(Some(contributor.signed_at)) + }) + .await + } + /// Records that a given user has signed the CLA. pub async fn add_contributor( &self,