mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-29 18:46:20 +00:00
Merge branch 'issue-13903' of https://0xacab.org/sutty/sutty into 17.3.alpine.panel.sutty.nl
This commit is contained in:
commit
c9337a0ad5
6 changed files with 94 additions and 20 deletions
|
@ -1,22 +1,75 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
# Recibe webhooks y lanza jobs
|
||||
class WebhooksController < BaseController
|
||||
# Trae los cambios a partir de un post de Webhooks:
|
||||
# (Gitlab, Github, Guitea, etc)
|
||||
def pull
|
||||
site = Site.find_by_name!(params[:site_id])
|
||||
usuarie = GitAuthor.new email: "webhook@#{Site.domain}", name: 'Webhook'
|
||||
message = I18n.with_locale(site.default_locale) do
|
||||
I18n.t('webhooks.pull.message')
|
||||
module V1
|
||||
# Recibe webhooks y lanza un PullJob
|
||||
class WebhooksController < BaseController
|
||||
# responde con forbidden si falla la validación del token
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer
|
||||
|
||||
# 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
|
||||
|
||||
private
|
||||
|
||||
# encuentra el sitio a partir de la url
|
||||
def site
|
||||
@site ||= Site.find_by_name!(params[:site_id])
|
||||
end
|
||||
|
||||
# valida el token que envía la plataforma del webhook
|
||||
#
|
||||
# @return [String]
|
||||
def token
|
||||
@token ||=
|
||||
begin
|
||||
# Gitlab
|
||||
if request.headers['X-Gitlab-Token']
|
||||
request.headers['X-Gitlab-Token']
|
||||
# Github
|
||||
elsif request.headers['X-HUB-SIGNATURE-256']
|
||||
token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256'])
|
||||
# Gitea
|
||||
elsif request.headers['HTTP_X_GITEA_SIGNATURE']
|
||||
token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE'])
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
GitPullJob.perform_later(site, usuarie, message)
|
||||
|
||||
head :ok
|
||||
# valida token a partir de firma de webhook
|
||||
#
|
||||
# @return [String, Boolean]
|
||||
def token_from_signature(signature)
|
||||
payload = request.body.read
|
||||
site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token|
|
||||
new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload)
|
||||
ActiveSupport::SecurityUtils.secure_compare(new_signature, signature)
|
||||
end.tap do |t|
|
||||
raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil?
|
||||
end
|
||||
end
|
||||
|
||||
# encuentra le usuarie
|
||||
def usuarie
|
||||
@usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie
|
||||
end
|
||||
|
||||
# respuesta de error a plataformas
|
||||
def platforms_answer(exception)
|
||||
head :forbidden
|
||||
ExceptionNotifier.notify_exception(exception, data: { params: params.to_h })
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Permite traer los cambios cada vez que se
|
||||
# hace un push al repositorio
|
||||
# Permite traer los cambios desde webhooks
|
||||
|
||||
class GitPullJob < ApplicationJob
|
||||
# @param :site [Site]
|
||||
# @param :usuarie [Usuarie]
|
||||
|
|
|
@ -14,6 +14,8 @@ class Rol < ApplicationRecord
|
|||
|
||||
validates_inclusion_of :rol, in: ROLES
|
||||
|
||||
before_save :add_token_if_missing!
|
||||
|
||||
def invitade?
|
||||
rol == INVITADE
|
||||
end
|
||||
|
@ -25,4 +27,11 @@ class Rol < ApplicationRecord
|
|||
def self.role?(rol)
|
||||
ROLES.include? rol
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Asegurarse que tenga un token
|
||||
def add_token_if_missing!
|
||||
self.token ||= SecureRandom.hex(64)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,9 +45,7 @@ class Site
|
|||
# @return [Integer]
|
||||
def fetch
|
||||
if origin.check_connection(:fetch, credentials: credentials)
|
||||
rugged.fetch(origin, credentials: credentials)[:received_objects].tap do |objects|
|
||||
git_sh("git", "lfs", "fetch", "origin", default_branch) if objects&.positive?
|
||||
end
|
||||
rugged.fetch(origin, credentials: credentials)[:received_objects]
|
||||
else
|
||||
0
|
||||
end
|
||||
|
@ -77,6 +75,8 @@ class Site
|
|||
# Forzamos el checkout para mover el HEAD al último commit y
|
||||
# escribir los cambios
|
||||
rugged.checkout 'HEAD', strategy: :force
|
||||
|
||||
git_sh("git", "lfs", "fetch", "origin", default_branch)
|
||||
# reemplaza los pointers por los archivos correspondientes
|
||||
git_sh("git", "lfs", "checkout")
|
||||
commit
|
||||
|
|
|
@ -479,7 +479,7 @@ es:
|
|||
message: 'Actualización del esqueleto'
|
||||
webhooks_controller:
|
||||
pull:
|
||||
message: 'Pull de webhooks'
|
||||
message: 'Traer los cambios a partir de un evento remoto'
|
||||
footer:
|
||||
powered_by: 'es desarrollada por'
|
||||
i18n:
|
||||
|
|
12
db/migrate/20230731195050_add_token_to_roles.rb
Normal file
12
db/migrate/20230731195050_add_token_to_roles.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
class AddTokenToRoles < ActiveRecord::Migration[6.1]
|
||||
def up
|
||||
add_column :roles, :token, :string
|
||||
Rol.find_each do |m|
|
||||
m.update_column( :token, SecureRandom.hex(64) )
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :roles, :token
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue