5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-19 22:26:23 +00:00

feat: rutas

This commit is contained in:
f 2024-02-20 17:13:42 -03:00
parent 27c0ca655e
commit 8921de81ae
No known key found for this signature in database
7 changed files with 142 additions and 119 deletions

View file

@ -1,72 +0,0 @@
# frozen_string_literal: true
module Api
module V1
# Helpers para webhooks
module WebhookConcern
extend ActiveSupport::Concern
included do
# Responde con forbidden si falla la validación del token
rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer
private
# Valida el token que envía la plataforma en el webhook
#
# @return [String]
def token
@token ||=
begin
header = request.headers
token = header['X-Social-Inbox'].presence
token ||= header['X-Gitlab-Token'].presence
token ||= token_from_signature(header['X-Gitea-Signature'].presence)
token ||= token_from_signature(header['X-Hub-Signature-256'].presence, 'sha256=')
token
ensure
raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if token.blank?
end
end
# Valida token a partir de firma
#
# @param signature [String,nil]
# @param prepend [String]
# @return [String, nil]
def token_from_signature(signature, prepend = '')
return if signature.nil?
payload = request.raw_post
site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token|
new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload)
ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s)
end
end
# Encuentra el sitio a partir de la URL
#
# @return [Site]
def site
@site ||= Site.find_by_name!(params[:site_id])
end
# Encuentra le usuarie
#
# @return [Site]
def usuarie
@usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie
end
# Respuesta de error a plataformas
def platforms_answer(exception)
ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h })
head :forbidden
end
end
end
end
end

View file

@ -1,22 +0,0 @@
# frozen_string_literal: true
module Api
module V1
# Recibe webhooks de la Social Inbox
class SocialInboxController < BaseController
include WebhookConcern
def moderationqueued
head :accepted
end
def onapproved
head :accepted
end
def onrejected
head :accepted
end
end
end
end

View file

@ -0,0 +1,76 @@
# frozen_string_literal: true
module Api
module V1
module Webhooks
module Concerns
# Helpers para webhooks
module WebhookConcern
extend ActiveSupport::Concern
included do
# Responde con forbidden si falla la validación del token
rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer
private
# Valida el token que envía la plataforma en el webhook
#
# @return [String]
def token
@token ||=
begin
header = request.headers
token = header['X-Social-Inbox'].presence
token ||= header['X-Gitlab-Token'].presence
token ||= token_from_signature(header['X-Gitea-Signature'].presence)
token ||= token_from_signature(header['X-Hub-Signature-256'].presence, 'sha256=')
token
ensure
raise ActiveRecord::RecordNotFound, 'Proveedor no soportado' if token.blank?
end
end
# Valida token a partir de firma
#
# @param signature [String,nil]
# @param prepend [String]
# @return [String, nil]
def token_from_signature(signature, prepend = '')
return if signature.nil?
payload = request.raw_post
site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token|
new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload)
ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s)
end
end
# Encuentra el sitio a partir de la URL
#
# @return [Site]
def site
@site ||= Site.find_by_name!(params[:site_id])
end
# Encuentra le usuarie
#
# @return [Site]
def usuarie
@usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie
end
# Respuesta de error a plataformas
def platforms_answer(exception)
ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h })
head :forbidden
end
end
end
end
end
end
end

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
module Api
module V1
module Webhooks
# Recibe webhooks y lanza un PullJob
class PullController < BaseController
include WebhookConcern
# Trae los cambios a partir de un post de Webhooks:
# (Gitlab, Github, Gitea, etc)
#
# @return [nil]
def pull
message = I18n.with_locale(site.default_locale) do
I18n.t('webhooks.pull.message')
end
GitPullJob.perform_later(site, usuarie, message)
head :ok
end
end
end
end
end

View file

@ -0,0 +1,39 @@
# frozen_string_literal: true
module Api
module V1
module Webhooks
# Recibe webhooks de la Social Inbox
#
# @see {https://www.w3.org/TR/activitypub/}
class SocialInboxController < BaseController
include Api::V1::Webhooks::Concerns::WebhookConcern
# Cuando una actividad ingresa en la cola de moderación, la
# recibimos por acá
#
# Vamos a recibir Create, Update, Delete, Follow, Undo y obtener
# el objeto dentro de cada una para guardar un estado asociado
# al sitio.
#
# El objeto del estado puede ser un objeto o une actore,
# dependiendo de la actividad.
def moderationqueued
head :accepted
end
# Cuando aprobamos una actividad, recibimos la confirmación y
# cambiamos el estado
def onapproved
head :accepted
end
# Cuando rechazamos una actividad, recibimos la confirmación y
# cambiamos el estado
def onrejected
head :accepted
end
end
end
end
end

View file

@ -1,23 +0,0 @@
# frozen_string_literal: true
module Api
module V1
# Recibe webhooks y lanza un PullJob
class WebhooksController < BaseController
include WebhookConcern
# Trae los cambios a partir de un post de Webhooks:
# (Gitlab, Github, Gitea, etc)
#
# @return [nil]
def pull
message = I18n.with_locale(site.default_locale) do
I18n.t('webhooks.pull.message')
end
GitPullJob.perform_later(site, usuarie, message)
head :ok
end
end
end
end

View file

@ -19,9 +19,9 @@ Rails.application.routes.draw do
post :'contact/:form', to: 'contact#receive', as: :contact post :'contact/:form', to: 'contact#receive', as: :contact
namespace :webhooks do namespace :webhooks do
post :pull, to: 'webhooks#pull' post :pull, to: 'pull#pull'
namespace :social_inbox do scope :social_inbox do
post :moderationqueued, to: 'social_inbox#moderationqueued' post :moderationqueued, to: 'social_inbox#moderationqueued'
post :onapproved, to: 'social_inbox#onapproved' post :onapproved, to: 'social_inbox#onapproved'
post :onrejected, to: 'social_inbox#onrejected' post :onrejected, to: 'social_inbox#onrejected'