diff --git a/app/models/communication/block.rb b/app/models/communication/block.rb index 1369e18f480bf3ac5acbfd4bdc4871e74834f8ee..aec48f232423fc4ce72c62a8ea11c9427a87db52 100644 --- a/app/models/communication/block.rb +++ b/app/models/communication/block.rb @@ -24,6 +24,7 @@ # fk_rails_18291ef65f (university_id => universities.id) # class Communication::Block < ApplicationRecord + include Sanitizable include WithUniversity include WithPosition include Accessible diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb index d48d2a51c9f6cfcc2ed88f03caefa06031441ca4..da5242530e14600fef86bc74bc50f113569307b2 100644 --- a/app/models/communication/extranet.rb +++ b/app/models/communication/extranet.rb @@ -35,6 +35,7 @@ class Communication::Extranet < ApplicationRecord self.filter_attributes += [:sso_cert] + # We don't include Sanitizable because too many complex attributes. We handle it below. include WithAbouts include WithLegal include WithSso @@ -49,6 +50,8 @@ class Communication::Extranet < ApplicationRecord validates :logo, size: { less_than: 1.megabytes } validates :favicon, size: { less_than: 1.megabytes } + before_validation :sanitize_fields + scope :ordered, -> { order(:name) } scope :for_search_term, -> (term) { where(" @@ -100,4 +103,16 @@ class Communication::Extranet < ApplicationRecord def to_s "#{name}" end + + private + + def sanitize_fields + self.color = Osuny::Sanitizer.sanitize(self.color, 'string') + self.cookies_policy = Osuny::Sanitizer.sanitize(self.cookies_policy, 'text') + self.host = Osuny::Sanitizer.sanitize(self.host, 'string') + self.name = Osuny::Sanitizer.sanitize(self.name, 'string') + self.privacy_policy = Osuny::Sanitizer.sanitize(self.privacy_policy, 'text') + self.registration_contact = Osuny::Sanitizer.sanitize(self.registration_contact, 'string') + self.terms = Osuny::Sanitizer.sanitize(self.terms, 'text') + end end diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb index 52a48b87fc60d8ecb08e652ddf6c199fdd42cbf7..2ef448ae985ec89cab6710d43e1074d1f8b3fd6e 100644 --- a/app/models/communication/website.rb +++ b/app/models/communication/website.rb @@ -64,6 +64,8 @@ class Communication::Website < ApplicationRecord validates :languages, length: { minimum: 1 } validate :languages_must_include_default_language + before_validation :sanitize_fields + scope :ordered, -> { order(:name) } scope :in_production, -> { where(in_production: true) } scope :for_theme_version, -> (version) { where(theme_version: version) } @@ -107,6 +109,15 @@ class Communication::Website < ApplicationRecord protected + def sanitize_fields + self.git_branch = Osuny::Sanitizer.sanitize(self.git_branch, 'string') + self.git_endpoint = Osuny::Sanitizer.sanitize(self.git_endpoint, 'string') + self.name = Osuny::Sanitizer.sanitize(self.name, 'string') + self.plausible_url = Osuny::Sanitizer.sanitize(self.plausible_url, 'string') + self.repository = Osuny::Sanitizer.sanitize(self.repository, 'string') + self.url = Osuny::Sanitizer.sanitize(self.url, 'string') + end + def languages_must_include_default_language errors.add(:languages, :must_include_default) unless language_ids.include?(default_language_id) end diff --git a/app/models/communication/website/git_file.rb b/app/models/communication/website/git_file.rb index d055984b8607a6f96ff6d599fe3ffe61170f2cfd..ca3bbce5eacdb87321d25c90a5fd1390b26b8bad 100644 --- a/app/models/communication/website/git_file.rb +++ b/app/models/communication/website/git_file.rb @@ -21,6 +21,8 @@ # fk_rails_8505d649e8 (website_id => communication_websites.id) # class Communication::Website::GitFile < ApplicationRecord + # We don't include Sanitizable as this model is never handled by users directly. + belongs_to :website, class_name: 'Communication::Website' belongs_to :about, polymorphic: true diff --git a/app/models/communication/website/permalink.rb b/app/models/communication/website/permalink.rb index 88f821fd28202d11e3338cce0ff2accac97f517b..5329fcc0c3e690ea1beb632dbb1b5214e6c52991 100644 --- a/app/models/communication/website/permalink.rb +++ b/app/models/communication/website/permalink.rb @@ -40,6 +40,7 @@ class Communication::Website::Permalink < ApplicationRecord "University::Person::Teacher" => Communication::Website::Permalink::Teacher } + # We don't include Sanitizable as this model is never handled by users directly. include WithUniversity belongs_to :university diff --git a/app/models/concerns/sanitizable.rb b/app/models/concerns/sanitizable.rb index 1d9b3906576f0dfbcd5ebcd97b9a20d3598404aa..83f0cdaea91da72821b1f68abb464f38a7559251 100644 --- a/app/models/concerns/sanitizable.rb +++ b/app/models/concerns/sanitizable.rb @@ -11,6 +11,9 @@ module Sanitizable .select { |attr_name, attr_type| [:string, :text].include?(attr_type) && public_send(attr_name).present? } + .reject { |attr_name, _| + attr_name.ends_with?('_type') # Reject polymorphic type + } attributes_to_sanitize.each do |attr_name, attr_type| public_send "#{attr_name}=", Osuny::Sanitizer.sanitize(public_send(attr_name), attr_type) diff --git a/app/models/education/cohort.rb b/app/models/education/cohort.rb index e37605bda37291b7b373eff62351d342f0b56c83..482c32aad582b6e2eecf5e8178bb67df8a4237d5 100644 --- a/app/models/education/cohort.rb +++ b/app/models/education/cohort.rb @@ -26,6 +26,7 @@ # fk_rails_c2d725cabd (academic_year_id => education_academic_years.id) # class Education::Cohort < ApplicationRecord + include Sanitizable include WithUniversity belongs_to :school, diff --git a/app/models/education/diploma.rb b/app/models/education/diploma.rb index f01e1db3bc274743ec9918ff0d368f3c262fcd35..7d78ab0898e83836b935508755fd7bd1804eb60b 100644 --- a/app/models/education/diploma.rb +++ b/app/models/education/diploma.rb @@ -23,6 +23,7 @@ # fk_rails_6cb2e9fa90 (university_id => universities.id) # class Education::Diploma < ApplicationRecord + include Sanitizable include WithBlocks include WithGit include WithPermalink diff --git a/app/models/education/school.rb b/app/models/education/school.rb index 14dbac9262e182359b73054c93cb1fca756bf071..78ab3e1fc5fbae0c810d23ff5a7feca6ab1d30a7 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -24,6 +24,7 @@ # fk_rails_e01b37a3ad (university_id => universities.id) # class Education::School < ApplicationRecord + include Sanitizable include WithGit include Aboutable include WithPrograms # must come before WithAlumni and WithTeam diff --git a/app/models/language.rb b/app/models/language.rb index 36cf5338a0bc6d3f337c79dcac2fdaacb195158f..212b40dce877387634041b6a844b49bd7c2b8836 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -10,6 +10,7 @@ # updated_at :datetime not null # class Language < ApplicationRecord + include Sanitizable has_many :users has_and_belongs_to_many :communication_websites, diff --git a/app/models/research/hal/author.rb b/app/models/research/hal/author.rb index 726c98e5450b49ece0fa9ab86cfecbc5f5f0049e..1a8e33ec278e2ddc8fc100f30213099a57743f94 100644 --- a/app/models/research/hal/author.rb +++ b/app/models/research/hal/author.rb @@ -17,6 +17,8 @@ # index_research_hal_authors_on_docid (docid) # class Research::Hal::Author < ApplicationRecord + include Sanitizable + has_and_belongs_to_many :publications, foreign_key: 'research_hal_publication_id', association_foreign_key: 'research_hal_author_id' @@ -76,7 +78,7 @@ class Research::Hal::Author < ApplicationRecord researchers << researcher researcher.import_research_hal_publications! end - + def disconnect_researcher(researcher) researchers.delete researcher researcher.import_research_hal_publications! diff --git a/app/models/research/hal/publication.rb b/app/models/research/hal/publication.rb index 75d03b57a5ab888c0e34e7a871a9d206f9ab2933..577fd844be578a2ef853c59e1a13297f4cd143af 100644 --- a/app/models/research/hal/publication.rb +++ b/app/models/research/hal/publication.rb @@ -20,9 +20,10 @@ # index_research_hal_publications_on_docid (docid) # class Research::Hal::Publication < ApplicationRecord + include Sanitizable include WithGit include WithSlug - + DOI_PREFIX = 'http://dx.doi.org/'.freeze has_and_belongs_to_many :researchers, diff --git a/app/models/research/journal.rb b/app/models/research/journal.rb index 21149af299ea637529ad441c4c9af6eb6960c15a..7919fd8eb63f04ac59dfae1eac008a4ff836dcc7 100644 --- a/app/models/research/journal.rb +++ b/app/models/research/journal.rb @@ -20,6 +20,7 @@ # fk_rails_96097d5f10 (university_id => universities.id) # class Research::Journal < ApplicationRecord + include Sanitizable include Aboutable include WithUniversity include WithGit diff --git a/app/models/research/journal/paper/kind.rb b/app/models/research/journal/paper/kind.rb index da961c04fcc36061726831a3d8b4d67e2e6324d2..f5895fd6f9b80d2246956fbc07cf648413edd341 100644 --- a/app/models/research/journal/paper/kind.rb +++ b/app/models/research/journal/paper/kind.rb @@ -21,6 +21,7 @@ # fk_rails_8e6f992b9d (university_id => universities.id) # class Research::Journal::Paper::Kind < ApplicationRecord + include Sanitizable include WithUniversity include WithGit include WithSlug diff --git a/app/models/research/laboratory.rb b/app/models/research/laboratory.rb index 2daa8f561dd6972026cfc0bba330ae23815192f5..d5e261d490e9555e69485746cbc70de878735f35 100644 --- a/app/models/research/laboratory.rb +++ b/app/models/research/laboratory.rb @@ -21,6 +21,7 @@ # fk_rails_f61d27545f (university_id => universities.id) # class Research::Laboratory < ApplicationRecord + include Sanitizable include WithGit include Aboutable diff --git a/app/models/university.rb b/app/models/university.rb index 15691d83123a5909d84f87a8c0616201f32a9c23..321f21333ed82efcb40e446851f6b5da3df545f0 100644 --- a/app/models/university.rb +++ b/app/models/university.rb @@ -38,6 +38,7 @@ class University < ApplicationRecord self.filter_attributes += [:sso_cert] + # We don't include Sanitizable because too many complex attributes. We handle it below. include WithPeopleAndOrganizations include WithCommunication include WithEducation @@ -59,6 +60,7 @@ class University < ApplicationRecord validates :sms_sender_name, presence: true, length: { maximum: 11 } validates :logo, size: { less_than: 1.megabytes } + before_validation :sanitize_fields after_destroy :destroy_remaining_blobs scope :ordered, -> { order(:name) } @@ -88,6 +90,20 @@ class University < ApplicationRecord private + def sanitize_fields + self.address = Osuny::Sanitizer.sanitize(self.address, 'string') + self.city = Osuny::Sanitizer.sanitize(self.city, 'string') + self.country = Osuny::Sanitizer.sanitize(self.country, 'string') + self.identifier = Osuny::Sanitizer.sanitize(self.identifier, 'string') + self.invoice_amount = Osuny::Sanitizer.sanitize(self.invoice_amount, 'string') + self.mail_from_address = Osuny::Sanitizer.sanitize(self.mail_from_address, 'string') + self.mail_from_name = Osuny::Sanitizer.sanitize(self.mail_from_name, 'string') + self.name = Osuny::Sanitizer.sanitize(self.name, 'string') + self.sms_sender_name = Osuny::Sanitizer.sanitize(self.sms_sender_name, 'string') + self.sso_button_label = Osuny::Sanitizer.sanitize(self.sso_button_label, 'string') + self.zipcode = Osuny::Sanitizer.sanitize(self.zipcode, 'string') + end + def destroy_remaining_blobs active_storage_blobs.delete_all end diff --git a/app/models/university/person/experience.rb b/app/models/university/person/experience.rb index a5f0b47c74ddc53c34fe856bf59a0bbe8e730985..60c2a43632ea9fdd7e62cadab1a7e9af2c5f6b8e 100644 --- a/app/models/university/person/experience.rb +++ b/app/models/university/person/experience.rb @@ -25,6 +25,7 @@ # fk_rails_923d0b71fd (university_id => universities.id) # class University::Person::Experience < ApplicationRecord + include Sanitizable include WithUniversity attr_accessor :organization_name diff --git a/app/models/university/person/involvement.rb b/app/models/university/person/involvement.rb index 988be24c96c7fa28a9a6eb6c18f87487d5db8a04..e80bd448a3bb315b90bcf4d0b3db213f35d31bff 100644 --- a/app/models/university/person/involvement.rb +++ b/app/models/university/person/involvement.rb @@ -25,6 +25,7 @@ # fk_rails_5c704f6338 (university_id => universities.id) # class University::Person::Involvement < ApplicationRecord + include Sanitizable include WithUniversity include WithPosition diff --git a/app/models/university/role.rb b/app/models/university/role.rb index 3e740ac5248e93ec6b98b178f8b8bf190d65c355..f631de252775ef4cb247f10b593063388e49a9c6 100644 --- a/app/models/university/role.rb +++ b/app/models/university/role.rb @@ -21,6 +21,7 @@ # fk_rails_8e52293a38 (university_id => universities.id) # class University::Role < ApplicationRecord + include Sanitizable include WithUniversity include WithPosition diff --git a/app/models/user.rb b/app/models/user.rb index 569270a99f6938fb281b3a5944e528b265872dbb..769136f69d5daba09c2b5ee5ca790e49111f1aeb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -56,6 +56,8 @@ # fk_rails_bd6f7212a9 (university_id => universities.id) # class User < ApplicationRecord + # We don't include Sanitizable because too many complex attributes. + # The sanitization is handled in User::WithAuthentication's sanitize_fields method. include WithAdminTheme include WithAvatar include WithRegistrationContext diff --git a/app/models/user/with_authentication.rb b/app/models/user/with_authentication.rb index 86a880834032231725a0fb57185d33e46bc141b7..443bbb02e0abd22074123342f2373dad51e61b2b 100644 --- a/app/models/user/with_authentication.rb +++ b/app/models/user/with_authentication.rb @@ -94,13 +94,11 @@ module User::WithAuthentication end def sanitize_fields - full_sanitizer = Rails::Html::FullSanitizer.new - # Only text allowed, and remove '=' to prevent excel formulas - self.email = full_sanitizer.sanitize(self.email)&.gsub('=', '') - self.first_name = full_sanitizer.sanitize(self.first_name)&.gsub('=', '') - self.last_name = full_sanitizer.sanitize(self.last_name)&.gsub('=', '') - self.mobile_phone = full_sanitizer.sanitize(self.mobile_phone)&.gsub('=', '') + self.email = Osuny::Sanitizer.sanitize(self.email, 'string')&.gsub('=', '') + self.first_name = Osuny::Sanitizer.sanitize(self.first_name, 'string')&.gsub('=', '') + self.last_name = Osuny::Sanitizer.sanitize(self.last_name, 'string')&.gsub('=', '') + self.mobile_phone = Osuny::Sanitizer.sanitize(self.mobile_phone, 'string')&.gsub('=', '') end def password_required? diff --git a/app/views/action_text/content/_layout.html.erb b/app/views/action_text/content/_layout.html.erb deleted file mode 100644 index 898a5066770e08c389a01f8428b91e6b2424c95f..0000000000000000000000000000000000000000 --- a/app/views/action_text/content/_layout.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render_action_text_content(content) %> diff --git a/app/views/active_storage/blobs/_blob.html.erb b/app/views/active_storage/blobs/_blob.html.erb deleted file mode 100644 index e823ece4caee828b2e1677c38b1cca44cb4fbbe2..0000000000000000000000000000000000000000 --- a/app/views/active_storage/blobs/_blob.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<figure class="attachment attachment--<%= blob.variable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>"> - <% if blob.image? %> - <%= kamifusen_tag blob, width: 800 %> - <% elsif blob.video? %> - <video controls> - <source src="<%= rails_blob_path(blob) %>" type="<%= blob.content_type %>"> - </video> - <% else %> - <%= link_to polymorphic_path(blob), target: :blank do %> - <p> - <span class="attachment__name"><%= blob.filename %></span> - <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span> - </p> - <% end %> - <% end %> - - <% if caption = blob.try(:caption) %> - <figcaption class="attachment__caption"> - <%= caption %> - </figcaption> - <% end %> -</figure> diff --git a/config/application.rb b/config/application.rb index fa9ee9cc7659a90eecb37623b4694e88c5589804..d7ff6b3577240e9c36bd8336a8b9cf434a54f2be 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,7 @@ require "active_storage/engine" require "action_controller/railtie" require "action_mailer/railtie" require "action_mailbox/engine" -require "action_text/engine" +# require "action_text/engine" require "action_view/railtie" # require "action_cable/engine" require "sprockets/railtie"