trustcaptcha_rust/
captcha_manager.rs

1use crate::errors::{
2    SecretKeyInvalidError, UnknownError, VerificationNotFinishedError, VerificationNotFoundError,
3    VerificationTokenInvalidError,
4};
5use crate::model::verification_result::VerificationResult;
6use crate::model::verification_token::VerificationToken;
7use base64::{engine::general_purpose, Engine as _};
8use reqwest::Client;
9use std::error::Error;
10
11pub struct CaptchaManager;
12
13impl CaptchaManager {
14    pub async fn get_verification_result(
15        secret_key: &str,
16        base64_verification_token: &str,
17    ) -> Result<VerificationResult, Box<dyn Error>> {
18        let verification_token =
19            match CaptchaManager::get_verification_token(base64_verification_token) {
20                Ok(token) => token,
21                Err(_) => return Err(Box::new(VerificationTokenInvalidError)),
22            };
23        CaptchaManager::fetch_verification_result(&verification_token, secret_key).await
24    }
25
26    fn get_verification_token(
27        base64_verification_token: &str,
28    ) -> Result<VerificationToken, Box<dyn Error>> {
29        let decoded_token = general_purpose::STANDARD.decode(base64_verification_token)?;
30        let decoded_str = String::from_utf8(decoded_token)?;
31        let verification_token: VerificationToken = serde_json::from_str(&decoded_str)?;
32        Ok(verification_token)
33    }
34
35    async fn fetch_verification_result(
36        verification_token: &VerificationToken,
37        secret_key: &str,
38    ) -> Result<VerificationResult, Box<dyn Error>> {
39        let url = format!(
40            "{}/verifications/{}/assessments",
41            verification_token.api_endpoint, verification_token.verification_id
42        );
43        let client = Client::new();
44        let response = client
45            .get(&url)
46            .header("tc-authorization", secret_key)
47            .header("tc-library-language", "rust")
48            .header("tc-library-version", "1.2")
49            .send()
50            .await?;
51
52        match response.status().as_u16() {
53            200 => {
54                let verification_result: VerificationResult = response.json().await?;
55                Ok(verification_result)
56            }
57            403 => Err(Box::new(SecretKeyInvalidError)),
58            404 => Err(Box::new(VerificationNotFoundError)),
59            423 => Err(Box::new(VerificationNotFinishedError)),
60            _ => Err(Box::new(UnknownError)),
61        }
62    }
63}