diff --git a/app/models/activity_pub/activity.rb b/app/models/activity_pub/activity.rb index ee555474..af005ff3 100644 --- a/app/models/activity_pub/activity.rb +++ b/app/models/activity_pub/activity.rb @@ -21,7 +21,7 @@ class ActivityPub validates :activity_pub_id, presence: true # Las actividades son únicas con respecto a su estado - validates :uri, presence: true, uniqueness: { scope: :activity_pub_id, message: 'estado duplicado' } + validates :uri, presence: true, url: true, uniqueness: { scope: :activity_pub_id, message: 'estado duplicado' } # Siempre en orden descendiente para saber el último estado default_scope -> { order(created_at: :desc) } diff --git a/app/models/activity_pub/actor.rb b/app/models/activity_pub/actor.rb index 919bc5e0..b03145e7 100644 --- a/app/models/activity_pub/actor.rb +++ b/app/models/activity_pub/actor.rb @@ -16,7 +16,7 @@ class ActivityPub has_many :remote_flags # Les actores son únicxs a toda la base de datos - validates :uri, presence: true, uniqueness: true + validates :uri, presence: true, url: true, uniqueness: true # Obtiene el nombre de la Actor como mención, solo si obtuvimos el # contenido de antemano. diff --git a/app/models/activity_pub/object.rb b/app/models/activity_pub/object.rb index 15b07bee..3fde326b 100644 --- a/app/models/activity_pub/object.rb +++ b/app/models/activity_pub/object.rb @@ -6,7 +6,7 @@ class ActivityPub include ActivityPub::Concerns::JsonLdConcern # Los objetos son únicos a toda la base de datos - validates :uri, presence: true, uniqueness: true + validates :uri, presence: true, url: true, uniqueness: true has_many :activity_pubs, as: :object diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb new file mode 100644 index 00000000..291f9288 --- /dev/null +++ b/app/validators/url_validator.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Valida URLs +# +# @see {https://storck.io/posts/better-http-url-validation-in-ruby-on-rails/} +class UrlValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + if value.blank? + record.errors.add(attribute, :url_missing) + return + end + + uri = URI.parse(value) + + record.errors.add(attribute, :scheme_missing) if uri.scheme.blank? + record.errors.add(attribute, :host_missing) if uri.host.blank? + record.errors.add(attribute, :path_missing) if uri.path.blank? + rescue URI::Error + record.errors.add(attribute, :invalid) + end +end