]> Untitled Git - lemmy.git/blob - crates/api/src/local_user/get_captcha.rs
92653cfc6c1c7a16ca2df8eb1b70b97861128641
[lemmy.git] / crates / api / src / local_user / get_captcha.rs
1 use crate::{captcha_as_wav_base64, Perform};
2 use actix_web::web::Data;
3 use captcha::{gen, Difficulty};
4 use lemmy_api_common::{
5   context::LemmyContext,
6   person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse},
7 };
8 use lemmy_db_schema::source::{
9   captcha_answer::{CaptchaAnswer, CaptchaAnswerForm},
10   local_site::LocalSite,
11 };
12 use lemmy_utils::error::LemmyError;
13
14 #[async_trait::async_trait(?Send)]
15 impl Perform for GetCaptcha {
16   type Response = GetCaptchaResponse;
17
18   #[tracing::instrument(skip(context))]
19   async fn perform(&self, context: &Data<LemmyContext>) -> Result<Self::Response, LemmyError> {
20     let local_site = LocalSite::read(context.pool()).await?;
21
22     if !local_site.captcha_enabled {
23       return Ok(GetCaptchaResponse { ok: None });
24     }
25
26     let captcha = gen(match local_site.captcha_difficulty.as_str() {
27       "easy" => Difficulty::Easy,
28       "hard" => Difficulty::Hard,
29       _ => Difficulty::Medium,
30     });
31
32     let answer = captcha.chars_as_string();
33
34     let png = captcha.as_base64().expect("failed to generate captcha");
35
36     let wav = captcha_as_wav_base64(&captcha)?;
37
38     let captcha_form: CaptchaAnswerForm = CaptchaAnswerForm { answer };
39     // Stores the captcha item in the db
40     let captcha = CaptchaAnswer::insert(context.pool(), &captcha_form).await?;
41
42     Ok(GetCaptchaResponse {
43       ok: Some(CaptchaResponse {
44         png,
45         wav,
46         uuid: captcha.uuid.to_string(),
47       }),
48     })
49   }
50 }