From: J Guthrie Date: Sun, 4 Nov 2018 18:28:27 +0000 (+0000) Subject: Create invalid_char validators and apply to models X-Git-Tag: live~2773^2~9 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/c2f23fea6a7821a4ad4c97fd65744b138ec86267 Create invalid_char validators and apply to models --- diff --git a/app/models/changeset_comment.rb b/app/models/changeset_comment.rb index 756fda14c..232785d95 100644 --- a/app/models/changeset_comment.rb +++ b/app/models/changeset_comment.rb @@ -3,8 +3,8 @@ # Table name: changeset_comments # # id :integer not null, primary key -# changeset_id :integer not null -# author_id :integer not null +# changeset_id :bigint(8) not null +# author_id :bigint(8) not null # body :text not null # created_at :datetime not null # visible :boolean not null @@ -28,7 +28,7 @@ class ChangesetComment < ActiveRecord::Base validates :changeset, :presence => true, :associated => true validates :author, :presence => true, :associated => true validates :visible, :inclusion => [true, false] - validates :body, :format => /\A[^\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff]*\z/ + validates :body, :invalid_chars => true # Return the comment text def body diff --git a/app/models/changeset_tag.rb b/app/models/changeset_tag.rb index 8d6cd45ac..1231fc24f 100644 --- a/app/models/changeset_tag.rb +++ b/app/models/changeset_tag.rb @@ -2,7 +2,7 @@ # # Table name: changeset_tags # -# changeset_id :integer not null, primary key +# changeset_id :bigint(8) not null, primary key # k :string default(""), not null, primary key # v :string default(""), not null # @@ -21,6 +21,6 @@ class ChangesetTag < ActiveRecord::Base belongs_to :changeset validates :changeset, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => :changeset_id } end diff --git a/app/models/diary_comment.rb b/app/models/diary_comment.rb index 63eae3f21..472129b1b 100644 --- a/app/models/diary_comment.rb +++ b/app/models/diary_comment.rb @@ -2,9 +2,9 @@ # # Table name: diary_comments # -# id :integer not null, primary key -# diary_entry_id :integer not null -# user_id :integer not null +# id :bigint(8) not null, primary key +# diary_entry_id :bigint(8) not null +# user_id :bigint(8) not null # body :text not null # created_at :datetime not null # updated_at :datetime not null @@ -28,7 +28,7 @@ class DiaryComment < ActiveRecord::Base scope :visible, -> { where(:visible => true) } - validates :body, :presence => true + validates :body, :presence => true, :invalid_chars => true validates :diary_entry, :user, :associated => true after_save :spam_check diff --git a/app/models/diary_entry.rb b/app/models/diary_entry.rb index 2a24d8002..d4139f652 100644 --- a/app/models/diary_entry.rb +++ b/app/models/diary_entry.rb @@ -2,8 +2,8 @@ # # Table name: diary_entries # -# id :integer not null, primary key -# user_id :integer not null +# id :bigint(8) not null, primary key +# user_id :bigint(8) not null # title :string not null # body :text not null # created_at :datetime not null @@ -37,7 +37,7 @@ class DiaryEntry < ActiveRecord::Base scope :visible, -> { where(:visible => true) } - validates :title, :body, :presence => true + validates :title, :body, :presence => true, :invalid_chars => true validates :title, :length => 1..255 validates :latitude, :allow_nil => true, :numericality => { :greater_than_or_equal_to => -90, diff --git a/app/models/issue_comment.rb b/app/models/issue_comment.rb index 3a5894cb3..2fe96f472 100644 --- a/app/models/issue_comment.rb +++ b/app/models/issue_comment.rb @@ -24,7 +24,7 @@ class IssueComment < ActiveRecord::Base belongs_to :issue belongs_to :user - validates :body, :presence => true + validates :body, :presence => true, :invalid_chars => true validates :user, :presence => true validates :issue, :presence => true end diff --git a/app/models/message.rb b/app/models/message.rb index aff628e03..2447c3b79 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -2,13 +2,13 @@ # # Table name: messages # -# id :integer not null, primary key -# from_user_id :integer not null +# id :bigint(8) not null, primary key +# from_user_id :bigint(8) not null # title :string not null # body :text not null # sent_on :datetime not null # message_read :boolean default(FALSE), not null -# to_user_id :integer not null +# to_user_id :bigint(8) not null # to_user_visible :boolean default(TRUE), not null # from_user_visible :boolean default(TRUE), not null # body_format :enum default("markdown"), not null @@ -32,6 +32,7 @@ class Message < ActiveRecord::Base validates :title, :presence => true, :utf8 => true, :length => 1..255 validates :body, :sent_on, :sender, :recipient, :presence => true + validates :title, :body, :invalid_chars => true def self.from_mail(mail, from, to) if mail.multipart? diff --git a/app/models/node_tag.rb b/app/models/node_tag.rb index 20065b993..d1e800592 100644 --- a/app/models/node_tag.rb +++ b/app/models/node_tag.rb @@ -2,7 +2,7 @@ # # Table name: current_node_tags # -# node_id :integer not null, primary key +# node_id :bigint(8) not null, primary key # k :string default(""), not null, primary key # v :string default(""), not null # @@ -18,6 +18,6 @@ class NodeTag < ActiveRecord::Base belongs_to :node validates :node, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => :node_id } end diff --git a/app/models/note_comment.rb b/app/models/note_comment.rb index 1772b3f97..69a93c532 100644 --- a/app/models/note_comment.rb +++ b/app/models/note_comment.rb @@ -34,7 +34,7 @@ class NoteComment < ActiveRecord::Base validates :author, :associated => true validates :event, :inclusion => %w[opened closed reopened commented hidden] validates :body, :length => { :maximum => 2000 }, - :format => /\A[^\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff]*\z/ + :invalid_chars => true # Return the comment text def body diff --git a/app/models/old_node_tag.rb b/app/models/old_node_tag.rb index 9e03d34f9..f6fb93e17 100644 --- a/app/models/old_node_tag.rb +++ b/app/models/old_node_tag.rb @@ -2,8 +2,8 @@ # # Table name: node_tags # -# node_id :integer not null, primary key -# version :integer not null, primary key +# node_id :bigint(8) not null, primary key +# version :bigint(8) not null, primary key # k :string default(""), not null, primary key # v :string default(""), not null # @@ -19,6 +19,6 @@ class OldNodeTag < ActiveRecord::Base belongs_to :old_node, :foreign_key => [:node_id, :version] validates :old_node, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => [:node_id, :version] } end diff --git a/app/models/old_relation_tag.rb b/app/models/old_relation_tag.rb index 052b60853..3b75e1c82 100644 --- a/app/models/old_relation_tag.rb +++ b/app/models/old_relation_tag.rb @@ -2,10 +2,10 @@ # # Table name: relation_tags # -# relation_id :integer default(0), not null, primary key +# relation_id :bigint(8) default(0), not null, primary key # k :string default(""), not null, primary key # v :string default(""), not null -# version :integer not null, primary key +# version :bigint(8) not null, primary key # # Foreign Keys # @@ -19,6 +19,6 @@ class OldRelationTag < ActiveRecord::Base belongs_to :old_relation, :foreign_key => [:relation_id, :version] validates :old_relation, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => [:relation_id, :version] } end diff --git a/app/models/old_way_tag.rb b/app/models/old_way_tag.rb index 8fffebc25..14043546c 100644 --- a/app/models/old_way_tag.rb +++ b/app/models/old_way_tag.rb @@ -2,10 +2,10 @@ # # Table name: way_tags # -# way_id :integer default(0), not null, primary key +# way_id :bigint(8) default(0), not null, primary key # k :string not null, primary key # v :string not null -# version :integer not null, primary key +# version :bigint(8) not null, primary key # # Foreign Keys # @@ -19,6 +19,6 @@ class OldWayTag < ActiveRecord::Base belongs_to :old_way, :foreign_key => [:way_id, :version] validates :old_way, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => [:way_id, :version] } end diff --git a/app/models/redaction.rb b/app/models/redaction.rb index b835864db..d9a5c6cd7 100644 --- a/app/models/redaction.rb +++ b/app/models/redaction.rb @@ -7,7 +7,7 @@ # description :text # created_at :datetime # updated_at :datetime -# user_id :integer not null +# user_id :bigint(8) not null # description_format :enum default("markdown"), not null # # Foreign Keys @@ -31,6 +31,7 @@ class Redaction < ActiveRecord::Base has_many :old_ways has_many :old_relations + validates :title, :description, :invalid_chars => true validates :description, :presence => true validates :description_format, :inclusion => { :in => %w[text html markdown] } diff --git a/app/models/relation_tag.rb b/app/models/relation_tag.rb index 5dc609987..02d5a216b 100644 --- a/app/models/relation_tag.rb +++ b/app/models/relation_tag.rb @@ -2,7 +2,7 @@ # # Table name: current_relation_tags # -# relation_id :integer not null, primary key +# relation_id :bigint(8) not null, primary key # k :string default(""), not null, primary key # v :string default(""), not null # @@ -18,6 +18,6 @@ class RelationTag < ActiveRecord::Base belongs_to :relation validates :relation, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => :relation_id } end diff --git a/app/models/report.rb b/app/models/report.rb index 63296a094..ac00f1cfb 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -27,7 +27,7 @@ class Report < ActiveRecord::Base validates :issue, :presence => true validates :user, :presence => true - validates :details, :presence => true + validates :details, :presence => true, :invalid_chars => true validates :category, :presence => true def self.categories_for(reportable) diff --git a/app/models/trace.rb b/app/models/trace.rb index 5096a81aa..0e8180550 100644 --- a/app/models/trace.rb +++ b/app/models/trace.rb @@ -2,17 +2,18 @@ # # Table name: gpx_files # -# id :integer not null, primary key -# user_id :integer not null +# id :bigint(8) not null, primary key +# user_id :bigint(8) not null # visible :boolean default(TRUE), not null # name :string default(""), not null -# size :integer +# size :bigint(8) # latitude :float # longitude :float # timestamp :datetime not null # description :string default(""), not null # inserted :boolean not null # visibility :enum default("public"), not null +# length :bigint(8) # # Indexes # @@ -39,6 +40,7 @@ class Trace < ActiveRecord::Base validates :user, :presence => true, :associated => true validates :name, :presence => true, :length => 1..255 + validates :name, :description, :invalid_chars => true validates :description, :presence => { :on => :create }, :length => 1..255 validates :timestamp, :presence => true validates :visibility, :inclusion => %w[private public trackable identifiable] diff --git a/app/models/tracetag.rb b/app/models/tracetag.rb index 1a4fbd398..cb7cf1145 100644 --- a/app/models/tracetag.rb +++ b/app/models/tracetag.rb @@ -2,9 +2,9 @@ # # Table name: gpx_file_tags # -# gpx_id :integer default(0), not null +# gpx_id :bigint(8) default(0), not null # tag :string not null -# id :integer not null, primary key +# id :bigint(8) not null, primary key # # Indexes # @@ -22,5 +22,5 @@ class Tracetag < ActiveRecord::Base belongs_to :trace, :foreign_key => "gpx_id" validates :trace, :associated => true - validates :tag, :length => 1..255, :format => %r{\A[^/;.,?]*\z} + validates :tag, :length => 1..255, :format => %r{\A[^/;.,?]*\z}, :invalid_chars => true end diff --git a/app/models/user.rb b/app/models/user.rb index 37351c6b2..0b0d37326 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -88,23 +88,16 @@ class User < ActiveRecord::Base :default_url => "/assets/:class/:attachment/:style.png", :styles => { :large => "100x100>", :small => "50x50>" } - INVALID_ASCII_CHARS = "/;.,?%#".freeze - INVALID_NON_ASCII_CHARS = "\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff".freeze - validates :display_name, :presence => true, :allow_nil => true, :length => 3..255, :exclusion => %w[new terms save confirm confirm-email go_public reset-password forgot-password suspended] validates :display_name, :if => proc { |u| u.display_name_changed? }, :uniqueness => { :case_sensitive => false } validates :display_name, :if => proc { |u| u.display_name_changed? }, - :format => { :with => /\A[^#{INVALID_NON_ASCII_CHARS}]*\z/ } - validates :display_name, :if => proc { |u| u.display_name_changed? }, - :format => { :with => /\A[^#{INVALID_ASCII_CHARS}]*\z/, - :message => I18n.t("users.account.invalid chars", :invalid_chars => INVALID_ASCII_CHARS) } - validates :display_name, :if => proc { |u| u.display_name_changed? }, - :format => { :with => /\A\S/, :message => I18n.t("users.account.leading whitespace") } - validates :display_name, :if => proc { |u| u.display_name_changed? }, - :format => { :with => /\S\z/, :message => I18n.t("users.account.trailing whitespace") } - validates :email, :presence => true, :confirmation => true + :invalid_chars => true, + :invalid_url_chars => true, + :leading_whitespace => true, + :trailing_whitespace => true + validates :email, :presence => true, :confirmation => true, :invalid_chars => true validates :email, :if => proc { |u| u.email_changed? }, :uniqueness => { :case_sensitive => false } validates :pass_crypt, :confirmation => true, :length => 8..255 diff --git a/app/models/user_block.rb b/app/models/user_block.rb index 9f32862af..f56f87b9d 100644 --- a/app/models/user_block.rb +++ b/app/models/user_block.rb @@ -3,12 +3,12 @@ # Table name: user_blocks # # id :integer not null, primary key -# user_id :integer not null -# creator_id :integer not null +# user_id :bigint(8) not null +# creator_id :bigint(8) not null # reason :text not null # ends_at :datetime not null # needs_view :boolean default(FALSE), not null -# revoker_id :integer +# revoker_id :bigint(8) # created_at :datetime # updated_at :datetime # reason_format :enum default("markdown"), not null @@ -26,6 +26,7 @@ class UserBlock < ActiveRecord::Base validate :moderator_permissions + validates :reason, :invalid_chars => true belongs_to :user, :class_name => "User", :foreign_key => :user_id belongs_to :creator, :class_name => "User", :foreign_key => :creator_id diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index 69b0e9dde..781dd626a 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -2,7 +2,7 @@ # # Table name: user_preferences # -# user_id :integer not null, primary key +# user_id :bigint(8) not null, primary key # k :string not null, primary key # v :string not null # @@ -17,7 +17,7 @@ class UserPreference < ActiveRecord::Base belongs_to :user validates :user, :presence => true, :associated => true - validates :k, :v, :length => 1..255 + validates :k, :v, :length => 1..255, :invalid_chars => true # Turn this Node in to an XML Node without the wrapper. def to_xml_node diff --git a/app/models/way_tag.rb b/app/models/way_tag.rb index 8ef75f38e..4e0f7ee2d 100644 --- a/app/models/way_tag.rb +++ b/app/models/way_tag.rb @@ -2,7 +2,7 @@ # # Table name: current_way_tags # -# way_id :integer not null, primary key +# way_id :bigint(8) not null, primary key # k :string default(""), not null, primary key # v :string default(""), not null # @@ -18,6 +18,6 @@ class WayTag < ActiveRecord::Base belongs_to :way validates :way, :presence => true, :associated => true - validates :k, :v, :allow_blank => true, :length => { :maximum => 255 } + validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :invalid_chars => true validates :k, :uniqueness => { :scope => :way_id } end diff --git a/app/validators/invalid_chars_validator.rb b/app/validators/invalid_chars_validator.rb new file mode 100644 index 000000000..c324fd394 --- /dev/null +++ b/app/validators/invalid_chars_validator.rb @@ -0,0 +1,9 @@ +class InvalidCharsValidator < ActiveModel::EachValidator + INVALID_CHARS = "\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff".freeze + + def validate_each(record, attribute, value) + if value =~ /[#{INVALID_CHARS}]/ + record.errors[attribute] << (options[:message] || "contains invalid chars") + end + end +end \ No newline at end of file diff --git a/app/validators/invalid_url_chars_validator.rb b/app/validators/invalid_url_chars_validator.rb new file mode 100644 index 000000000..77a2fc58c --- /dev/null +++ b/app/validators/invalid_url_chars_validator.rb @@ -0,0 +1,9 @@ +class InvalidUrlCharsValidator < ActiveModel::EachValidator + INVALID_URL_CHARS = "/;.,?%#".freeze + + def validate_each(record, attribute, value) + if value =~ /[#{INVALID_URL_CHARS}]/ + record.errors[attribute] << (options[:message] || I18n.t("validations.invalid chars", :invalid_chars => INVALID_URL_CHARS)) + end + end +end \ No newline at end of file diff --git a/app/validators/leading_whitespace_validator.rb b/app/validators/leading_whitespace_validator.rb new file mode 100644 index 000000000..fcefb0a19 --- /dev/null +++ b/app/validators/leading_whitespace_validator.rb @@ -0,0 +1,7 @@ +class LeadingWhitespaceValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + if value =~ /\A\s/ + record.errors[attribute] << (options[:message] || I18n.t("validations.leading whitespace")) + end + end +end \ No newline at end of file diff --git a/app/validators/trailing_whitespace_validator.rb b/app/validators/trailing_whitespace_validator.rb new file mode 100644 index 000000000..bb34ef463 --- /dev/null +++ b/app/validators/trailing_whitespace_validator.rb @@ -0,0 +1,7 @@ +class TrailingWhitespaceValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + if value =~ /\s\z/ + record.errors[attribute] << (options[:message] || I18n.t("validations.trailing whitespace")) + end + end +end \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 0a5ee729d..c53ae19c8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2134,9 +2134,6 @@ en: return to profile: Return to profile flash update success confirm needed: "User information updated successfully. Check your email for a note to confirm your new email address." flash update success: "User information updated successfully." - leading whitespace: "has leading whitespace" - trailing whitespace: "has trailing whitespace" - invalid chars: "cannot contain invalid chars: %{invalid_chars}" confirm: heading: Check your email! introduction_1: | @@ -2565,3 +2562,7 @@ en: not_empty: "Redaction is not empty. Please un-redact all versions belonging to this redaction before destroying it." flash: "Redaction destroyed." error: "There was an error destroying this redaction." + validations: + leading whitespace: "has leading whitespace" + trailing whitespace: "has trailing whitespace" + invalid chars: "must not contain an invalid char: %{invalid_chars}"