mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-19 16:46:21 +00:00
feat: rutas
This commit is contained in:
parent
27c0ca655e
commit
8921de81ae
7 changed files with 142 additions and 119 deletions
|
@ -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
|
|
@ -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
|
76
app/controllers/api/v1/webhooks/concerns/webhook_concern.rb
Normal file
76
app/controllers/api/v1/webhooks/concerns/webhook_concern.rb
Normal 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
|
25
app/controllers/api/v1/webhooks/pull_controller.rb
Normal file
25
app/controllers/api/v1/webhooks/pull_controller.rb
Normal 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
|
39
app/controllers/api/v1/webhooks/social_inbox_controller.rb
Normal file
39
app/controllers/api/v1/webhooks/social_inbox_controller.rb
Normal 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
|
|
@ -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
|
|
@ -19,9 +19,9 @@ Rails.application.routes.draw do
|
|||
post :'contact/:form', to: 'contact#receive', as: :contact
|
||||
|
||||
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 :onapproved, to: 'social_inbox#onapproved'
|
||||
post :onrejected, to: 'social_inbox#onrejected'
|
||||
|
|
Loading…
Reference in a new issue