about summary refs log tree commit diff
path: root/corp/rih/backend/src
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-06-09T17·18+0300
committerclbot <clbot@tvl.fyi>2023-06-11T16·59+0000
commitba36a15b3166bcb09bdf2cd67acb6a3763a79e9c (patch)
tree657cb992c71072c03972999fc8107a022c8be5a1 /corp/rih/backend/src
parentb3ca1a78eb780e427a85dd1bbe1c649f998dee65 (diff)
feat(corp/rih): implement backend captcha validation r/6264
Change-Id: Ia80a6aeb8c20bdacbf93356be31592ca4ba7fcdc
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8741
Autosubmit: tazjin <tazjin@tvl.su>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Diffstat (limited to 'corp/rih/backend/src')
-rw-r--r--corp/rih/backend/src/main.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/corp/rih/backend/src/main.rs b/corp/rih/backend/src/main.rs
index c696858da5a4..208e0367c6a8 100644
--- a/corp/rih/backend/src/main.rs
+++ b/corp/rih/backend/src/main.rs
@@ -43,6 +43,40 @@ impl Record {
     }
 }
 
+fn validate_captcha(token: &str) -> Result<()> {
+    // TODO(tazjin): pass `ip` parameter
+    let url = "https://smartcaptcha.yandexcloud.net/validate";
+    let backend_key =
+        env::var("YANDEX_SMARTCAPTCHA_KEY").context("captcha verification key not provided")?;
+
+    #[derive(Deserialize)]
+    struct CaptchaResponse {
+        status: String,
+        message: String,
+    }
+
+    let response: CaptchaResponse = attohttpc::get(url)
+        .param("secret", backend_key)
+        .param("token", token)
+        .send()
+        .context("failed to send captcha verification request")?
+        .error_for_status()
+        .context("captcha verification request failed")?
+        .json()
+        .context("failed to deserialize captcha verification response")?;
+
+    if response.status != "ok" {
+        warn!(
+            "invalid captcha: {} ({})",
+            response.message, response.status
+        );
+    }
+
+    info!("captcha token was valid");
+
+    Ok(())
+}
+
 fn persist_record(ip: &SocketAddr, record: &Record) -> Result<()> {
     let bucket_name = "rih-backend-data";
     let credentials =
@@ -88,6 +122,8 @@ fn handle_submit(req: &Request) -> Result<Response> {
     let submitted: FrontendReq =
         rouille::input::json::json_input(req).context("failed to deserialise frontend request")?;
 
+    validate_captcha(&submitted.captcha_token)?;
+
     if !submitted.record.validate() {
         bail!("invalid record: {:?}", submitted.record);
     }