Add user input sanitizing in the models [SCI-102]

This commit is contained in:
Oleksii Kriuchykhin 2017-01-05 12:51:14 +01:00
parent 835e982292
commit 0ecb6904d4
22 changed files with 173 additions and 0 deletions

View file

@ -3,4 +3,8 @@ module InputSanitizeHelper
ActionController::Base.helpers.sanitize(text,
tags: Constants::WHITELISTED_TAGS)
end
def escape_input(text)
ERB::Util.html_escape(text)
end
end

View file

@ -1,7 +1,9 @@
class Checklist < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::TEXT_MAX_LENGTH }
@ -54,4 +56,9 @@ class Checklist < ActiveRecord::Base
end
end
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,5 +1,8 @@
class ChecklistItem < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :text, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :text,
presence: true,
length: { maximum: Constants::TEXT_MAX_LENGTH }
@ -9,4 +12,10 @@ class ChecklistItem < ActiveRecord::Base
belongs_to :checklist, inverse_of: :checklist_items
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User'
private
def sanitize_fields
self.text = sanitize_input(text)
end
end

View file

@ -1,7 +1,9 @@
class Comment < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :message, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :message,
presence: true,
length: { maximum: Constants::TEXT_MAX_LENGTH }
@ -101,4 +103,7 @@ class Comment < ActiveRecord::Base
end
end
def sanitize_fields
self.message = sanitize_input(message)
end
end

View file

@ -1,5 +1,8 @@
class CustomField < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH },
@ -20,4 +23,10 @@ class CustomField < ActiveRecord::Base
def update_samples_table_state
SamplesTable.update_samples_table_state(self, nil)
end
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,5 +1,6 @@
class Experiment < ActiveRecord::Base
include ArchivableModel, SearchableModel
include InputSanitizeHelper
belongs_to :project, inverse_of: :experiments
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
@ -18,6 +19,7 @@ class Experiment < ActiveRecord::Base
if: :workflowimg_check
auto_strip_attributes :name, :description, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH },
@ -408,6 +410,11 @@ class Experiment < ActiveRecord::Base
private
def sanitize_fields
self.name = escape_input(name)
self.description = sanitize_input(description)
end
# Archive all modules. Receives an array of module integer IDs.
def archive_modules(module_ids)
module_ids.each do |m_id|

View file

@ -1,9 +1,11 @@
class MyModule < ActiveRecord::Base
include ArchivableModel, SearchableModel
include InputSanitizeHelper
before_create :create_blank_protocol
auto_strip_attributes :name, :description, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH }
@ -357,6 +359,11 @@ class MyModule < ActiveRecord::Base
private
def sanitize_fields
self.name = escape_input(name)
self.description = sanitize_input(description)
end
def create_blank_protocol
protocols << Protocol.new_blank_for_module(self)
end

View file

@ -1,7 +1,9 @@
class MyModuleGroup < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
@ -80,4 +82,10 @@ class MyModuleGroup < ActiveRecord::Base
clone.save
clone
end
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -2,8 +2,10 @@ class Organization < ActiveRecord::Base
# Not really MVC-compliant, but we just use it for logger
# output in space_taken related functions
include ActionView::Helpers::NumberHelper
include InputSanitizeHelper
auto_strip_attributes :name, :description, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH }
@ -306,4 +308,11 @@ class Organization < ActiveRecord::Base
def protocol_keywords_list
ProtocolKeyword.where(organization: self).pluck(:name)
end
private
def sanitize_fields
self.name = escape_input(name)
self.description = sanitize_input(description)
end
end

View file

@ -1,9 +1,11 @@
class Project < ActiveRecord::Base
include ArchivableModel, SearchableModel
include InputSanitizeHelper
enum visibility: { hidden: 0, visible: 1 }
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH },
@ -173,4 +175,10 @@ class Project < ActiveRecord::Base
.distinct
end
end
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,6 +1,7 @@
class Protocol < ActiveRecord::Base
include SearchableModel
include RenamingUtil
include InputSanitizeHelper
after_save :update_linked_children
after_destroy :decrement_linked_children
@ -14,6 +15,7 @@ class Protocol < ActiveRecord::Base
}
auto_strip_attributes :name, :description, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
# Name is required when its actually specified (i.e. :in_repository? is true)
validates :name, length: { maximum: Constants::NAME_MAX_LENGTH }
validates :description, length: { maximum: Constants::TEXT_MAX_LENGTH }
@ -590,6 +592,11 @@ class Protocol < ActiveRecord::Base
private
def sanitize_fields
self.name = escape_input(name)
self.description = sanitize_input(description)
end
def deep_clone(clone, current_user)
# Save cloned protocol first
success = clone.save

View file

@ -1,5 +1,8 @@
class ProtocolKeyword < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH }
@ -9,4 +12,10 @@ class ProtocolKeyword < ActiveRecord::Base
has_many :protocol_protocol_keywords, inverse_of: :protocol_keyword, dependent: :destroy
has_many :protocols, through: :protocol_protocol_keywords
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,7 +1,9 @@
class Report < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, :description, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH },
@ -115,4 +117,9 @@ class Report < ActiveRecord::Base
end
end
end
def sanitize_fields
self.name = escape_input(name)
self.description = sanitize_input(description)
end
end

View file

@ -1,7 +1,9 @@
class Result < ActiveRecord::Base
include ArchivableModel, SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :user, :my_module, presence: true
validates :name, length: { maximum: Constants::NAME_MAX_LENGTH }
validate :text_or_asset_or_table
@ -95,6 +97,7 @@ class Result < ActiveRecord::Base
end
private
def text_or_asset_or_table
num_of_assigns = 0
num_of_assigns += result_text.blank? ? 0 : 1
@ -109,4 +112,8 @@ class Result < ActiveRecord::Base
errors.add(:base, "Result should be instance of text/asset/table.")
end
end
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,9 +1,18 @@
class ResultText < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :text, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :text,
presence: true,
length: { maximum: Constants::RICH_TEXT_MAX_LENGTH }
validates :result, presence: true
belongs_to :result, inverse_of: :result_text
private
def sanitize_fields
self.text = sanitize_input(text)
end
end

View file

@ -1,7 +1,9 @@
class Sample < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
@ -70,4 +72,9 @@ class Sample < ActiveRecord::Base
end
end
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,5 +1,8 @@
class SampleCustomField < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :value, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :value,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
@ -7,4 +10,10 @@ class SampleCustomField < ActiveRecord::Base
belongs_to :custom_field, inverse_of: :sample_custom_fields
belongs_to :sample, inverse_of: :sample_custom_fields
private
def sanitize_fields
self.value = escape_input(value)
end
end

View file

@ -1,5 +1,8 @@
class SampleGroup < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :name, :color, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH },
@ -17,4 +20,11 @@ class SampleGroup < ActiveRecord::Base
has_many :samples, inverse_of: :sample_groups
scope :sorted, -> { order(name: :asc) }
private
def sanitize_fields
self.name = escape_input(name)
self.color = escape_input(color)
end
end

View file

@ -1,5 +1,8 @@
class SampleType < ActiveRecord::Base
include InputSanitizeHelper
auto_strip_attributes :name, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH },
@ -14,4 +17,10 @@ class SampleType < ActiveRecord::Base
has_many :samples, inverse_of: :sample_types
scope :sorted, -> { order(name: :asc) }
private
def sanitize_fields
self.name = escape_input(name)
end
end

View file

@ -1,7 +1,9 @@
class Step < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, :description, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
@ -159,4 +161,11 @@ class Step < ActiveRecord::Base
end
end
end
private
def sanitize_fields
self.name = escape_input(name)
self.description = sanitize_input(description)
end
end

View file

@ -1,7 +1,9 @@
class Tag < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
auto_strip_attributes :name, :color, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
@ -56,4 +58,11 @@ class Tag < ActiveRecord::Base
project: project
)
end
private
def sanitize_fields
self.name = escape_input(name)
self.color = escape_input(color)
end
end

View file

@ -1,5 +1,6 @@
class User < ActiveRecord::Base
include SearchableModel
include InputSanitizeHelper
acts_as_token_authenticatable
devise :invitable, :confirmable, :database_authenticatable, :registerable,
@ -20,6 +21,7 @@ class User < ActiveRecord::Base
}
auto_strip_attributes :full_name, :initials, nullify: false
before_validation :sanitize_fields, on: [:create, :update]
validates :full_name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH }
@ -274,6 +276,12 @@ class User < ActiveRecord::Base
private
def sanitize_fields
self.full_name = escape_input(full_name)
self.initials = escape_input(initials)
self.email = escape_input(email)
end
def destroy_notifications
# Find all notifications where user is the only reference
# on the notification, and destroy all such notifications