mirror of
https://0xacab.org/sutty/sutty
synced 2025-03-14 17:18:20 +00:00
Merge branch 'issue-17722' into 'rails'
Draft: feat: prueba de antispam See merge request sutty/sutty!286
This commit is contained in:
commit
686c6d6b9b
4 changed files with 100 additions and 1 deletions
77
app/controllers/registrations_controller.rb
Normal file
77
app/controllers/registrations_controller.rb
Normal file
|
@ -0,0 +1,77 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Modificaciones locales al registro de usuaries
|
||||
#
|
||||
# @see {https://github.com/heartcombo/devise/wiki/How-To:-Use-Recaptcha-with-Devise}
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
class SpambotError < StandardError; end
|
||||
|
||||
PRIVATE_HEADERS = /(cookie|secret|token)/i
|
||||
|
||||
prepend_before_action :anti_spambot_traps, only: %i[create]
|
||||
prepend_after_action :lock_spambots, only: %i[create]
|
||||
|
||||
private
|
||||
|
||||
# Condiciones bajo las que consideramos que un registro viene de unx
|
||||
# spambot
|
||||
#
|
||||
# @return [Bool]
|
||||
def spambot?
|
||||
@spambot ||= params.dig(:usuarie, :name).present?
|
||||
end
|
||||
|
||||
# Bloquea las cuentas de spam dentro de un minuto, para hacerles creer
|
||||
# que la cuenta se creó correctamente.
|
||||
def lock_spambots
|
||||
return unless spambot?
|
||||
return unless current_usuarie
|
||||
|
||||
LockUsuarieJob.set(wait: 1.minute).perform_later(usuarie: current_usuarie)
|
||||
end
|
||||
|
||||
# Detecta e informa spambots muy simples
|
||||
#
|
||||
# @return [nil]
|
||||
def anti_spambot_traps
|
||||
raise SpambotError if spambot?
|
||||
rescue SpambotError => e
|
||||
ExceptionNotifier.notify_exception(e, data: { params: anonymized_params, headers: anonymized_headers })
|
||||
nil
|
||||
end
|
||||
|
||||
# Devuelve parámetros anonimizados para prevenir filtrar la contraseña
|
||||
# de falsos positivos.
|
||||
#
|
||||
# @return [Hash]
|
||||
def anonymized_params
|
||||
params.except(:authenticity_token).permit!.to_h.tap do |p|
|
||||
p['usuarie'].delete 'password'
|
||||
p['usuarie'].delete 'password_confirmation'
|
||||
end
|
||||
end
|
||||
|
||||
# Devuelve los encabezados de la petición sin información sensible de
|
||||
# Rails
|
||||
#
|
||||
# @return [Hash]
|
||||
def anonymized_headers
|
||||
request.headers.to_h.select do |_, v|
|
||||
v.is_a? String
|
||||
end.reject do |k, _|
|
||||
k =~ PRIVATE_HEADERS
|
||||
end
|
||||
end
|
||||
|
||||
# Si le usuarie es considerade spambot, no enviamos el correo de
|
||||
# confirmación al crear la cuenta.
|
||||
def sign_up_params
|
||||
if spambot?
|
||||
params[:usuarie][:confirmed_at] = Time.now.utc
|
||||
|
||||
devise_parameter_sanitizer.permit(:sign_up, keys: %i[confirmed_at])
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
19
app/jobs/lock_usuarie_job.rb
Normal file
19
app/jobs/lock_usuarie_job.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Bloquea el acceso a une usuarie
|
||||
class LockUsuarieJob < ApplicationJob
|
||||
# Cambiamos la contraseña, aplicamos un bloqueo y cerramos la sesión
|
||||
# para que no pueda volver a entrar hasta que siga las instrucciones
|
||||
# de desbloqueo.
|
||||
#
|
||||
# @param :usuarie [Usuarie]
|
||||
# @return [nil]
|
||||
def perform(usuarie:)
|
||||
password = SecureRandom.base36
|
||||
|
||||
usuarie.skip_password_change_notification!
|
||||
usuarie.update(password: password, password_confirmation: password, remember_created_at: nil, locked_at: Time.now.utc)
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
|
@ -12,6 +12,9 @@
|
|||
as: resource_name,
|
||||
url: registration_path(resource_name, params: { locale: params[:locale] })) do |f|
|
||||
|
||||
.d-none
|
||||
= f.text_field :name, autocomplete: 'off'
|
||||
|
||||
.form-group
|
||||
= f.label :email, class: 'sr-only'
|
||||
= f.email_field :email, autofocus: true, autocomplete: 'email',
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
SITE_ID_RE = %r{[^/]+}.freeze
|
||||
|
||||
Rails.application.routes.draw do
|
||||
devise_for :usuaries
|
||||
devise_for :usuaries, controllers: { registrations: 'registrations' }
|
||||
get '/.well-known/change-password', to: redirect('/usuaries/edit')
|
||||
|
||||
require 'que/web'
|
||||
|
|
Loading…
Reference in a new issue