From 5f01741943d77907683fa8ec97ee3e348836ace2 Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 1 Dec 2024 19:56:49 +0100 Subject: [PATCH] Validate the Captcha challenge for account signup --- app/controllers/application_controller.rb | 12 ++++++++++++ app/controllers/users/registrations_controller.rb | 2 ++ app/services/libre_captcha.rb | 6 ++++++ spec/requests/captcha_spec.rb | 4 ++-- spec/requests/schemas.rb | 11 +++++++++++ spec/requests/users/registrations_spec.rb | 3 ++- 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f163c3e..15a4b17 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -30,6 +30,18 @@ class ApplicationController < ActionController::Base private + def validate_captcha! + Rails.logger.info("Captcha params: #{captcha_params}") + + return if LibreCaptcha.new.valid?(id: captcha_params[:id], answer: captcha_params[:answer]) + + render json: { error: 'Incorrect CAPTCHA solution' }, status: :unprocessable_entity + end + + def captcha_params + params.expect(captcha: [:id, :answer]) + end + def default_url_options(options = {}) options.merge(path_params: { slug: ActsAsTenant.current_tenant&.slug }) end diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 24d8eca..4894d4b 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -4,6 +4,8 @@ class Users::RegistrationsController < Devise::RegistrationsController clear_respond_to respond_to :json + before_action :validate_captcha!, only: :create + def create wedding = Wedding.create(wedding_params) unless wedding.persisted? diff --git a/app/services/libre_captcha.rb b/app/services/libre_captcha.rb index d811437..8684e9f 100644 --- a/app/services/libre_captcha.rb +++ b/app/services/libre_captcha.rb @@ -11,4 +11,10 @@ class LibreCaptcha }.to_json ).then { |raw| JSON.parse(raw)['id'] } end + + def valid?(id:, answer:) + HTTParty.post("http://libre-captcha:8888/v2/answer", + body: { id:, answer: }.to_json + ).then { |raw| JSON.parse(raw)['result'] == 'True' } + end end \ No newline at end of file diff --git a/spec/requests/captcha_spec.rb b/spec/requests/captcha_spec.rb index 4cde63a..607a2d9 100644 --- a/spec/requests/captcha_spec.rb +++ b/spec/requests/captcha_spec.rb @@ -14,8 +14,8 @@ RSpec.describe 'captcha', type: :request do schema type: :object, required: %i[id], properties: { - id: { type: :string, format: :uuid } - media_url: { type: :string, format: :uri } + id: { type: :string, format: :uuid }, + media_url: { type: :string, format: :uri }, } xit end diff --git a/spec/requests/schemas.rb b/spec/requests/schemas.rb index 6602db8..e1f7b43 100644 --- a/spec/requests/schemas.rb +++ b/spec/requests/schemas.rb @@ -18,5 +18,16 @@ module Swagger example: :default, description: 'Wedding slug' } + + CAPTCHA = { + captcha: { + type: :object, + required: %i[id answer], + properties: { + id: { type: :string, format: :uuid }, + answer: { type: :string } + } + } + } end end \ No newline at end of file diff --git a/spec/requests/users/registrations_spec.rb b/spec/requests/users/registrations_spec.rb index ae0f86d..f29b387 100644 --- a/spec/requests/users/registrations_spec.rb +++ b/spec/requests/users/registrations_spec.rb @@ -30,7 +30,8 @@ RSpec.describe 'users/registrations', type: :request do properties: { date: { type: :string, format: :date}, } - } + }, + **Swagger::Schema::CAPTCHA } }