From 712514bc8c03b0ccd9f0289e3956aeddc8993c0b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 20 Apr 2023 18:11:43 -0300 Subject: [PATCH 01/86] feat: avisar que hay que publicar al cambiar la configuracion #13114 --- app/controllers/sites_controller.rb | 1 + app/views/layouts/_flash.haml | 2 +- config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index 63865e44..17287eb0 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -57,6 +57,7 @@ class SitesController < ApplicationController usuarie: current_usuarie) if service.update.valid? + flash[:notice] = I18n.t('sites.update.post') redirect_to site_posts_path(site, locale: site.default_locale) else render 'edit' diff --git a/app/views/layouts/_flash.haml b/app/views/layouts/_flash.haml index 7bd7ec0b..2d65ff78 100644 --- a/app/views/layouts/_flash.haml +++ b/app/views/layouts/_flash.haml @@ -1,4 +1,4 @@ - flash.each do |type, message| - unless type == 'js' = render 'bootstrap/alert' do - = message + = sanitize_markdown message, tags: %w[a strong em] diff --git a/config/locales/en.yml b/config/locales/en.yml index 3ddf681d..b37214e5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -402,6 +402,8 @@ en: title: 'Edit %{site}' submit: 'Save changes' btn: 'Configuration' + update: + post: "Your changes have been saved. **If you enabled a publication method, don't forget to publish changes.**" form: errors: title: There were errors and we couldn't save your changes :( diff --git a/config/locales/es.yml b/config/locales/es.yml index 01f1085c..aaff1a24 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -408,6 +408,8 @@ es: title: 'Editar %{site}' submit: 'Guardar cambios' btn: 'Configuración' + update: + post: "Tus cambios han sido guardados. **Si agregaste un método de publicación, no te olvides de publicar cambios.**" form: errors: title: Hubo errores y no pudimos guardar tus cambios :( From a9bce070e8753c28dc208e650366b30013f5d9fa Mon Sep 17 00:00:00 2001 From: f Date: Wed, 26 Apr 2023 15:25:09 -0300 Subject: [PATCH 02/86] fix: temporalmente deshabilitar el cambio de plantillas #13260 --- app/views/sites/_form.haml | 59 +++++++++++++++++++------------------- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 69997ffa..0dcccbe3 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -46,36 +46,37 @@ .invalid-feedback= site.errors.messages[:description].join(', ') %hr/ - .form-group#design_id - %h2= t('.design.title') - %p.lead= t('.help.design') - - if invalid? site, :design_id - = render 'bootstrap/alert' do - = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', - layouts: site.incompatible_layouts.to_sentence) - .row.row-cols-1.row-cols-md-2.designs - -# Demasiado complejo para un f.collection_radio_buttons - - Design.all.order(priority: :desc).each do |design| - .design.col.d-flex.flex-column - .custom-control.custom-radio - = f.radio_button :design_id, design.id, - checked: design.id == site.design_id, - disabled: design.disabled, - required: true, class: 'custom-control-input' - = f.label "design_id_#{design.id}", design.name, - class: 'custom-control-label' - .flex-fill - = sanitize_markdown design.description, - tags: %w[p a strong em] + - unless site.persisted? + .form-group#design_id + %h2= t('.design.title') + %p.lead= t('.help.design') + - if invalid? site, :design_id + = render 'bootstrap/alert' do + = t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.help', + layouts: site.incompatible_layouts.to_sentence) + .row.row-cols-1.row-cols-md-2.designs + -# Demasiado complejo para un f.collection_radio_buttons + - Design.all.order(priority: :desc).each do |design| + .design.col.d-flex.flex-column + .custom-control.custom-radio + = f.radio_button :design_id, design.id, + checked: design.id == site.design_id, + disabled: design.disabled, + required: true, class: 'custom-control-input' + = f.label "design_id_#{design.id}", design.name, + class: 'custom-control-label' + .flex-fill + = sanitize_markdown design.description, + tags: %w[p a strong em] - .btn-group{ role: 'group', 'aria-label': t('.design.actions') } - - if design.url - = link_to t('.design.url'), design.url, - target: '_blank', class: 'btn' - - if design.license - = link_to t('.design.license'), design.license, - target: '_blank', class: 'btn' - %hr/ + .btn-group{ role: 'group', 'aria-label': t('.design.actions') } + - if design.url + = link_to t('.design.url'), design.url, + target: '_blank', class: 'btn' + - if design.license + = link_to t('.design.license'), design.license, + target: '_blank', class: 'btn' + %hr/ .form-group.licenses#license_id %h2= t('.licencia.title') diff --git a/config/locales/en.yml b/config/locales/en.yml index 2628ffb1..1f46ffed 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -410,7 +410,7 @@ en: name: "The name of your site. It can only include numbers and letters." title: 'The title can be anything you want' description: 'You site description that appears in search engines. Between 50 and 160 characters.' - design: 'Select the design for your site. You can change it later. We add more designs from time to time!' + design: 'Select the design for your site. We add more designs from time to time!' licencia: 'Everything we publish has automatic copyright. This means nobody can use our works without explicit permission. By using licenses, we stablish conditions by which we want to share diff --git a/config/locales/es.yml b/config/locales/es.yml index 6ad61228..3630ea25 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -416,7 +416,7 @@ es: name: 'El nombre de tu sitio que formará parte de la dirección (**ejemplo**.sutty.nl). Solo puede contener letras minúsculas, números y guiones.' title: 'El título de tu sitio puede ser lo que quieras.' description: 'La descripción del sitio, que saldrá en buscadores. Entre 50 y 160 caracteres.' - design: 'Elegí el diseño que va a tener tu sitio aquí. Podés cambiarlo luego. De tanto en tanto vamos sumando diseños nuevos.' + design: 'Elegí el diseño que va a tener tu sitio aquí. De tanto en tanto vamos sumando diseños nuevos.' licencia: 'Todo lo que publicamos posee automáticamente derechos de autore. Esto significa que nadie puede hacer uso de nuestras obras sin permiso explícito. Con las licencias establecemos From 1839d48893ca278a71208d40c17f3ed4d009233a Mon Sep 17 00:00:00 2001 From: f Date: Sat, 29 Apr 2023 18:10:28 -0300 Subject: [PATCH 03/86] fix: permitir el atributo start #13321 --- app/models/metadata_template.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index 5de54be1..b324e71c 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -202,7 +202,7 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, def allowed_attributes @allowed_attributes ||= %w[style href src alt controls data-align data-multimedia data-multimedia-inner id - name].freeze + name start].freeze end def allowed_tags From 068bed5c0ad58be73949dd9b01304db4295f7002 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 May 2023 14:34:24 -0300 Subject: [PATCH 04/86] Revert "deshabilitar el paginado temporalmente" This reverts commit 9c4a0a86f3eeec8f578e3872096896a710e01632. --- app/controllers/posts_controller.rb | 4 ++-- app/views/posts/index.haml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 9720fe13..21a6dc06 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -23,7 +23,7 @@ class PostsController < ApplicationController return unless stale?([current_usuarie, site, filter_params]) # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale) + @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) # De este tipo @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] # Que estén dentro de la categoría @@ -154,7 +154,7 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout).to_hash.select do |_, v| + @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select do |_, v| v.present? end.transform_keys(&:to_sym) end diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index e8c3dea7..470e9641 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -85,6 +85,8 @@ %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') %div + = link_to_prev_page @posts, t('posts.prev'), class: 'btn' + = link_to_next_page @posts, t('posts.next'), class: 'btn' %tbody - dir = @site.data.dig(params[:locale], 'dir') - size = @posts.size From 3540886554455ac1627b190327d32117e04bf129 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 May 2023 14:36:42 -0300 Subject: [PATCH 05/86] feat: poder paginar solo algunos sitios #12714 --- app/controllers/posts_controller.rb | 3 ++- app/views/posts/index.haml | 7 ++++--- db/migrate/20230519143500_add_pagination_to_site.rb | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20230519143500_add_pagination_to_site.rb diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 21a6dc06..057c3068 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -23,7 +23,8 @@ class PostsController < ApplicationController return unless stale?([current_usuarie, site, filter_params]) # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) + @posts = site.indexed_posts.where(locale: locale) + @posts = @posts.page(filter_params.delete(:page)) if site.pagination # De este tipo @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] # Que estén dentro de la categoría diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 470e9641..ae53aa7a 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -84,9 +84,10 @@ %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') - %div - = link_to_prev_page @posts, t('posts.prev'), class: 'btn' - = link_to_next_page @posts, t('posts.next'), class: 'btn' + - if @site.pagination + %div + = link_to_prev_page @posts, t('posts.prev'), class: 'btn' + = link_to_next_page @posts, t('posts.next'), class: 'btn' %tbody - dir = @site.data.dig(params[:locale], 'dir') - size = @posts.size diff --git a/db/migrate/20230519143500_add_pagination_to_site.rb b/db/migrate/20230519143500_add_pagination_to_site.rb new file mode 100644 index 00000000..776fa318 --- /dev/null +++ b/db/migrate/20230519143500_add_pagination_to_site.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Agrega la opción de paginación a los sitios +class AddPaginationToSites < ActiveRecord::Migration[6.1] + def change + add_column :sites, :pagination, :boolean, default: false + end +end From d0f7843fbf90ef936afe955b046d8cab1ee6f7d8 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 19 May 2023 14:40:42 -0300 Subject: [PATCH 06/86] fixup! feat: poder paginar solo algunos sitios #12714 --- db/migrate/20230519143500_add_pagination_to_site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230519143500_add_pagination_to_site.rb b/db/migrate/20230519143500_add_pagination_to_site.rb index 776fa318..387dc588 100644 --- a/db/migrate/20230519143500_add_pagination_to_site.rb +++ b/db/migrate/20230519143500_add_pagination_to_site.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Agrega la opción de paginación a los sitios -class AddPaginationToSites < ActiveRecord::Migration[6.1] +class AddPaginationToSite < ActiveRecord::Migration[6.1] def change add_column :sites, :pagination, :boolean, default: false end From e35bddf915ea332c0a169556d581d41744b6f0ad Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 10:04:22 -0300 Subject: [PATCH 07/86] fix: no permitir que les usuaries elijan un idioma que no existe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit porque se les rompe el panel después --- app/models/usuarie.rb | 12 ++++++++++++ config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 2bc7a1b5..42f20c0b 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -10,6 +10,7 @@ class Usuarie < ApplicationRecord validates_uniqueness_of :email validates_with EmailAddress::ActiveRecordValidator, field: :email + validate :locale_available! before_create :lang_from_locale! before_update :remove_confirmation_invitation_inconsistencies! @@ -78,4 +79,15 @@ class Usuarie < ApplicationRecord self.invitation_accepted_at ||= Time.now.utc end end + + # Muestra un error si el idioma no está disponible al cambiar el + # idioma de la cuenta. + # + # @return [nil] + def locale_available! + return if I18n.locale_available? self.lang + + errors.add(:lang, I18n.t('activerecord.errors.models.usuarie.attributes.lang.not_available')) + nil + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..ab6a9305 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -194,6 +194,10 @@ en: layout_incompatible: error: "Design can't be changed because there are posts with incompatible layouts" help: "Your site has posts with layouts only compatible with the current design. If you change it, the site won't work as you expect. If you're trying out designs, you can delete posts in the following incompatible layouts:: %{layouts}." + usuarie: + attributes: + lang: + not_available: "This language is not yet available, would you help us by translating Sutty into it?" errors: argument_error: 'Argument `%{argument}` must be an instance of %{class}' unknown_locale: 'Unknown %{locale} locale' diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..e3c271da 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -194,6 +194,10 @@ es: layout_incompatible: error: 'No se puede cambiar la plantilla porque hay artículos con formatos incompatibles' help: 'En tu sitio hay artículos que solo son compatibles con el diseño actual, si cambias la plantilla el sitio no funcionará como esperas. Si estás probando plantillas, puedes eliminar los artículos en los formatos incompatibles: %{layouts}.' + usuarie: + attributes: + lang: + not_available: "Este idioma todavía no está disponible, ¿nos ayudas a agregarlo y mantenerlo?" errors: argument_error: 'El argumento `%{argument}` debe ser una instancia de %{class}' unknown_locale: 'El idioma %{locale} es desconocido' From 4e002e042bc5b0e5c129ab8cac3df03cf340fefb Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 May 2023 10:06:11 -0300 Subject: [PATCH 08/86] fix: no permitir idiomas que no existen en el cambio de idioma #13493 --- app/controllers/application_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ee153394..2746ab10 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -59,7 +59,11 @@ class ApplicationController < ActionController::Base # # @return [String,Symbol] def current_locale - session[:locale] = params[:change_locale_to] if params[:change_locale_to].present? + locale = params[:change_locale_to] + + if locale.present? && I18n.locale_available?(locale) + session[:locale] = params[:change_locale_to] + end session[:locale] || current_usuarie&.lang || I18n.locale end From 8d7d1c10b18cd4725f994c9f5900517947f3f9d3 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 12:04:44 -0300 Subject: [PATCH 09/86] fix: indexar posts luego de crear el sitio #13610 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit se producía una condición donde el sitio se quería indexar sin haber terminado de instalar las gemas y todo fallaba. no tenemos que usar más callbacks, solo servicios --- app/models/site/index.rb | 2 -- app/services/site_service.rb | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index e11095e3..c2c55ade 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -8,8 +8,6 @@ class Site extend ActiveSupport::Concern included do - # TODO: Debería ser un Job? - after_create :index_posts! has_many :indexed_posts, dependent: :destroy def index_posts! diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 2c29538c..367d3b08 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -33,6 +33,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do add_licencias && add_code_of_conduct && add_privacy_policy && + site.index_posts! && deploy end From 6e4247206719c8330f6229139df17858e8de734c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 13:33:25 -0300 Subject: [PATCH 10/86] =?UTF-8?q?fix:=20darle=20bola=20a=20los=20mensajes?= =?UTF-8?q?=20de=20deprecaci=C3=B3n=20de=20bundler=20#13610?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit se configuraban las opciones que le pasábamos pero no se aplicaban en el comando actual, con lo que quería instalar las gemas globalmente y fallaba la creación de sitios. --- app/models/deploy_local.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 75ea8b1c..ed5f1919 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -138,7 +138,12 @@ class DeployLocal < Deploy end def bundle(output: false) - run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output + run %(bundle config set --local clean 'true'), output: output + run %(bundle config set --local deployment 'true'), output: output + run %(bundle config set --local path '#{gems_dir}'), output: output + run %(bundle config set --local without 'test development'), output: output + run %(bundle config set --local cache_all 'false'), output: output + run %(bundle install), output: output end def jekyll_build(output: false) From d17db5428abb9df95ddf32bf8cdbd7189a60fec5 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 18:28:34 -0300 Subject: [PATCH 11/86] fix: deprecar Dir#chdir #13619 --- app/models/deploy.rb | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index a92708c0..515a8530 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -65,22 +65,20 @@ class Deploy < ApplicationRecord lines = [] time_start - Dir.chdir(site.path) do - Open3.popen2e(env, cmd, unsetenv_others: true) do |_, o, t| - # TODO: Enviar a un websocket para ver el proceso en vivo? - Thread.new do - o.each do |line| - lines << line + Open3.popen2e(env, cmd, unsetenv_others: true, chdir: site.path) do |_, o, t| + # TODO: Enviar a un websocket para ver el proceso en vivo? + Thread.new do + o.each do |line| + lines << line - puts line if output - end - rescue IOError => e - lines << e.message - puts e.message if output + puts line if output end - - r = t.value + rescue IOError => e + lines << e.message + puts e.message if output end + + r = t.value end time_stop From 6d64fa144392d0b011ca56ec677f99f095857a27 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 15 Jun 2023 18:51:16 -0300 Subject: [PATCH 12/86] fix: generar un registro cuando falla distributed press #13628 --- app/models/deploy_distributed_press.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 889d8e34..2c892b55 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -52,7 +52,12 @@ class DeployDistributedPress < Deploy end end - status = c.publish(publishing_site, deploy_local.destination) + begin + status = c.publish(publishing_site, deploy_local.destination) + rescue DistributedPress::V1::Error => e + ExceptionNotifier.notify_exception(e, data: { site: site.name }) + status = false + end if status self.remote_info[:distributed_press] = c.show(publishing_site).to_h From bb7487e941f86fb74a3be4dbc7383ebd5384c721 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 6 Jul 2023 12:43:28 -0300 Subject: [PATCH 13/86] fix: correr chdir de a uno por thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit como jekyll no es multi-threaded, pero rails si, es posible que se produzca una excepción en Dir.chdir si se intenta leer sitios concurrentemente (por ejemplo, abrir dos pestañas del mismo sitio). closes #13717 closes #13716 closes #13715 closes #13619 --- app/models/site.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..81264a24 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -447,6 +447,10 @@ class Site < ApplicationRecord find_by(name: "#{Site.domain}.") end + def self.one_at_a_time + @@one_at_a_time ||= Thread::Mutex.new + end + def reset @read = false @layouts = nil @@ -553,7 +557,9 @@ class Site < ApplicationRecord end def run_in_path(&block) - Dir.chdir path, &block + Site.one_at_a_time.synchronize do + Dir.chdir path, &block + end end # Instala las gemas cuando es necesario: From ae794322787548a79e6416663c45f3e8dd9cad62 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 21 Jul 2023 17:33:23 -0300 Subject: [PATCH 14/86] fix: renombrar el skel a upstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit si lo mantenemos como origin por defecto, el GitPushJob va a querer enviar cambios a un repositorio común, rompiendo todo. --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..0fddeff5 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -473,7 +473,7 @@ class Site < ApplicationRecord def clone_skel! return if jekyll? - Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path + Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path, remote: 'upstream' end # Elimina el directorio del sitio From b7e93cd8c8e8a9cbccc40d865571e21ecf0abfc3 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 26 Jul 2023 14:44:11 -0300 Subject: [PATCH 15/86] feat: controlador para gestionar los webhooks #13903 --- app/controllers/api/v1/webhooks_controller.rb | 17 +++++++++++++++++ app/models/site/repository.rb | 4 ++-- config/locales/en.yml | 3 +++ config/locales/es.yml | 3 +++ config/routes.rb | 2 ++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 app/controllers/api/v1/webhooks_controller.rb diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb new file mode 100644 index 00000000..4811d792 --- /dev/null +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Api + module V1 + # Recibe webhooks y lanza jobs + class WebhooksController < BaseController + def pull + # encontrar el sitio + site = Site.find_by_name(params[:site_id]) + usuarie = GitAuthor.new email: "webhook@#{Site.domain}", name: 'Webhook' + message = I18n.t('webhooks.pull.message') + + GitPullJob.perform_later(site, usuarie, message) + end + end + end +end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 404cde3e..a3487bc5 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -56,7 +56,7 @@ class Site # Incorpora los cambios en el repositorio actual # # @return [Rugged::Commit] - def merge(usuarie) + def merge(usuarie, message) merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos @@ -71,7 +71,7 @@ class Site .create(rugged, update_ref: 'HEAD', parents: [head_commit, remote_head_commit], tree: merge.write_tree(rugged), - message: I18n.t('sites.fetch.merge.message'), + message: message, author: author(usuarie), committer: committer) # Forzamos el checkout para mover el HEAD al último commit y diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..05fcf1e5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -466,6 +466,9 @@ en: success: 'Site upgrade has been completed. Your next build will run this upgrade :)' error: "There was an error when trying to upgrade your site. This could be due to conflicts that couldn't be solved automatically. A report of the issue has already been sent to our admins. Sorry for the inconvenience! :(" message: 'Skeleton upgrade' + webhooks_controller: + pull: + message: 'Webhooks upgrade' footer: powered_by: 'is developed by' i18n: diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..af5a7db7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -474,6 +474,9 @@ es: success: 'Ya se incorporaron los cambios en el sitio, se aplicarán en la próxima compilación que hagas :)' error: 'Hubo un error al incorporar los cambios en el sitio. Esto puede deberse a conflictos entre cambios que no se pueden resolver automáticamente. Hemos enviado un reporte del problema a les administradores de Sutty para que estén al tanto de la situación. ¡Lo sentimos! :(' message: 'Actualización del esqueleto' + webhooks_controller: + pull: + message: 'Actualización desde Webhooks' footer: powered_by: 'es desarrollada por' i18n: diff --git a/config/routes.rb b/config/routes.rb index 3828915c..f2487066 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,6 +17,8 @@ Rails.application.routes.draw do get :'contact/cookie', to: 'invitades#contact_cookie' post :'contact/:form', to: 'contact#receive', as: :contact + + post :'webhooks/pull', to: 'webhooks#pull' end end end From 8947942cb9066f2775faf4b0864e2874a1c39907 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 27 Jul 2023 16:46:32 -0300 Subject: [PATCH 16/86] fix: commit message fixed #13903 --- app/controllers/api/v1/webhooks_controller.rb | 9 ++++++--- app/jobs/git_pull_job.rb | 4 ++-- app/models/site/repository.rb | 2 +- config/locales/en.yml | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 4811d792..40187915 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -4,11 +4,14 @@ 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 - # encontrar el sitio - site = Site.find_by_name(params[:site_id]) + site = Site.find_by_name!(params[:site_id]) usuarie = GitAuthor.new email: "webhook@#{Site.domain}", name: 'Webhook' - message = I18n.t('webhooks.pull.message') + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') + end GitPullJob.perform_later(site, usuarie, message) end diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index de263403..5cd86981 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -6,8 +6,8 @@ class GitPullJob < ApplicationJob # @param :site [Site] # @param :usuarie [Usuarie] # @return [nil] - def perform(site, usuarie) + def perform(site, usuarie, message) site.repository.fetch - site.repository.merge(usuarie) + site.repository.merge(usuarie, message) if site.repository.fetch&.positive? end end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index a3487bc5..a864e8b9 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -56,7 +56,7 @@ class Site # Incorpora los cambios en el repositorio actual # # @return [Rugged::Commit] - def merge(usuarie, message) + def merge(usuarie, message= I18n.t('sites.fetch.merge.message')) merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos diff --git a/config/locales/en.yml b/config/locales/en.yml index 05fcf1e5..8ae8cce5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -468,7 +468,7 @@ en: message: 'Skeleton upgrade' webhooks_controller: pull: - message: 'Webhooks upgrade' + message: 'Webhooks pull' footer: powered_by: 'is developed by' i18n: From 9f5364a738825e7dc17b8482ecdd882f069d1ba4 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 27 Jul 2023 17:02:48 -0300 Subject: [PATCH 17/86] fix: add documentation to pull job #13903 --- app/jobs/git_pull_job.rb | 2 +- app/models/site/repository.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index 5cd86981..a0c15950 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -5,9 +5,9 @@ class GitPullJob < ApplicationJob # @param :site [Site] # @param :usuarie [Usuarie] + # @param :message [String] # @return [nil] def perform(site, usuarie, message) - site.repository.fetch site.repository.merge(usuarie, message) if site.repository.fetch&.positive? end end \ No newline at end of file diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index a864e8b9..c0607d84 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -56,7 +56,7 @@ class Site # Incorpora los cambios en el repositorio actual # # @return [Rugged::Commit] - def merge(usuarie, message= I18n.t('sites.fetch.merge.message')) + def merge(usuarie, message = I18n.t('sites.fetch.merge.message')) merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos From 9f94ee3bc704dfe9a7787ce6be0b8015a2fcb676 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 27 Jul 2023 17:23:40 -0300 Subject: [PATCH 18/86] fix: add response status to pull method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 2 ++ config/locales/es.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 40187915..a538d99f 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -14,6 +14,8 @@ module Api end GitPullJob.perform_later(site, usuarie, message) + + head :ok end end end diff --git a/config/locales/es.yml b/config/locales/es.yml index af5a7db7..b03a222f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -476,7 +476,7 @@ es: message: 'Actualización del esqueleto' webhooks_controller: pull: - message: 'Actualización desde Webhooks' + message: 'Pull de webhooks' footer: powered_by: 'es desarrollada por' i18n: From 9a78c628b4aac8bffe44e4dffb80d0c268be6b83 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 12:29:27 -0300 Subject: [PATCH 19/86] fix: fix typo in es.yml #13864 --- config/locales/es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..eabddcc9 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -693,7 +693,7 @@ es: new: 'Crear' edit: 'Configurar' posts: - new: 'Nuevo %{layout}' + new: 'Agregar %{layout}' edit: 'Editando' usuaries: index: 'Usuaries' From 06ebb63d9389c260e547c73487eb89c108dacb0b Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 14:18:07 -0300 Subject: [PATCH 20/86] =?UTF-8?q?fix:=20movido=20git=20lfs=20a=20m=C3=A9to?= =?UTF-8?q?do=20merge=20en=20repository.rb=20#13903?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/git_pull_job.rb | 4 ++-- app/models/site/repository.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/jobs/git_pull_job.rb b/app/jobs/git_pull_job.rb index a0c15950..dc4a285c 100644 --- a/app/jobs/git_pull_job.rb +++ b/app/jobs/git_pull_job.rb @@ -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] diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index c0607d84..9c4d873f 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -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 From 579e1776842774733c036b6b621ccf087b2b06cc Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 17:32:14 -0300 Subject: [PATCH 21/86] feat: agregada columna token a model rol #13903 --- app/models/rol.rb | 10 ++++++++++ db/migrate/20230731195050_add_token_to_roles.rb | 5 +++++ db/migrate/20230731202003_change_token_name.rb | 5 +++++ 3 files changed, 20 insertions(+) create mode 100644 db/migrate/20230731195050_add_token_to_roles.rb create mode 100644 db/migrate/20230731202003_change_token_name.rb diff --git a/app/models/rol.rb b/app/models/rol.rb index fcd07037..f17bf418 100644 --- a/app/models/rol.rb +++ b/app/models/rol.rb @@ -14,6 +14,9 @@ class Rol < ApplicationRecord validates_inclusion_of :rol, in: ROLES + encrypts :token + before_save :add_token_if_missing! + def invitade? rol == INVITADE end @@ -25,4 +28,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 diff --git a/db/migrate/20230731195050_add_token_to_roles.rb b/db/migrate/20230731195050_add_token_to_roles.rb new file mode 100644 index 00000000..635e065c --- /dev/null +++ b/db/migrate/20230731195050_add_token_to_roles.rb @@ -0,0 +1,5 @@ +class AddTokenToRoles < ActiveRecord::Migration[6.1] + def change + add_column :roles, :token, :text + end +end diff --git a/db/migrate/20230731202003_change_token_name.rb b/db/migrate/20230731202003_change_token_name.rb new file mode 100644 index 00000000..50fc0c40 --- /dev/null +++ b/db/migrate/20230731202003_change_token_name.rb @@ -0,0 +1,5 @@ +class ChangeTokenName < ActiveRecord::Migration[6.1] + def change + rename_column :roles, :token, :token_cyphertext + end +end From c19c834f10962e3c58d2b08418ee7790430318c9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 31 Jul 2023 18:46:07 -0300 Subject: [PATCH 22/86] =?UTF-8?q?fix:=20cambio=20nombre=20comuna=20token?= =?UTF-8?q?=5Fcyphertext=20en=20modelo=20rol=20y=20asignaci=C3=B3n=20retro?= =?UTF-8?q?activa=20#13903?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20230731202003_change_token_name.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20230731202003_change_token_name.rb b/db/migrate/20230731202003_change_token_name.rb index 50fc0c40..c3fce3c0 100644 --- a/db/migrate/20230731202003_change_token_name.rb +++ b/db/migrate/20230731202003_change_token_name.rb @@ -1,5 +1,6 @@ class ChangeTokenName < ActiveRecord::Migration[6.1] def change rename_column :roles, :token, :token_cyphertext + Rol.find_each { |m| m.update_column( :token_cyphertext, SecureRandom.hex(64) ) } end end From 705d15c0c1959d3e50b2f8646830a15372c4797e Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 10 Aug 2023 16:05:14 -0300 Subject: [PATCH 23/86] fix: change token attribute from encrypted to normal in Rol model #13903 --- app/controllers/api/v1/webhooks_controller.rb | 22 ++++++++++++++----- app/models/rol.rb | 1 - 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index a538d99f..1933f24e 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -2,19 +2,31 @@ module Api module V1 - # Recibe webhooks y lanza jobs + # Recibe webhooks y lanza un PullJob class WebhooksController < BaseController + rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + + def site + @site ||= Site.find_by_name!(params[:site_id]) + end + + # valida la plataforma del webhook + def usuarie + # Gitlab + token = request.headers["X-Gitlab-Token"] + @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie + end + # 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') end - GitPullJob.perform_later(site, usuarie, message) - + end + + def platforms_answer head :ok end end diff --git a/app/models/rol.rb b/app/models/rol.rb index f17bf418..37332400 100644 --- a/app/models/rol.rb +++ b/app/models/rol.rb @@ -14,7 +14,6 @@ class Rol < ApplicationRecord validates_inclusion_of :rol, in: ROLES - encrypts :token before_save :add_token_if_missing! def invitade? From 63fd91ee48f3a9cab4417f6e9bd21be6604440f0 Mon Sep 17 00:00:00 2001 From: jazzari Date: Thu, 10 Aug 2023 16:13:13 -0300 Subject: [PATCH 24/86] feat: add token to existing records #13903 --- db/migrate/20230731195050_add_token_to_roles.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20230731195050_add_token_to_roles.rb b/db/migrate/20230731195050_add_token_to_roles.rb index 635e065c..620c9fef 100644 --- a/db/migrate/20230731195050_add_token_to_roles.rb +++ b/db/migrate/20230731195050_add_token_to_roles.rb @@ -1,5 +1,6 @@ class AddTokenToRoles < ActiveRecord::Migration[6.1] def change add_column :roles, :token, :text + Rol.find_each { |m| m.update_column( :token, SecureRandom.hex(64) ) } end end From 23732bbfe0ed8c4920bd7188b700f63ed5612b51 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 14 Aug 2023 12:50:18 -0300 Subject: [PATCH 25/86] feat: add method to validate token from diff platforms in webhooks controller #13903 --- app/controllers/api/v1/webhooks_controller.rb | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 1933f24e..091d467e 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -10,10 +10,32 @@ module Api @site ||= Site.find_by_name!(params[:site_id]) end - # valida la plataforma del webhook + # valida el token que envía la plataforma del webhook + def token + @token ||= + begin + # Gitlab + if request.headers['X-Gitlab-Token'] + request.headers["X-Gitlab-Token"] + # Github + elsif request.headers['X-HUB-SIGNATURE-256'] + signature(request.env['HTTP_X_HUB_SIGNATURE_256']) + # Guitea + else + signature(request.env['HTTP_X_GITEA_SIGNATURE']) + end + end + end + + def token_from_signature(signature) + payload = request.body.read + site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| + new_signature = hash_mac(OpenSSL::Digest.new('sha256'), token, payload) + @token ||= Rack::Utils.secure_compare(new_signature, signature) + end + end + def usuarie - # Gitlab - token = request.headers["X-Gitlab-Token"] @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie end @@ -23,6 +45,7 @@ module Api message = I18n.with_locale(site.default_locale) do I18n.t('webhooks.pull.message') end + GitPullJob.perform_later(site, usuarie, message) end From f2236bb305573e7a471e1b3a94ab50d486bc0d63 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 14 Aug 2023 16:49:24 -0300 Subject: [PATCH 26/86] feat: move methods to private #13903 --- app/controllers/api/v1/webhooks_controller.rb | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 091d467e..b356d20a 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -6,6 +6,19 @@ module Api class WebhooksController < BaseController rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + # Trae los cambios a partir de un post de Webhooks: + # (Gitlab, Github, Guitea, etc) + def pull + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') + end + + GitPullJob.perform_later(site, usuarie, message) + platforms_answer + end + + private + def site @site ||= Site.find_by_name!(params[:site_id]) end @@ -37,17 +50,7 @@ module Api def usuarie @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end - - # Trae los cambios a partir de un post de Webhooks: - # (Gitlab, Github, Guitea, etc) - def pull - message = I18n.with_locale(site.default_locale) do - I18n.t('webhooks.pull.message') - end - - GitPullJob.perform_later(site, usuarie, message) - end + end def platforms_answer head :ok From a098e1baa7d2e7e96b18bc16be7a21cc413c8f38 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 15 Aug 2023 16:14:34 -0300 Subject: [PATCH 27/86] fix: change migration methods to add token to roles #13903 --- db/migrate/20230731195050_add_token_to_roles.rb | 12 +++++++++--- db/migrate/20230731202003_change_token_name.rb | 6 ------ 2 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 db/migrate/20230731202003_change_token_name.rb diff --git a/db/migrate/20230731195050_add_token_to_roles.rb b/db/migrate/20230731195050_add_token_to_roles.rb index 620c9fef..c38b0526 100644 --- a/db/migrate/20230731195050_add_token_to_roles.rb +++ b/db/migrate/20230731195050_add_token_to_roles.rb @@ -1,6 +1,12 @@ class AddTokenToRoles < ActiveRecord::Migration[6.1] - def change - add_column :roles, :token, :text - Rol.find_each { |m| m.update_column( :token, SecureRandom.hex(64) ) } + 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 diff --git a/db/migrate/20230731202003_change_token_name.rb b/db/migrate/20230731202003_change_token_name.rb deleted file mode 100644 index c3fce3c0..00000000 --- a/db/migrate/20230731202003_change_token_name.rb +++ /dev/null @@ -1,6 +0,0 @@ -class ChangeTokenName < ActiveRecord::Migration[6.1] - def change - rename_column :roles, :token, :token_cyphertext - Rol.find_each { |m| m.update_column( :token_cyphertext, SecureRandom.hex(64) ) } - end -end From c5406acb26221e591804d481ac6547072dd38952 Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 15 Aug 2023 16:59:16 -0300 Subject: [PATCH 28/86] fix: add documentation and fix typos #13903 --- app/controllers/api/v1/webhooks_controller.rb | 101 ++++++++++-------- config/locales/es.yml | 2 +- 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index b356d20a..20cc0ddc 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -1,60 +1,69 @@ # frozen_string_literal: true module Api - module V1 - # Recibe webhooks y lanza un PullJob - class WebhooksController < BaseController - rescue_from ActiveRecord::RecordNotFound, with: :platforms_answer + 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, Guitea, etc) - def pull - message = I18n.with_locale(site.default_locale) do - I18n.t('webhooks.pull.message') - end - - GitPullJob.perform_later(site, usuarie, message) - platforms_answer + # Trae los cambios a partir de un post de Webhooks: + # (Gitlab, Github, Gitea, etc) + def pull + message = I18n.with_locale(site.default_locale) do + I18n.t('webhooks.pull.message') end - private + GitPullJob.perform_later(site, usuarie, message) + head :ok + end - def site - @site ||= Site.find_by_name!(params[:site_id]) - end + private - # valida el token que envía la plataforma del webhook - def token - @token ||= - begin - # Gitlab - if request.headers['X-Gitlab-Token'] - request.headers["X-Gitlab-Token"] - # Github - elsif request.headers['X-HUB-SIGNATURE-256'] - signature(request.env['HTTP_X_HUB_SIGNATURE_256']) - # Guitea - else - signature(request.env['HTTP_X_GITEA_SIGNATURE']) - end - end - end + # encuentra el sitio a partir de la url + def site + @site ||= Site.find_by_name!(params[:site_id]) + end - def token_from_signature(signature) - payload = request.body.read - site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| - new_signature = hash_mac(OpenSSL::Digest.new('sha256'), token, payload) - @token ||= Rack::Utils.secure_compare(new_signature, signature) - end - 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'] + request.env['HTTP_X_HUB_SIGNATURE_256'] + # Gitea + else + request.env['HTTP_X_GITEA_SIGNATURE'] + end + end + end - def usuarie - @usuarie = site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end - - def platforms_answer - head :ok + # valida token a partir de firma de webhook + # + # @return [String] + 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 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 + head :forbidden + end end + end end \ No newline at end of file diff --git a/config/locales/es.yml b/config/locales/es.yml index b03a222f..7a83483f 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -476,7 +476,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: From aeb2105dc7273cf603ab8e86f7bc90780f96093f Mon Sep 17 00:00:00 2001 From: jazzari Date: Tue, 15 Aug 2023 19:25:06 -0300 Subject: [PATCH 29/86] fix: add rescue in token_from_signature method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 20cc0ddc..0ecca9d7 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -9,6 +9,8 @@ module Api # 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') @@ -36,22 +38,27 @@ module Api request.headers['X-Gitlab-Token'] # Github elsif request.headers['X-HUB-SIGNATURE-256'] - request.env['HTTP_X_HUB_SIGNATURE_256'] + token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) # Gitea else - request.env['HTTP_X_GITEA_SIGNATURE'] + token_from_signatureq(request.env['HTTP_X_GITEA_SIGNATURE']) end end end # valida token a partir de firma de webhook # - # @return [String] + # @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 ArgumentError, 'token no encontrado' if t.nil? + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) + raise ActiveRecord::RecordNotFound end end From 5ac628b38a0032a26e0f9d29f1c4e1266069360b Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 12:58:14 -0300 Subject: [PATCH 30/86] fix: fix typo and change response to platforms #13903 --- app/controllers/api/v1/webhooks_controller.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 0ecca9d7..40f2f06d 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -40,8 +40,10 @@ module Api elsif request.headers['X-HUB-SIGNATURE-256'] token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) # Gitea + elsif + token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) else - token_from_signatureq(request.env['HTTP_X_GITEA_SIGNATURE']) + raise ActiveRecord::RecordNotFound end end end @@ -55,10 +57,7 @@ module Api new_signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) ActiveSupport::SecurityUtils.secure_compare(new_signature, signature) end.tap do |t| - raise ArgumentError, 'token no encontrado' if t.nil? - rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) - raise ActiveRecord::RecordNotFound + raise ActiveRecord::RecordNotFound if t.nil? end end @@ -70,6 +69,9 @@ module Api # respuesta de error a plataformas def platforms_answer head :forbidden + raise ArgumentError, 'token no encontrado' + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) end end end From 35dca9d7565f40f2a037b095ea8005cd2a953232 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 13:39:29 -0300 Subject: [PATCH 31/86] fix: fix exception in platforms_answer method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 40f2f06d..13a227ce 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -57,7 +57,7 @@ module Api 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 if t.nil? + raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil? end end @@ -67,12 +67,9 @@ module Api end # respuesta de error a plataformas - def platforms_answer + def platforms_answer(exception) head :forbidden - raise ArgumentError, 'token no encontrado' - rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { params: params.to_h }) - end + ExceptionNotifier.notify_exception(exception, data: { params: params.to_h }) end end end \ No newline at end of file From cefd053d1d7f70233f07cd047fd1dc5d321dd8b5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 14:57:01 -0300 Subject: [PATCH 32/86] fix: add condition in elsif in token method #13903 --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 13a227ce..3af9abee 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -40,7 +40,7 @@ module Api elsif request.headers['X-HUB-SIGNATURE-256'] token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) # Gitea - elsif + elsif request.headers['HTTP_X_GITEA_SIGNATURE'] token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) else raise ActiveRecord::RecordNotFound From 114fe4b2d5dce83874735cf1de97af6e89b925d5 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 16 Aug 2023 15:43:57 -0300 Subject: [PATCH 33/86] fix: fix in es.yml & en.yml and missing end #13903 --- app/controllers/api/v1/webhooks_controller.rb | 11 ++++++----- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 3af9abee..8ef943be 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -38,12 +38,12 @@ module Api request.headers['X-Gitlab-Token'] # Github elsif request.headers['X-HUB-SIGNATURE-256'] - token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256']) + token_from_signature(request.env['HTTP_X_HUB_SIGNATURE_256'], 'sha256=') # Gitea elsif request.headers['HTTP_X_GITEA_SIGNATURE'] token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) else - raise ActiveRecord::RecordNotFound + raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end end end @@ -51,10 +51,10 @@ module Api # valida token a partir de firma de webhook # # @return [String, Boolean] - def token_from_signature(signature) + def token_from_signature(signature. prepend = '') 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) + new_signature = prepend + 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? @@ -69,7 +69,8 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) head :forbidden - ExceptionNotifier.notify_exception(exception, data: { params: params.to_h }) + ExceptionNotifier.notify_exception(exception, env: request.env) + end end end end \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 8ae8cce5..c9a723bc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -466,7 +466,7 @@ en: success: 'Site upgrade has been completed. Your next build will run this upgrade :)' error: "There was an error when trying to upgrade your site. This could be due to conflicts that couldn't be solved automatically. A report of the issue has already been sent to our admins. Sorry for the inconvenience! :(" message: 'Skeleton upgrade' - webhooks_controller: + webhooks: pull: message: 'Webhooks pull' footer: diff --git a/config/locales/es.yml b/config/locales/es.yml index 7a83483f..857217ec 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -474,7 +474,7 @@ es: success: 'Ya se incorporaron los cambios en el sitio, se aplicarán en la próxima compilación que hagas :)' error: 'Hubo un error al incorporar los cambios en el sitio. Esto puede deberse a conflictos entre cambios que no se pueden resolver automáticamente. Hemos enviado un reporte del problema a les administradores de Sutty para que estén al tanto de la situación. ¡Lo sentimos! :(' message: 'Actualización del esqueleto' - webhooks_controller: + webhooks: pull: message: 'Traer los cambios a partir de un evento remoto' footer: From 5ef601139fab2f99952dcda124a6a06bd10dc054 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:21:48 -0300 Subject: [PATCH 34/86] fix: eliminar espacio en blanco --- app/controllers/api/v1/webhooks_controller.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 8ef943be..fb4a710c 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -11,7 +11,7 @@ module Api # (Gitlab, Github, Gitea, etc) # # @return [nil] - def pull + def pull message = I18n.with_locale(site.default_locale) do I18n.t('webhooks.pull.message') end @@ -20,17 +20,17 @@ module Api head :ok end - private + private # encuentra el sitio a partir de la url - def site + 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 + def token @token ||= begin # Gitlab @@ -45,14 +45,14 @@ module Api else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end - end + end end # valida token a partir de firma de webhook # # @return [String, Boolean] def token_from_signature(signature. prepend = '') - payload = request.body.read + payload = request.body.read 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) @@ -61,10 +61,10 @@ module Api end end - # encuentra le usuarie + # encuentra le usuarie def usuarie @usuarie ||= site.roles.find_by!(temporal: false, rol: 'usuarie', token: token).usuarie - end + end # respuesta de error a plataformas def platforms_answer(exception) @@ -73,4 +73,4 @@ module Api end end end -end \ No newline at end of file +end From 690efe329c571c0d8c601645735d186b7890a572 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:22:57 -0300 Subject: [PATCH 35/86] fix: llamar a los headers consistentemente --- app/controllers/api/v1/webhooks_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index fb4a710c..1d1258fd 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -37,11 +37,11 @@ module Api 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'], 'sha256=') + elsif request.headers['X-Hub-Signature-256'] + token_from_signature(request.headers['X_Hub_Signature_256'], 'sha256=') # Gitea - elsif request.headers['HTTP_X_GITEA_SIGNATURE'] - token_from_signature(request.env['HTTP_X_GITEA_SIGNATURE']) + elsif request.headers['X_Gitea_Signature'] + token_from_signature(request.headers['X_Gitea_Signature']) else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end From a99e03ce15d13122f36e2aab976fd5229156300e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:23:39 -0300 Subject: [PATCH 36/86] feat: enviar los headers en el reporte --- app/controllers/api/v1/webhooks_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 1d1258fd..6be6c2dc 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -68,8 +68,9 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) + ExceptionNotifier.notify_exception(exception, env: request.env, data: { headers: request.headers.to_h }) + head :forbidden - ExceptionNotifier.notify_exception(exception, env: request.env) end end end From 42e6a0b6eb5432773d2337ed33ac154defd2c042 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:24:33 -0300 Subject: [PATCH 37/86] fix: typo --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 6be6c2dc..ab2fce6b 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -51,7 +51,7 @@ module Api # valida token a partir de firma de webhook # # @return [String, Boolean] - def token_from_signature(signature. prepend = '') + def token_from_signature(signature, prepend = '') payload = request.body.read site.roles.where(temporal: false, rol: 'usuarie').pluck(:token).find do |token| new_signature = prepend + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, payload) From b9083c492cd3e50971bbbca9a549b81c4781efe3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:26:39 -0300 Subject: [PATCH 38/86] fix: presencia --- app/controllers/api/v1/webhooks_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index ab2fce6b..23bfae22 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -34,13 +34,13 @@ module Api @token ||= begin # Gitlab - if request.headers['X-Gitlab-Token'] + if request.headers['X-Gitlab-Token'].present? request.headers['X-Gitlab-Token'] # Github - elsif request.headers['X-Hub-Signature-256'] + elsif request.headers['X-Hub-Signature-256'].present? token_from_signature(request.headers['X_Hub_Signature_256'], 'sha256=') # Gitea - elsif request.headers['X_Gitea_Signature'] + elsif request.headers['X_Gitea_Signature'].present? token_from_signature(request.headers['X_Gitea_Signature']) else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' From a2678c3e81f7943368edf9a51e9de80354af603f Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:35:36 -0300 Subject: [PATCH 39/86] fix: no ignorar excepciones como record not found --- config/environments/production.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 4cc1cb39..5e089ff9 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -142,7 +142,7 @@ Rails.application.configure do } config.action_mailer.default_options = { from: ENV.fetch('DEFAULT_FROM', "noreply@sutty.nl") } - config.middleware.use ExceptionNotification::Rack, gitlab: {}, ignore_exceptions: (['DeployJob::DeployAlreadyRunningException'] + ExceptionNotifier.ignored_exceptions) + config.middleware.use ExceptionNotification::Rack, gitlab: {}, ignore_exceptions: ['DeployJob::DeployAlreadyRunningException'] Rails.application.routes.default_url_options[:host] = "panel.#{ENV.fetch('SUTTY', 'sutty.nl')}" Rails.application.routes.default_url_options[:protocol] = 'https' From ef8ed271d75dd1e4bdf079c11f8bcaf450af25ac Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 16:46:11 -0300 Subject: [PATCH 40/86] fix: consistencia al llamar a headers --- app/controllers/api/v1/webhooks_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 23bfae22..95439cd4 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -38,10 +38,10 @@ module Api request.headers['X-Gitlab-Token'] # Github elsif request.headers['X-Hub-Signature-256'].present? - token_from_signature(request.headers['X_Hub_Signature_256'], 'sha256=') + token_from_signature(request.headers['X-Hub-Signature-256'], 'sha256=') # Gitea - elsif request.headers['X_Gitea_Signature'].present? - token_from_signature(request.headers['X_Gitea_Signature']) + elsif request.headers['X-Gitea-Signature'].present? + token_from_signature(request.headers['X-Gitea-Signature']) else raise ActiveRecord::RecordNotFound, 'proveedor no soportado' end From 4a7ac981e5029ce8c23fa0c54c5ba99268dcb3ee Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 17:04:34 -0300 Subject: [PATCH 41/86] fix: no fallar si la firma es nil closes #14089 --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 95439cd4..1730034e 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -55,7 +55,7 @@ module Api payload = request.body.read 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) + ActiveSupport::SecurityUtils.secure_compare(new_signature, signature.to_s) end.tap do |t| raise ActiveRecord::RecordNotFound, 'token no encontrado' if t.nil? end From 6bae3a68f167956a7799d1252833ab2f7b0e694a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 17:35:20 -0300 Subject: [PATCH 42/86] feat: enviar cambios luego de commitearlos --- app/services/post_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/post_service.rb b/app/services/post_service.rb index 7b31867d..601915f8 100644 --- a/app/services/post_service.rb +++ b/app/services/post_service.rb @@ -96,6 +96,8 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do remove: action == :destroyed, message: I18n.t("post_service.#{action}", title: post&.title&.value)) + + GitPushJob.perform_later(site) end # Solo permitir cambiar estos atributos de cada articulo From 5a004b1cad1734af695a37d92d4a271603b818f1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Aug 2023 17:35:33 -0300 Subject: [PATCH 43/86] =?UTF-8?q?feat:=20enviar=20configuraci=C3=B3n=20lue?= =?UTF-8?q?go=20de=20comitearla?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/site_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 2c29538c..fc82ae84 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -97,6 +97,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do file: site.config.path, message: I18n.t("site_service.#{action}", name: site.name)) + + GitPushJob.perform_later(site) end def add_role(temporal: true, rol: 'invitade') From 1be1977c343a6d6b6a9a379d9414872db9830f8b Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 23 Aug 2023 14:13:25 -0300 Subject: [PATCH 44/86] fix: fix minima design's link to demostration site #14131 --- db/seeds/designs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/seeds/designs.yml b/db/seeds/designs.yml index a04c99c1..46f1cd0d 100644 --- a/db/seeds/designs.yml +++ b/db/seeds/designs.yml @@ -18,7 +18,7 @@ - name_en: 'Minima' name_es: 'Mínima' gem: 'sutty-minima' - url: 'https://0xacab.org/sutty/jekyll/minima' + url: 'https://minima.sutty.nl/' description_en: "Sutty Minima is based on [Minima](https://jekyll.github.io/minima/), a blog-focused theme for Jekyll." description_es: 'Sutty Mínima es una plantilla para blogs basada en [Mínima](https://jekyll.github.io/minima/).' license: 'https://0xacab.org/sutty/jekyll/minima/-/blob/master/LICENSE.txt' From c6c638fb60edf3d8f7a6eddbc7dab819b01e1d15 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 29 Aug 2023 17:43:19 -0300 Subject: [PATCH 45/86] feat: almacenar la llave privada --- app/models/site.rb | 1 + app/models/site/social_distributed_press.rb | 12 ++++++++++++ ...204127_add_private_key_pem_ciphertext_to_sites.rb | 9 +++++++++ 3 files changed, 22 insertions(+) create mode 100644 app/models/site/social_distributed_press.rb create mode 100644 db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..9ec21561 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -10,6 +10,7 @@ class Site < ApplicationRecord include Site::DeployDependencies include Site::BuildStats include Site::LayoutOrdering + include Site::SocialDistributedPress include Tienda # Cifrar la llave privada que cifra y decifra campos ocultos. Sutty diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb new file mode 100644 index 00000000..9d283103 --- /dev/null +++ b/app/models/site/social_distributed_press.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Site + # Agrega soporte para Social Distributed Press en los sitios + module SocialDistributedPress + extend ActiveSupport::Concern + + included do + encrypts :private_key_pem + end + end +end diff --git a/db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb b/db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb new file mode 100644 index 00000000..9f26f21a --- /dev/null +++ b/db/migrate/20230829204127_add_private_key_pem_ciphertext_to_sites.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Almacena las llaves privadas de cada sitio +class AddPrivateKeyPemCiphertextToSites < ActiveRecord::Migration[6.1] + # Agrega la columna cifrada + def change + add_column :sites, :private_key_pem_ciphertext, :text + end +end From 4de3352950f700bd303d2f5e472f5045a06c1810 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 29 Aug 2023 17:49:25 -0300 Subject: [PATCH 46/86] feat: generar la llave privada #14169 --- app/models/site/social_distributed_press.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/models/site/social_distributed_press.rb b/app/models/site/social_distributed_press.rb index 9d283103..5d469f03 100644 --- a/app/models/site/social_distributed_press.rb +++ b/app/models/site/social_distributed_press.rb @@ -7,6 +7,17 @@ class Site included do encrypts :private_key_pem + + before_save :generate_private_key_pem!, unless: :private_key_pem? + + private + + # Genera la llave privada y la almacena + # + # @return [nil] + def generate_private_key_pem! + self.private_key_pem ||= DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export + end end end end From 8b0b0199f60ad67b733c781fbc3425d5f6546fba Mon Sep 17 00:00:00 2001 From: f Date: Tue, 29 Aug 2023 18:26:03 -0300 Subject: [PATCH 47/86] feat: correr un comando obteniendo la llave dentro de un archivo temporal --- app/models/deploy.rb | 15 +++++++++++++++ app/models/deploy_local.rb | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index a92708c0..77e5b8d8 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -109,6 +109,21 @@ class Deploy < ApplicationRecord private + # Escribe el contenido en un archivo temporal y ejecuta el bloque + # provisto con el archivo como parámetro + # + # @param :content [String] + def with_tempfile(content, &block) + Tempfile.create(SecureRandom.hex) do |file| + file.write content.to_s + file.rewind + file.close + + # @yieldparam :file [File] + yield file + end + end + # @param [String] # @return [String] def readable_cmd(cmd) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 75ea8b1c..e66bb003 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -141,8 +141,12 @@ class DeployLocal < Deploy run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output end + # TODO: Esto significa que todos los sitios van a tener activity pub + # activado def jekyll_build(output: false) - run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}"), output: output + with_tempfile(site.private_key_pem) do |file| + run %(bundle exec jekyll build --trace --profile --key #{file.path} --destination "#{escaped_destination}"), output: output + end end # no debería haber espacios ni caracteres especiales, pero por si From 9ac404ae06286e69e8981c5322c2a9256ff04f99 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 10:47:08 -0300 Subject: [PATCH 48/86] feat: habilitar/deshabilitar activity pub --- .../_deploy_social_distributed_press.haml | 21 +++++++++++++++++++ config/locales/en.yml | 12 +++++++++++ config/locales/es.yml | 12 +++++++++++ 3 files changed, 45 insertions(+) create mode 100644 app/views/deploys/_deploy_social_distributed_press.haml diff --git a/app/views/deploys/_deploy_social_distributed_press.haml b/app/views/deploys/_deploy_social_distributed_press.haml new file mode 100644 index 00000000..5c73b262 --- /dev/null +++ b/app/views/deploys/_deploy_social_distributed_press.haml @@ -0,0 +1,21 @@ +-# Publicar a la web distribuida + +.row + .col + = deploy.hidden_field :id + = deploy.hidden_field :type + .custom-control.custom-switch + -# + El checkbox invierte la lógica de destrucción porque queremos + crear el deploy si está activado y destruirlo si está + desactivado. + = deploy.check_box :_destroy, + { checked: deploy.object.persisted?, class: 'custom-control-input' }, + '0', '1' + = deploy.label :_destroy, class: 'custom-control-label' do + %h3= t('.title') + = sanitize_markdown t('.help'), + tags: %w[p strong em a] + + +%hr/ diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..0dad2e68 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -123,6 +123,10 @@ en: title: Distributed Web success: Success! error: Error + deploy_social_distributed_press: + title: Fediverse + success: Success! + error: Error deploy_reindex: title: Reindex success: Success! @@ -307,6 +311,14 @@ en: indefinitely. [Learn more](https://sutty.nl/learn-more-about-publish-to-dweb-functionality/) + deploy_social_distributed_press: + title: 'Publish on the Fediverse' + help: | + By using the ActivityPub protocol, people on the Fediverse + ([Mastodon](https://joinmastodon.org/servers), + [Pixelfed](https://pixelfed.social/site/about), and + [others](https://fediverse.party/)) can follow your site, + receive news and interact with them. stats: index: title: Statistics diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..d899b99c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -123,6 +123,10 @@ es: title: Web distribuida success: ¡Éxito! error: Hubo un error + deploy_social_distributed_press: + title: Fediverso + success: ¡Éxito! + error: Hubo un error deploy_reindex: title: Reindexación success: ¡Éxito! @@ -312,6 +316,14 @@ es: copias de tu contenido indefinidamente. [Saber más](https://sutty.nl/saber-mas-sobre-publicar-a-la-web-distribuida/) + deploy_social_distributed_press: + title: 'Publicar al Fediverso' + help: | + Utilizando el protocolo ActivityPub, otras personas en el + Fediverso ([Mastodon](https://joinmastodon.org/servers), + [Pixelfed](https://pixelfed.social/site/about) y + [otros](https://fediverse.party/)) pueden seguir a tu sitio, + recibir novedades e interactuar con ellas. stats: index: title: Estadísticas From f019805314735c813847043fadf051961ad5837a Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 10:47:27 -0300 Subject: [PATCH 49/86] =?UTF-8?q?fix:=20generar=20todos=20los=20deploys=20?= =?UTF-8?q?autom=C3=A1ticamente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site.rb | 4 ---- app/services/site_service.rb | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index 9ec21561..961831d5 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -19,10 +19,6 @@ class Site < ApplicationRecord # protege de acceso al panel de Sutty! encrypts :private_key - # TODO: Hacer que los diferentes tipos de deploy se auto registren - # @see app/services/site_service.rb - DEPLOYS = %i[local private www zip hidden_service distributed_press].freeze - validates :name, uniqueness: true, hostname: { allow_root_label: true } diff --git a/app/services/site_service.rb b/app/services/site_service.rb index b1df3d10..5bd89888 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -54,9 +54,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Genera los Deploy necesarios para el sitio a menos que ya los tenga. def build_deploys - Site::DEPLOYS.map { |deploy| "Deploy#{deploy.to_s.camelcase}" } - .each do |deploy| - next if site.deploys.find_by type: deploy + Deploy.subclasses.each do |deploy| + next if site.deploys.find_by type: deploy.name site.deploys.build type: deploy end From 4ade0944def7484ddcbee854c63ed184067b0f1c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 10:58:52 -0300 Subject: [PATCH 50/86] =?UTF-8?q?feat:=20los=20deploys=20pueden=20pasar=20?= =?UTF-8?q?opciones=20de=20compilaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy.rb | 5 ++++ app/models/deploy_local.rb | 16 ++++++++++--- app/models/deploy_social_distributed_press.rb | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 app/models/deploy_social_distributed_press.rb diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 77e5b8d8..abf5591f 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -100,6 +100,11 @@ class Deploy < ApplicationRecord @local_env ||= {} end + # Devuelve opciones para jekyll build + # + # @return [String,nil] + def flags_for_build(**args); end + # Trae todas las dependencias # # @return [Array] diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index e66bb003..9228581f 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -141,11 +141,11 @@ class DeployLocal < Deploy run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output end - # TODO: Esto significa que todos los sitios van a tener activity pub - # activado def jekyll_build(output: false) with_tempfile(site.private_key_pem) do |file| - run %(bundle exec jekyll build --trace --profile --key #{file.path} --destination "#{escaped_destination}"), output: output + flags = extra_flags(private_key: file) + + run %(bundle exec jekyll build --trace --profile #{flags} --destination "#{escaped_destination}"), output: output end end @@ -173,4 +173,14 @@ class DeployLocal < Deploy end end end + + # Genera opciones extra desde los otros deploys + # + # @param :args [Hash] + # @return [String] + def extra_flags(**args) + non_local_deploys.map do |deploy| + deploy.flags_for_build(**args) + end.compact.join(' ') + end end diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb new file mode 100644 index 00000000..47464ea9 --- /dev/null +++ b/app/models/deploy_social_distributed_press.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'distributed_press/v1/social/client' + +# Publicar novedades al Fediverso +class DeploySocialDistributedPress < Deploy + # Solo luego de publicar remotamente + DEPENDENCIES = %i[deploy_distributed_press deploy_rsync deploy_full_rsync] + + # Envía las notificaciones + def deploy(output: false) + with_tempfile(site.private_key_pem) do |file| + run %(bundle exec jekyll notify --trace --key #{file.path} --destination "#{escaped_destination}"), output: output + end + end + + # Genera la opción de llave privada para jekyll build + # + # @params :args [Hash] + # @return [String] + def flags_for_build(**args) + "--key #{Shellwords.escape args[:private_key].path}" + end +end From 26f57a8467241e825b87fefcccdf76c4e9c3561d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 11:09:08 -0300 Subject: [PATCH 51/86] =?UTF-8?q?feat:=20m=C3=A9todos=20de=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_social_distributed_press.rb | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_social_distributed_press.rb b/app/models/deploy_social_distributed_press.rb index 47464ea9..db555ab7 100644 --- a/app/models/deploy_social_distributed_press.rb +++ b/app/models/deploy_social_distributed_press.rb @@ -10,10 +10,41 @@ class DeploySocialDistributedPress < Deploy # Envía las notificaciones def deploy(output: false) with_tempfile(site.private_key_pem) do |file| - run %(bundle exec jekyll notify --trace --key #{file.path} --destination "#{escaped_destination}"), output: output + key = Shellwords.escape file.path + dest = Shellwords.escape destination + + run %(bundle exec jekyll notify --trace --key #{key} --destination "#{dest}"), output: output end end + # Igual que DeployLocal + # + # @return [String] + def destination + File.join(Rails.root, '_deploy', site.hostname) + end + + # Solo uno + # + # @return [Integer] + def limit + 1 + end + + # Espacio ocupado, pero no podemos calcularlo + # + # @return [Integer] + def size + 0 + end + + # El perfil de actor + # + # @return [String,nil] + def url + site.data.dig('activity_pub', 'actor') + end + # Genera la opción de llave privada para jekyll build # # @params :args [Hash] From 2a4073178a7b431e6f1ea1b7798fcfc1d7b8a10b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 11:13:49 -0300 Subject: [PATCH 52/86] fix: actualizar la gema --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index dd880219..5ccee727 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'commonmarker' gem 'devise' gem 'devise-i18n' gem 'devise_invitable' -gem 'distributed-press-api-client', '~> 0.2.3' +gem 'distributed-press-api-client', '~> 0.3.0rc0' gem 'njalla-api-client', '~> 0.2.0' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' diff --git a/Gemfile.lock b/Gemfile.lock index f71053d7..6c3dae96 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -153,7 +153,7 @@ GEM devise_invitable (2.0.8) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.2.4) + distributed-press-api-client (0.3.0rc0) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema @@ -595,7 +595,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.2.3) + distributed-press-api-client (~> 0.3.0rc0) dotenv-rails down ed25519 From c9866a0eecfca61d5c3136ffa412045687728dc3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 15:33:48 -0300 Subject: [PATCH 53/86] =?UTF-8?q?fix:=20mover=20m=C3=A9todos=20a=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy.rb | 36 ++++++++++++++++++++++++++++++++++++ app/models/deploy_local.rb | 36 ------------------------------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index abf5591f..c01a378f 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -55,6 +55,28 @@ class Deploy < ApplicationRecord @gems_dir ||= Rails.root.join('_storage', 'gems', site.name) end + # Un entorno que solo tiene lo que necesitamos + # + # @return [Hash] + def env + # XXX: This doesn't support Windows paths :B + paths = [File.dirname(`which bundle`), '/usr/local/bin', '/usr/bin', '/bin'] + + # Las variables de entorno extra no pueden superponerse al local. + extra_env.merge({ + 'HOME' => home_dir, + 'PATH' => paths.join(':'), + 'SPREE_API_KEY' => site.tienda_api_key, + 'SPREE_URL' => site.tienda_url, + 'AIRBRAKE_PROJECT_ID' => site.id.to_s, + 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, + 'JEKYLL_ENV' => Rails.env, + 'LANG' => ENV['LANG'], + 'YARN_CACHE_FOLDER' => yarn_cache_dir, + 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] + }) + end + # Corre un comando, lo registra en la base de datos y devuelve el # estado. # @@ -142,4 +164,18 @@ class Deploy < ApplicationRecord def non_local_deploys @non_local_deploys ||= site.deploys.where.not(type: 'DeployLocal') end + + # Consigue todas las variables de entorno configuradas por otros + # deploys. + # + # @deprecated Solo tenía sentido para Distributed Press v0 + # @return [Hash] + def extra_env + @extra_env ||= + non_local_deploys.reduce({}) do |extra_env, deploy| + extra_env.tap do |e| + e.merge! deploy.local_env + end + end + end end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 9228581f..edf85bf5 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -68,28 +68,6 @@ class DeployLocal < Deploy FileUtils.mkdir_p destination end - # Un entorno que solo tiene lo que necesitamos - # - # @return [Hash] - def env - # XXX: This doesn't support Windows paths :B - paths = [File.dirname(`which bundle`), '/usr/local/bin', '/usr/bin', '/bin'] - - # Las variables de entorno extra no pueden superponerse al local. - extra_env.merge({ - 'HOME' => home_dir, - 'PATH' => paths.join(':'), - 'SPREE_API_KEY' => site.tienda_api_key, - 'SPREE_URL' => site.tienda_url, - 'AIRBRAKE_PROJECT_ID' => site.id.to_s, - 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, - 'JEKYLL_ENV' => Rails.env, - 'LANG' => ENV['LANG'], - 'YARN_CACHE_FOLDER' => yarn_cache_dir, - 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] - }) - end - def yarn_cache_dir Rails.root.join('_yarn_cache').to_s end @@ -160,20 +138,6 @@ class DeployLocal < Deploy FileUtils.rm_rf destination end - # Consigue todas las variables de entorno configuradas por otros - # deploys. - # - # @deprecated Solo tenía sentido para Distributed Press v0 - # @return [Hash] - def extra_env - @extra_env ||= - non_local_deploys.reduce({}) do |extra_env, deploy| - extra_env.tap do |e| - e.merge! deploy.local_env - end - end - end - # Genera opciones extra desde los otros deploys # # @param :args [Hash] From f337e4967b1ac422062b696a8fc705f9f49d9e34 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 16:40:33 -0300 Subject: [PATCH 54/86] fix: recolectar variables de entorno --- app/models/deploy.rb | 17 ++--------------- app/models/deploy_local.rb | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index c01a378f..55ec46f6 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -66,14 +66,8 @@ class Deploy < ApplicationRecord extra_env.merge({ 'HOME' => home_dir, 'PATH' => paths.join(':'), - 'SPREE_API_KEY' => site.tienda_api_key, - 'SPREE_URL' => site.tienda_url, - 'AIRBRAKE_PROJECT_ID' => site.id.to_s, - 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, 'JEKYLL_ENV' => Rails.env, 'LANG' => ENV['LANG'], - 'YARN_CACHE_FOLDER' => yarn_cache_dir, - 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] }) end @@ -161,21 +155,14 @@ class Deploy < ApplicationRecord @deploy_local ||= site.deploys.find_by(type: 'DeployLocal') end - def non_local_deploys - @non_local_deploys ||= site.deploys.where.not(type: 'DeployLocal') - end - # Consigue todas las variables de entorno configuradas por otros # deploys. # - # @deprecated Solo tenía sentido para Distributed Press v0 # @return [Hash] def extra_env @extra_env ||= - non_local_deploys.reduce({}) do |extra_env, deploy| - extra_env.tap do |e| - e.merge! deploy.local_env - end + site.deployment_list.reduce({}) do |extra, deploy| + extra.merge deploy.local_env end end end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index edf85bf5..0bb3958f 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -62,6 +62,20 @@ class DeployLocal < Deploy FileUtils.rm_rf(File.join(site.path, '.jekyll-cache')) end + # Opciones necesarias para la compilación del sitio + # + # @return [Hash] + def local_env + @local_env ||= { + 'SPREE_API_KEY' => site.tienda_api_key, + 'SPREE_URL' => site.tienda_url, + 'AIRBRAKE_PROJECT_ID' => site.id.to_s, + 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, + 'YARN_CACHE_FOLDER' => yarn_cache_dir, + 'GEMS_SOURCE' => ENV['GEMS_SOURCE'] + } + end + private def mkdir @@ -143,7 +157,7 @@ class DeployLocal < Deploy # @param :args [Hash] # @return [String] def extra_flags(**args) - non_local_deploys.map do |deploy| + site.deployment_list.map do |deploy| deploy.flags_for_build(**args) end.compact.join(' ') end From cd7c21792063c815adb4886540d6a64fe9c0ecf3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 30 Aug 2023 17:17:04 -0300 Subject: [PATCH 55/86] fix: poder asignar valor por defecto a los campos boolean --- app/models/metadata_boolean.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/metadata_boolean.rb b/app/models/metadata_boolean.rb index 90c002a7..9932c6fd 100644 --- a/app/models/metadata_boolean.rb +++ b/app/models/metadata_boolean.rb @@ -4,8 +4,12 @@ # # Esto es increíblemente difícil de lograr que salga bien! class MetadataBoolean < MetadataTemplate + # El valor por defecto es una versión booleana de lo que diga (o no + # diga) el esquema + # + # @return [Boolean] def default_value - false + !!super end # Los checkboxes son especiales porque la especificación de HTML From d8e21c97e2efcc6ffbfdc294119545b58b538cd0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:41:34 -0300 Subject: [PATCH 56/86] fix: solo vincular urls que tienen protocolo --- app/controllers/build_stats_controller.rb | 7 ++++++- app/jobs/deploy_job.rb | 6 +++++- app/mailers/deploy_mailer.rb | 2 +- app/views/build_stats/index.haml | 2 +- app/views/deploy_mailer/deployed.html.haml | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/controllers/build_stats_controller.rb b/app/controllers/build_stats_controller.rb index 31a4c5d6..6961cf45 100644 --- a/app/controllers/build_stats_controller.rb +++ b/app/controllers/build_stats_controller.rb @@ -22,7 +22,12 @@ class BuildStatsController < ApplicationController @table = site.deployment_list.map do |deploy| type = deploy.class.name.underscore - urls = deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact + urls = (deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact).map do |url| + URI.parse(url) + rescue URI::Error + nil + end.compact + urls = [nil] if urls.empty? build_stat = deploy.build_stats.where(status: true).last seconds = build_stat&.seconds || 0 diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index a5cda360..6f486f29 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -51,7 +51,11 @@ class DeployJob < ApplicationJob status = d.deploy(output: @output) seconds = d.build_stats.last.try(:seconds) || 0 size = d.size - urls = d.respond_to?(:urls) ? d.urls : [d.url].compact + urls = (d.respond_to?(:urls) ? d.urls : [d.url].compact).map do |url| + URI.parse url + rescue URI::Error + nil + end.compact rescue StandardError => e status = false seconds ||= 0 diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index b7b464cb..37748b42 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -52,7 +52,7 @@ class DeployMailer < ApplicationMailer t << (row.map do |k, v| case k when :seconds then v[:human] - when :urls then url + when :urls then url.to_s else v end end) diff --git a/app/views/build_stats/index.haml b/app/views/build_stats/index.haml index 27c063f9..0b0e7755 100644 --- a/app/views/build_stats/index.haml +++ b/app/views/build_stats/index.haml @@ -14,7 +14,7 @@ - row[:urls].each do |url| %tr %th{ scope: 'row' }= row[:title] - %td= link_to_if url.present?, url, url, class: 'word-break-all' + %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s, class: 'word-break-all' %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index f5afe5de..b3463db6 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -13,7 +13,7 @@ %tr %td= row[:title] %td= row[:status] - %td= link_to_if url.present?, url, url + %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From f076838be5137821ca2a2ca18f9e89c53047ea5f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:47:44 -0300 Subject: [PATCH 57/86] fixup! fix: solo vincular urls que tienen protocolo --- app/jobs/deploy_job.rb | 2 +- app/views/deploy_mailer/deployed.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 6f486f29..00ae7585 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -70,7 +70,7 @@ class DeployJob < ApplicationJob status: status, seconds: seconds, size: size, - urls: urls + urls: urls.map(&:to_s) } end diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index b3463db6..762bf4db 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -13,7 +13,7 @@ %tr %td= row[:title] %td= row[:status] - %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s + %td= link_to_if (url.present? && url.scheme.present?), url.to_s, url.to_s %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From a6195fbcccf80e47245429228f6631b9139aced4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:52:49 -0300 Subject: [PATCH 58/86] fix: simplificar --- app/controllers/build_stats_controller.rb | 2 +- app/jobs/deploy_job.rb | 2 +- app/models/deploy.rb | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/build_stats_controller.rb b/app/controllers/build_stats_controller.rb index 6961cf45..339f17f0 100644 --- a/app/controllers/build_stats_controller.rb +++ b/app/controllers/build_stats_controller.rb @@ -22,7 +22,7 @@ class BuildStatsController < ApplicationController @table = site.deployment_list.map do |deploy| type = deploy.class.name.underscore - urls = (deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact).map do |url| + urls = deploy.urls.map do |url| URI.parse(url) rescue URI::Error nil diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 00ae7585..0870b827 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -51,7 +51,7 @@ class DeployJob < ApplicationJob status = d.deploy(output: @output) seconds = d.build_stats.last.try(:seconds) || 0 size = d.size - urls = (d.respond_to?(:urls) ? d.urls : [d.url].compact).map do |url| + urls = d.urls.map do |url| URI.parse url rescue URI::Error nil diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 55ec46f6..811047f1 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -23,6 +23,11 @@ class Deploy < ApplicationRecord raise NotImplementedError end + # @return [Array] + def urls + [url].compact + end + def limit raise NotImplementedError end From 927f92d985e7b1af86424cb332e48f900d988a83 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:56:00 -0300 Subject: [PATCH 59/86] fix: typo --- app/views/build_stats/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/build_stats/index.haml b/app/views/build_stats/index.haml index 0b0e7755..de04d84d 100644 --- a/app/views/build_stats/index.haml +++ b/app/views/build_stats/index.haml @@ -14,7 +14,7 @@ - row[:urls].each do |url| %tr %th{ scope: 'row' }= row[:title] - %td= link_to_if (url.present? && uri.scheme.present?), url.to_s, url.to_s, class: 'word-break-all' + %td= link_to_if (url.present? && url.scheme.present?), url.to_s, url.to_s, class: 'word-break-all' %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From 3dedd84db78512e017706cd90610318c677879d4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 31 Aug 2023 14:58:16 -0300 Subject: [PATCH 60/86] fix: enviar urls parseadas --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 0870b827..291991c7 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -70,7 +70,7 @@ class DeployJob < ApplicationJob status: status, seconds: seconds, size: size, - urls: urls.map(&:to_s) + urls: urls } end From 6aa0f7d6cf6a54f4f0cee94d27d3c8206a849c86 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 1 Sep 2023 20:11:46 -0300 Subject: [PATCH 61/86] =?UTF-8?q?feat:=20guardar=20la=20fecha=20de=20creac?= =?UTF-8?q?i=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/post.rb b/app/models/post.rb index 5cc1c5ea..6265a313 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -267,6 +267,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq + yaml['created_at'] ||= Time.now yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 10d958e50aed0f92dfae7140bde7650d371b1d22 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Sep 2023 12:44:57 -0300 Subject: [PATCH 62/86] =?UTF-8?q?fix:=20compartir=20la=20misma=20fecha=20d?= =?UTF-8?q?e=20creaci=C3=B3n=20y=20de=20actualizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index 6265a313..f31c33b6 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -267,7 +267,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq - yaml['created_at'] ||= Time.now + yaml['created_at'] ||= modified_at yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 8ae5dd597501d81d4e266bedbbf62edbe7778761 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Sep 2023 14:49:17 -0300 Subject: [PATCH 63/86] fix: no compartir la misma instancia sutty/jekyll/jekyll-activitypub#42 --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index f31c33b6..36a0b02e 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -267,7 +267,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq - yaml['created_at'] ||= modified_at + yaml['created_at'] ||= modified_at.dup yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 6b1eccade35aec862160950549123f59be7d1fe7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 17:52:21 -0300 Subject: [PATCH 64/86] =?UTF-8?q?feat:=20fecha=20de=20creaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_created_at.rb | 14 ++++++++++++++ app/models/post.rb | 8 ++++++-- app/views/posts/attribute_ro/_created_at.haml | 4 ++++ app/views/posts/attributes/_created_at.haml | 1 + config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 6 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 app/models/metadata_created_at.rb create mode 100644 app/views/posts/attribute_ro/_created_at.haml create mode 100644 app/views/posts/attributes/_created_at.haml diff --git a/app/models/metadata_created_at.rb b/app/models/metadata_created_at.rb new file mode 100644 index 00000000..2a7c07ed --- /dev/null +++ b/app/models/metadata_created_at.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Fecha y hora de creación +class MetadataCreatedAt < MetadataTemplate + # Por defecto la hora actual + def default_value + Time.now + end + + # Nunca cambia + def value=(new_value) + value + end +end diff --git a/app/models/post.rb b/app/models/post.rb index 36a0b02e..8bd5dab3 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -12,7 +12,7 @@ class Post DEFAULT_ATTRIBUTES = %i[site document layout].freeze # Otros atributos que no vienen en los metadatos PRIVATE_ATTRIBUTES = %i[path slug attributes errors].freeze - PUBLIC_ATTRIBUTES = %i[lang date uuid].freeze + PUBLIC_ATTRIBUTES = %i[lang date uuid created_at].freeze ATTR_SUFFIXES = %w[? =].freeze attr_reader :attributes, :errors, :layout, :site, :document @@ -217,6 +217,11 @@ class Post post: self, required: true) end + # La fecha de creación inmodificable del post + def created_at + @metadata[:created_at] ||= MetadataCreatedAt.new(document: document, site: site, layout: layout, name: :created_at, type: :timestamp, post: self, required: true) + end + # Detecta si es un atributo válido o no, a partir de la tabla de la # plantilla def attribute?(mid) @@ -267,7 +272,6 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq - yaml['created_at'] ||= modified_at.dup yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" diff --git a/app/views/posts/attribute_ro/_created_at.haml b/app/views/posts/attribute_ro/_created_at.haml new file mode 100644 index 00000000..04f6d716 --- /dev/null +++ b/app/views/posts/attribute_ro/_created_at.haml @@ -0,0 +1,4 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ dir: dir, lang: locale } + %time{ datetime: metadata.value.xmlschema }= l metadata.value diff --git a/app/views/posts/attributes/_created_at.haml b/app/views/posts/attributes/_created_at.haml new file mode 100644 index 00000000..0aab9802 --- /dev/null +++ b/app/views/posts/attributes/_created_at.haml @@ -0,0 +1 @@ +-# nada diff --git a/config/locales/en.yml b/config/locales/en.yml index 0dad2e68..5c00701c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -524,6 +524,8 @@ en: feedback: 'This field cannot be empty!' uuid: label: 'Unique identifier' + created_at: + label: 'Created at' geo: uri: 'Open in app' osm: 'Open in web map' diff --git a/config/locales/es.yml b/config/locales/es.yml index d899b99c..0ff7e1c8 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -532,6 +532,8 @@ es: feedback: '¡Este campo no puede estar vacío!' uuid: label: 'Identificador único' + created_at: + label: 'Fecha de creación' geo: uri: 'Abrir en aplicación' osm: 'Abrir en mapa web' From 35e8a087163683c77de16fd398006d8b71c5bec8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 17:53:51 -0300 Subject: [PATCH 65/86] =?UTF-8?q?fixup!=20feat:=20fecha=20de=20creaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/post.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/post.rb b/app/models/post.rb index 8bd5dab3..73785cad 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -219,7 +219,7 @@ class Post # La fecha de creación inmodificable del post def created_at - @metadata[:created_at] ||= MetadataCreatedAt.new(document: document, site: site, layout: layout, name: :created_at, type: :timestamp, post: self, required: true) + @metadata[:created_at] ||= MetadataCreatedAt.new(document: document, site: site, layout: layout, name: :created_at, type: :created_at, post: self, required: true) end # Detecta si es un atributo válido o no, a partir de la tabla de la From d27717ed3b7a21413361e86030ef59f4c3b84b3c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 17:59:50 -0300 Subject: [PATCH 66/86] fix: agregar created_at al front matter --- app/models/post.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/post.rb b/app/models/post.rb index 73785cad..fab9ab06 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -272,6 +272,7 @@ class Post # Y que no se procese liquid yaml['liquid'] = false yaml['usuaries'] = usuaries.map(&:id).uniq + yaml['created_at'] = created_at.value yaml['last_modified_at'] = modified_at "#{yaml.to_yaml}---\n\n#{body}" From 99c919e5e6cfca0e6affcd138da52a0565b6fd32 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Sep 2023 18:07:25 -0300 Subject: [PATCH 67/86] fix: retrocompatibilidad --- app/models/metadata_created_at.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/models/metadata_created_at.rb b/app/models/metadata_created_at.rb index 2a7c07ed..d31b3a1c 100644 --- a/app/models/metadata_created_at.rb +++ b/app/models/metadata_created_at.rb @@ -2,9 +2,14 @@ # Fecha y hora de creación class MetadataCreatedAt < MetadataTemplate - # Por defecto la hora actual + # Por defecto la hora actual, pero por retrocompatibilidad, queremos + # la fecha de publicación def default_value - Time.now + if post.date.value.to_date < Time.now.to_date + post.date.value + else + Time.now + end end # Nunca cambia From a2d84bfa96a375bd8c0ce79cda4a2ec20f0f5e9d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 12:25:23 -0300 Subject: [PATCH 68/86] fix: renombrar el remote correctamente --- app/models/site.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 0fddeff5..fa1d7b46 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -473,7 +473,10 @@ class Site < ApplicationRecord def clone_skel! return if jekyll? - Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path, remote: 'upstream' + Rugged::Repository.clone_at ENV['SKEL_SUTTY'], path + + # Necesita un bloque + repository.rugged.remotes.rename('origin', 'upstream') {} end # Elimina el directorio del sitio From 69e1664084cd2b1cfb4fa71dfee745883f546c2d Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:02:15 -0300 Subject: [PATCH 69/86] fix: renombrar todos los repositorios remotos --- ...921155401_site_rename_origin_to_upstream.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 db/migrate/20230921155401_site_rename_origin_to_upstream.rb diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb new file mode 100644 index 00000000..c27d7747 --- /dev/null +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Renombrar todos los repositorios que apunten a skel como su origin +class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] + # Renombrar + def up + Site.find_each do |site| + next unless site.repository.origin&.url == ENV['SKEL_SUTTY'] + + site.repository.rugged.remotes.rename('origin', 'upstream') + rescue Rugged::Error => e + Rails.logger.warn "#{site.name}: #{e.message}" + end + end + + # No se puede deshacer + def down; end +end From e4dc6588f925756d9523b6d344668c099f17b382 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:04:25 -0300 Subject: [PATCH 70/86] =?UTF-8?q?fix:=20informar=20qu=C3=A9=20est=C3=A1=20?= =?UTF-8?q?pasando?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20230921155401_site_rename_origin_to_upstream.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb index c27d7747..e32ca6fc 100644 --- a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -8,6 +8,7 @@ class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] next unless site.repository.origin&.url == ENV['SKEL_SUTTY'] site.repository.rugged.remotes.rename('origin', 'upstream') + Rails.logger.info "#{site.name}: renamed origin to upstream" rescue Rugged::Error => e Rails.logger.warn "#{site.name}: #{e.message}" end From 7709b9f79803ccdda400526f5b2dfb9f49ad6cc8 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:09:10 -0300 Subject: [PATCH 71/86] =?UTF-8?q?fix:=20capturar=20m=C3=A1s=20errores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20230921155401_site_rename_origin_to_upstream.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb index e32ca6fc..4ad53f1b 100644 --- a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -9,7 +9,7 @@ class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] site.repository.rugged.remotes.rename('origin', 'upstream') Rails.logger.info "#{site.name}: renamed origin to upstream" - rescue Rugged::Error => e + rescue Rugged::Error, Rugged::OSError => e Rails.logger.warn "#{site.name}: #{e.message}" end end From b06b829357a607a9567d75fbf3bded07d7002a53 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Sep 2023 13:10:26 -0300 Subject: [PATCH 72/86] fix: necesita un bloque --- db/migrate/20230921155401_site_rename_origin_to_upstream.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb index 4ad53f1b..864f4c4a 100644 --- a/db/migrate/20230921155401_site_rename_origin_to_upstream.rb +++ b/db/migrate/20230921155401_site_rename_origin_to_upstream.rb @@ -7,8 +7,9 @@ class SiteRenameOriginToUpstream < ActiveRecord::Migration[6.1] Site.find_each do |site| next unless site.repository.origin&.url == ENV['SKEL_SUTTY'] - site.repository.rugged.remotes.rename('origin', 'upstream') - Rails.logger.info "#{site.name}: renamed origin to upstream" + site.repository.rugged.remotes.rename('origin', 'upstream') do |_| + Rails.logger.info "#{site.name}: renamed origin to upstream" + end rescue Rugged::Error, Rugged::OSError => e Rails.logger.warn "#{site.name}: #{e.message}" end From 84f82cbb0fccde12f51cc69678ccdafe151b96b3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 12:21:55 -0300 Subject: [PATCH 73/86] fix: obtener el usuario del repositorio --- Gemfile | 1 + Gemfile.lock | 4 ++++ app/models/site/repository.rb | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index dd880219..6edeac5a 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,7 @@ gem 'redis-rails' gem 'rollups', git: 'https://github.com/fauno/rollup.git', branch: 'update' gem 'rubyzip' gem 'rugged' +gem 'git_clone_url' gem 'concurrent-ruby-ext' gem 'que' gem 'symbol-fstring', require: 'fstring/all' diff --git a/Gemfile.lock b/Gemfile.lock index f71053d7..9549a51d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -217,6 +217,8 @@ GEM activerecord (>= 4.0.0) get_process_mem (0.2.7) ffi (~> 1.0) + git_clone_url (2.0.0) + uri-ssh_git (>= 2.0) globalid (1.1.0) activesupport (>= 5.0) groupdate (6.2.1) @@ -553,6 +555,7 @@ GEM unf_ext unf_ext (0.0.8.2-x86_64-linux-musl) unicode-display_width (1.8.0) + uri-ssh_git (2.0.0) validates_hostname (1.0.13) activerecord (>= 3.0) activesupport (>= 3.0) @@ -606,6 +609,7 @@ DEPENDENCIES fast_jsonparser (~> 0.5.0) flamegraph friendly_id + git_clone_url hairtrigger haml-lint hamlit-rails diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 74d874c1..d776efa4 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -173,7 +173,21 @@ class Site def credentials return unless File.exist? private_key - @credentials ||= Rugged::Credentials::SshKey.new username: 'git', publickey: public_key, privatekey: private_key + @credentials ||= + begin + username = parse_url(origin.url)&.user || 'git' + + Rugged::Credentials::SshKey.new username: username, publickey: public_key, privatekey: private_key + end + end + + # @param :url [String] + # @return [URI, nil] + def parse_url(url) + GitCloneUrl.parse(url) + rescue URI::Error => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, url: url }) + nil end # @return [String] From 0c7a37a1d82e7035b05cfb4fb96614c36fd38369 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 12:46:32 -0300 Subject: [PATCH 74/86] fix: mantener rugged 1.5.0.1 versiones posteriores se rompen con urls ssh:// https://github.com/libgit2/libgit2/issues/6496 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 6edeac5a..ce776647 100644 --- a/Gemfile +++ b/Gemfile @@ -69,7 +69,7 @@ gem 'redis', '~> 4.0', require: %w[redis redis/connection/hiredis] gem 'redis-rails' gem 'rollups', git: 'https://github.com/fauno/rollup.git', branch: 'update' gem 'rubyzip' -gem 'rugged' +gem 'rugged', '1.5.0.1' gem 'git_clone_url' gem 'concurrent-ruby-ext' gem 'que' diff --git a/Gemfile.lock b/Gemfile.lock index 9549a51d..11561776 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -496,7 +496,7 @@ GEM ruby_parser (3.20.1) sexp_processor (~> 4.16) rubyzip (2.3.2) - rugged (1.6.3-x86_64-linux-musl) + rugged (1.5.0.1-x86_64-linux-musl) safe_yaml (1.0.6) safely_block (0.3.0) errbase (>= 0.1.1) @@ -654,7 +654,7 @@ DEPENDENCIES rollups! rubocop-rails rubyzip - rugged + rugged (= 1.5.0.1) safe_yaml safely_block (~> 0.3.0) sassc-rails From 52e22a53bfd3f8bed30a01820ca522304384b619 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 12:47:18 -0300 Subject: [PATCH 75/86] fix: no sabemos el sitio --- app/models/site/repository.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index d776efa4..128a557a 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -186,7 +186,7 @@ class Site def parse_url(url) GitCloneUrl.parse(url) rescue URI::Error => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, url: url }) + ExceptionNotifier.notify_exception(e, data: { path: path, url: url }) nil end From 7793c5f96d63bad20243b6eb3bb0d8bc79e92e6d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 13:03:28 -0300 Subject: [PATCH 76/86] =?UTF-8?q?fix:=20no=20enviar=20el=20env=20en=20la?= =?UTF-8?q?=20notificaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/webhooks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/webhooks_controller.rb b/app/controllers/api/v1/webhooks_controller.rb index 1730034e..36e6a6d1 100644 --- a/app/controllers/api/v1/webhooks_controller.rb +++ b/app/controllers/api/v1/webhooks_controller.rb @@ -68,7 +68,7 @@ module Api # respuesta de error a plataformas def platforms_answer(exception) - ExceptionNotifier.notify_exception(exception, env: request.env, data: { headers: request.headers.to_h }) + ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h } head :forbidden end From c176a8a4b44b5b62ffe01fb7708c39abf4eecbd9 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 13:19:21 -0300 Subject: [PATCH 77/86] feat: poder obtener el usuario de cualquier remoto --- app/models/site/repository.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 128a557a..119a1495 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -173,12 +173,18 @@ class Site def credentials return unless File.exist? private_key - @credentials ||= - begin - username = parse_url(origin.url)&.user || 'git' + Rugged::Credentials::SshKey.new username: username_for(origin), publickey: public_key, privatekey: private_key + end - Rugged::Credentials::SshKey.new username: username, publickey: public_key, privatekey: private_key - end + # Obtiene el nombre de usuario para el repositorio remoto, por + # defecto git + # + # @param :remote [Rugged::Remote] + # @return [String] + def username_for(remote) + username = parse_url(remote.url)&.user if remote.respond_to? :url + + username || 'git' end # @param :url [String] From aeaf72c27036753b52087acac6c2fd523e923f78 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Sep 2023 13:20:20 -0300 Subject: [PATCH 78/86] feat: poder pushear a cualquier remoto --- app/models/site/repository.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 119a1495..2eafb92e 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -158,22 +158,29 @@ class Site # Pushea cambios al repositorio remoto # + # @param :remote [Rugged::Remote] # @return [Boolean, nil] - def push - origin.push(rugged.head.canonical_name, credentials: credentials) - git_sh("git", "lfs", "push", "origin", default_branch) + def push(remote = origin) + remote.push(rugged.head.canonical_name, credentials: credentials_for(remote)) + git_sh('git', 'lfs', 'push', remote.name, default_branch) end private + # @deprecated + def credentials + @credentials ||= credentials_for(origin) + end + # Si Sutty tiene una llave privada de tipo ED25519, devuelve las # credenciales necesarias para trabajar con repositorios remotos. # + # @param :remote [Rugged::Remote] # @return [Nil, Rugged::Credentials::SshKey] - def credentials + def credentials_for(remote) return unless File.exist? private_key - Rugged::Credentials::SshKey.new username: username_for(origin), publickey: public_key, privatekey: private_key + Rugged::Credentials::SshKey.new username: username_for(remote), publickey: public_key, privatekey: private_key end # Obtiene el nombre de usuario para el repositorio remoto, por From de59cd9f34b8e346df111643f11482df9647bd15 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:08:37 -0300 Subject: [PATCH 79/86] fix: informar cuando la plantilla no tiene gema #14309 --- config/initializers/core_extensions.rb | 14 ++++++++++++++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + 3 files changed, 16 insertions(+) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 1516a43a..837fbd18 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -91,6 +91,15 @@ module Jekyll spec.name == name end + unless spec + I18n.with_locale(locale) do + raise ArgumentError, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { theme: name, site: site.path }) + raise + end + end + ruby_version = Gem::Version.new(RUBY_VERSION) ruby_version.canonical_segments[2] = 0 base_path = Rails.root.join('_storage', 'gems', File.basename(site.source), 'ruby', @@ -114,6 +123,11 @@ module Jekyll private def gemspec; end + + # @return [Symbol] + def locale + @locale ||= (site.config['locale'] || site.config['lang'] || I18n.locale).to_sym + end end # No necesitamos los archivos de la plantilla diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..56b8c213 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -191,6 +191,7 @@ en: deploys: deploy_local_presence: 'We need to be build the site!' design_id: + missing_gem: "Site is configured to use %{theme} theme, but the corresponding gem is missing from Gemfile" layout_incompatible: error: "Design can't be changed because there are posts with incompatible layouts" help: "Your site has posts with layouts only compatible with the current design. If you change it, the site won't work as you expect. If you're trying out designs, you can delete posts in the following incompatible layouts:: %{layouts}." diff --git a/config/locales/es.yml b/config/locales/es.yml index 9e0b8945..b4fde8a3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -191,6 +191,7 @@ es: deploys: deploy_local_presence: '¡Necesitamos poder generar el sitio!' design_id: + missing_gem: "El sitio usa la plantilla %{theme} pero la gema correspondiente no se encuentra en el Gemfile" layout_incompatible: error: 'No se puede cambiar la plantilla porque hay artículos con formatos incompatibles' help: 'En tu sitio hay artículos que solo son compatibles con el diseño actual, si cambias la plantilla el sitio no funcionará como esperas. Si estás probando plantillas, puedes eliminar los artículos en los formatos incompatibles: %{layouts}.' From 01e7436576c1060d38dd47a0ef0e4aca656c02f8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:10:34 -0300 Subject: [PATCH 80/86] fix: obtener el nombre del sitio --- config/initializers/core_extensions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 837fbd18..2e9ed7e1 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -95,7 +95,7 @@ module Jekyll I18n.with_locale(locale) do raise ArgumentError, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { theme: name, site: site.path }) + ExceptionNotifier.notify_exception(e, data: { theme: name, site: File.basename(site.source) }) raise end end From bfd31d051fb002e303ddcd0f253b1e2a7aa50f49 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 25 Sep 2023 14:15:32 -0300 Subject: [PATCH 81/86] =?UTF-8?q?fix:=20lanzar=20una=20excepci=C3=B3n=20co?= =?UTF-8?q?ntundente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/initializers/core_extensions.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 2e9ed7e1..d6039e16 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -93,8 +93,8 @@ module Jekyll unless spec I18n.with_locale(locale) do - raise ArgumentError, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) - rescue ArgumentError => e + raise Jekyll::Errors::InvalidThemeName, I18n.t('activerecord.errors.models.site.attributes.design_id.missing_gem', theme: name) + rescue Jekyll::Errors::InvalidThemeName => e ExceptionNotifier.notify_exception(e, data: { theme: name, site: File.basename(site.source) }) raise end From 59f8f8aabbab3ef93572dacae14e56ea724364c8 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 27 Sep 2023 14:29:28 -0300 Subject: [PATCH 82/86] fix: arreglado typo en breadcrumbs en en.yml #13864 --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f97a8b9..6b73205a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -685,7 +685,7 @@ en: new: 'Create' edit: 'Configure' posts: - new: 'New %{layout}' + new: 'Add %{layout}' edit: 'Editing' usuaries: index: 'Users' From 134d1105f62256b23d64ff4fb88582a880882ec9 Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 27 Sep 2023 15:48:53 -0300 Subject: [PATCH 83/86] =?UTF-8?q?fix:=20agregada=20la=20fecha=20de=20creac?= =?UTF-8?q?ion=20del=20post=20para=20seleccionar=20posts=20por=20t=C3=ADtu?= =?UTF-8?q?lo=20si=20est=C3=A1n=20duplicados=20#14179?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_related_posts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index 092f219a..f20ea85c 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -34,7 +34,7 @@ class MetadataRelatedPosts < MetadataArray end def title(post) - "#{post&.title&.value || post&.slug&.value} (#{post.layout.humanized_name})" + "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.trftime('%F')} (#{post.layout.humanized_name})" end # Encuentra el filtro From 5e05ba7d7b4dcffbb05bf54a2276619ea4de366f Mon Sep 17 00:00:00 2001 From: jazzari Date: Wed, 27 Sep 2023 15:52:33 -0300 Subject: [PATCH 84/86] fix: fix typo #14179 --- app/models/metadata_related_posts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index f20ea85c..25eb3fd1 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -34,7 +34,7 @@ class MetadataRelatedPosts < MetadataArray end def title(post) - "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.trftime('%F')} (#{post.layout.humanized_name})" + "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.strftime('%F')} (#{post.layout.humanized_name})" end # Encuentra el filtro From cb2c1b0e7daeab32fdc3f01fca9f7158eaf6918e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 29 Sep 2023 10:10:18 -0300 Subject: [PATCH 85/86] =?UTF-8?q?fix:=20usar=20la=20codificaci=C3=B3n=20co?= =?UTF-8?q?rrecta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit los archivos con tildes fallaban --- app/models/site/index.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/models/site/index.rb b/app/models/site/index.rb index 06c8821b..6f4714c6 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -108,11 +108,14 @@ class Site end # Obtiene el idioma y la ruta del post a partir de la ubicación en - # el disco + # el disco. + # + # Las rutas vienen en ASCII-9BIT desde Rugged, pero en realidad + # son UTF-8 # # @return [Array] def locale_and_path_from(path) - locale, path = path.split(File::SEPARATOR, 2) + locale, path = path.force_encoding('utf-8').split(File::SEPARATOR, 2) [ locale.sub(LOCALE_FROM_PATH, ''), From 86436aafd70ba21b385e40b5b07a4001552adf64 Mon Sep 17 00:00:00 2001 From: jazzari Date: Mon, 2 Oct 2023 14:36:36 -0300 Subject: [PATCH 86/86] fix: typo en metadata_related_posts.rb #14179 --- app/models/metadata_related_posts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_related_posts.rb b/app/models/metadata_related_posts.rb index 25eb3fd1..42d1381b 100644 --- a/app/models/metadata_related_posts.rb +++ b/app/models/metadata_related_posts.rb @@ -34,7 +34,7 @@ class MetadataRelatedPosts < MetadataArray end def title(post) - "#{post&.title&.value || post&.slug&.value} #{post&.date&.values.strftime('%F')} (#{post.layout.humanized_name})" + "#{post&.title&.value || post&.slug&.value} #{post&.date&.value.strftime('%F')} (#{post.layout.humanized_name})" end # Encuentra el filtro