5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-07-04 00:55:46 +00:00
panel/app/controllers/api/v1/contact_controller.rb

110 lines
3.5 KiB
Ruby
Raw Normal View History

2020-03-23 20:46:19 +00:00
# frozen_string_literal: true
module Api
module V1
# API para formulario de contacto
class ContactController < BaseController
# Permitir conexiones desde varios sitios, estamos chequeando más
# adelante.
skip_forgery_protection
2020-03-23 20:46:19 +00:00
# Aplicar algunos chequeos básicos. Deberíamos registrar de
# alguna forma los errores pero tampoco queremos que nos usen
# recursos.
#
# TODO: Agregar los mismos chequeos que en PostsController
before_action :site_exists?, unless: :performed?
before_action :site_is_origin?, unless: :performed?
before_action :from_is_address?, unless: :performed?
before_action :gave_consent?, unless: :performed?
# Recibe un mensaje a través del formulario de contacto y lo envía
# a les usuaries del sitio.
#
# Tenemos que verificar que el sitio exista y que algunos campos
# estén llenos para detener spambots o DDOS. También nos vamos a
# estar apoyando en la limitación de peticiones en el servidor web.
def receive
# No hacer nada si no se pasaron los chequeos
return if performed?
# Si todo salió bien, enviar los correos y redirigir al sitio.
# El sitio nos dice a dónde tenemos que ir.
ContactJob.perform_async site_id: site.id,
**contact_params.to_h.symbolize_keys
redirect_to contact_params[:redirect] || site.url
end
private
# Comprueba que el sitio existe
#
# TODO: Responder con una zip bomb!
def site_exists?
render html: body(:site_exists), status: status unless site
end
# Comprueba que el mensaje vino fue enviado desde el sitio
def site_is_origin?
2020-05-04 18:51:20 +00:00
return if site.url.start_with? origin.to_s
2020-03-23 20:46:19 +00:00
render html: body(:site_is_origin), status: status
end
# Detecta si la dirección de contacto es válida. Además es
# opcional.
def from_is_address?
return unless contact_params[:from]
return if EmailAddress.valid? contact_params[:from]
render html: body(:from_is_address), status: status
end
# No aceptar nada si no dió su consentimiento
def gave_consent?
return if contact_params[:gdpr].present?
render html: body(:gave_consent), status: status
end
# Realiza la inversa de Site#hostname
2020-05-06 13:52:45 +00:00
#
# TODO: El sitio sutty.nl no aplica a ninguno de estos y le
# tuvimos que poner 'sutty.nl..sutty.nl' para pasar el test.
def site_id
@site_id ||= if params[:site_id].end_with? Site.domain
2020-05-06 13:52:45 +00:00
params[:site_id].sub(/\.#{Site.domain}\z/, '')
else
2020-05-06 13:52:45 +00:00
params[:site_id] + '.'
end
end
2020-03-23 20:46:19 +00:00
# Encuentra el sitio
def site
@site ||= Site.find_by(name: site_id)
2020-03-23 20:46:19 +00:00
end
# Parámetros limpios
def contact_params
@contact_params ||= params.permit(:gdpr, :name, :pronouns, :from,
:contact, :body, :redirect)
end
# Para poder testear, enviamos un mensaje en el cuerpo de la
# respuesta
#
# @param [Any] el mensaje
def body(message)
return message.to_s if Rails.env.test?
end
# No queremos informar nada a los spammers, pero en testeo
# queremos saber por qué. :no_content oculta el cuerpo.
def status
Rails.env.test? ? :unprocessable_entity : :no_content
end
end
end
end