From 1ba570092e0043b7516cccbbb5c27451eb1f0e6a Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 1 Apr 2021 13:30:24 -0400 Subject: [PATCH] Adding more rust captcha features. Fixes #1248 --- crates/api/src/lib.rs | 60 +++++------------------------- crates/api/src/local_user.rs | 8 ++-- crates/api_common/src/person.rs | 4 +- docker/dev/Dockerfile | 3 -- docker/dev/volume_mount.dockerfile | 4 +- docker/prod/Dockerfile | 3 -- docker/prod/Dockerfile.arm | 4 +- 7 files changed, 18 insertions(+), 68 deletions(-) diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 5dc678be6..c9de749ef 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,9 +1,9 @@ use actix_web::{web, web::Data}; +use captcha::Captcha; use lemmy_api_common::{comment::*, community::*, person::*, post::*, site::*, websocket::*}; use lemmy_utils::{ConnectionId, LemmyError}; use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation}; use serde::Deserialize; -use std::{env, process::Command}; mod comment; mod comment_report; @@ -158,60 +158,23 @@ where serialize_websocket_message(&op, &res) } -pub(crate) fn captcha_espeak_wav_base64(captcha: &str) -> Result { - let mut built_text = String::new(); +/// Converts the captcha to a base64 encoded wav audio file +pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String { + let letters = captcha.as_wav(); - // Building proper speech text for espeak - for mut c in captcha.chars() { - let new_str = if c.is_alphabetic() { - if c.is_lowercase() { - c.make_ascii_uppercase(); - format!("lower case {} ... ", c) - } else { - c.make_ascii_uppercase(); - format!("capital {} ... ", c) - } - } else { - format!("{} ...", c) - }; + let mut concat_letters: Vec = Vec::new(); - built_text.push_str(&new_str); + for letter in letters { + let bytes = letter.unwrap_or_default(); + concat_letters.extend(bytes); } - espeak_wav_base64(&built_text) -} - -pub(crate) fn espeak_wav_base64(text: &str) -> Result { - // Make a temp file path - let uuid = uuid::Uuid::new_v4().to_string(); - let file_path = format!( - "{}/lemmy_espeak_{}.wav", - env::temp_dir().to_string_lossy(), - &uuid - ); - - // Write the wav file - Command::new("espeak") - .arg("-w") - .arg(&file_path) - .arg(text) - .status()?; - - // Read the wav file bytes - let bytes = std::fs::read(&file_path)?; - - // Delete the file - std::fs::remove_file(file_path)?; - // Convert to base64 - let base64 = base64::encode(bytes); - - Ok(base64) + base64::encode(concat_letters) } #[cfg(test)] mod tests { - use crate::captcha_espeak_wav_base64; use lemmy_api_common::check_validator_time; use lemmy_db_queries::{establish_unpooled_connection, source::local_user::LocalUser_, Crud}; use lemmy_db_schema::source::{ @@ -253,9 +216,4 @@ mod tests { let num_deleted = Person::delete(&conn, inserted_person.id).unwrap(); assert_eq!(1, num_deleted); } - - #[test] - fn test_espeak() { - assert!(captcha_espeak_wav_base64("WxRt2l").is_ok()) - } } diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index 656ddf971..831e38a17 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -1,4 +1,4 @@ -use crate::{captcha_espeak_wav_base64, Perform}; +use crate::{captcha_as_wav_base64, Perform}; use actix_web::web::Data; use anyhow::Context; use bcrypt::verify; @@ -135,13 +135,11 @@ impl Perform for GetCaptcha { let answer = captcha.chars_as_string(); - let png_byte_array = captcha.as_png().expect("failed to generate captcha"); - - let png = base64::encode(png_byte_array); + let png = captcha.as_base64().expect("failed to generate captcha"); let uuid = uuid::Uuid::new_v4().to_string(); - let wav = captcha_espeak_wav_base64(&answer).ok(); + let wav = captcha_as_wav_base64(&captcha); let captcha_item = CaptchaItem { answer, diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 7767da460..7b732412c 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -39,8 +39,8 @@ pub struct GetCaptchaResponse { #[derive(Serialize)] pub struct CaptchaResponse { - pub png: String, // A Base64 encoded png - pub wav: Option, // A Base64 encoded wav audio + pub png: String, // A Base64 encoded png + pub wav: String, // A Base64 encoded wav audio pub uuid: String, } diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 954c85c84..5d2acec7f 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -49,9 +49,6 @@ FROM alpine:3.12 as lemmy # Install libpq for postgres RUN apk add libpq -# Install Espeak for captchas -RUN apk add espeak - RUN addgroup -g 1000 lemmy RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy diff --git a/docker/dev/volume_mount.dockerfile b/docker/dev/volume_mount.dockerfile index 0cb036247..d848e0ea6 100644 --- a/docker/dev/volume_mount.dockerfile +++ b/docker/dev/volume_mount.dockerfile @@ -19,9 +19,9 @@ RUN --mount=type=cache,target=/app/target \ FROM ubuntu:20.10 -# Install libpq for postgres and espeak +# Install libpq for postgres RUN apt-get update -y -RUN apt-get install -y libpq-dev espeak +RUN apt-get install -y libpq-dev # Copy resources COPY config/defaults.hjson /config/defaults.hjson diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile index 2ad601aec..88a05fb26 100644 --- a/docker/prod/Dockerfile +++ b/docker/prod/Dockerfile @@ -49,9 +49,6 @@ FROM alpine:3.12 as lemmy # Install libpq for postgres RUN apk add libpq -# Install Espeak for captchas -RUN apk add espeak - RUN addgroup -g 1000 lemmy RUN adduser -D -s /bin/sh -u 1000 -G lemmy lemmy diff --git a/docker/prod/Dockerfile.arm b/docker/prod/Dockerfile.arm index 61d1f86c9..b3eacb4f9 100644 --- a/docker/prod/Dockerfile.arm +++ b/docker/prod/Dockerfile.arm @@ -22,9 +22,9 @@ RUN cp ./target/release/lemmy_server /app/lemmy_server # The Debian runner FROM debian:buster-slim as lemmy -# Install libpq for postgres and espeak for captchas +# Install libpq for postgres RUN apt-get update \ - && apt-get -y install --no-install-recommends espeak postgresql-client libc6 libssl1.1 \ + && apt-get -y install --no-install-recommends postgresql-client libc6 libssl1.1 \ && rm -rf /var/lib/apt/lists/* RUN addgroup --gid 1000 lemmy