From 6be629ae82bd5574451ef36aa43a3d388ae6a471 Mon Sep 17 00:00:00 2001 From: Ahmad Farhat Date: Tue, 5 Jan 2021 17:22:57 -0500 Subject: [PATCH] Make all LIKE queries case insensitive (#2402) --- app/models/concerns/queries.rb | 41 +++++++++++++++++++++++ app/models/room.rb | 43 ++++++++++++------------- app/models/user.rb | 59 +++++++++++++++++----------------- 3 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 app/models/concerns/queries.rb diff --git a/app/models/concerns/queries.rb b/app/models/concerns/queries.rb new file mode 100644 index 00000000..8138429a --- /dev/null +++ b/app/models/concerns/queries.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/. +# +# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). +# +# This program is free software; you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free Software +# Foundation; either version 3.0 of the License, or (at your option) any later +# version. +# +# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License along +# with BigBlueButton; if not, see . + +module Queries + extend ActiveSupport::Concern + + def created_at_text + active_database = Rails.configuration.database_configuration[Rails.env]["adapter"] + # Postgres requires created_at to be cast to a string + if active_database == "postgresql" + "created_at::text" + else + "created_at" + end + end + + def like_text + active_database = Rails.configuration.database_configuration[Rails.env]["adapter"] + # Use postgres case insensitive like + if active_database == "postgresql" + "ILIKE" + else + "LIKE" + end + end +end diff --git a/app/models/room.rb b/app/models/room.rb index 8feb56c1..1d9abf5b 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -32,36 +32,33 @@ class Room < ApplicationRecord has_one_attached :presentation - def self.admins_search(string) - active_database = Rails.configuration.database_configuration[Rails.env]["adapter"] - # Postgres requires created_at to be cast to a string - created_at_query = if active_database == "postgresql" - "created_at::text" - else - "created_at" + class << self + include Queries + + def admins_search(string) + like = like_text + search_query = "rooms.name #{like} :search OR rooms.uid #{like} :search OR users.email #{like} :search" \ + " OR users.#{created_at_text} #{like} :search" + + search_param = "%#{sanitize_sql_like(string)}%" + where(search_query, search: search_param) end - search_query = "rooms.name LIKE :search OR rooms.uid LIKE :search OR users.email LIKE :search" \ - " OR users.#{created_at_query} LIKE :search" + def admins_order(column, direction, running_ids) + # Include the owner of the table + table = joins(:owner) - search_param = "%#{sanitize_sql_like(string)}%" - where(search_query, search: search_param) - end + # Rely on manual ordering if trying to sort by status + return order_by_status(table, running_ids) if column == "status" - def self.admins_order(column, direction, running_ids) - # Include the owner of the table - table = joins(:owner) + return table.order("COALESCE(rooms.last_session,rooms.created_at) DESC") if column == "created_at" - # Rely on manual ordering if trying to sort by status - return order_by_status(table, running_ids) if column == "status" + return table.order(Arel.sql("rooms.#{column} #{direction}")) if table.column_names.include?(column) - return table.order("COALESCE(rooms.last_session,rooms.created_at) DESC") if column == "created_at" + return table.order(Arel.sql("#{column} #{direction}")) if column == "users.name" - return table.order(Arel.sql("rooms.#{column} #{direction}")) if table.column_names.include?(column) - - return table.order(Arel.sql("#{column} #{direction}")) if column == "users.name" - - table + table + end end # Determines if a user owns a room. diff --git a/app/models/user.rb b/app/models/user.rb index cb5d3d8b..66f6fc31 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -54,6 +54,7 @@ class User < ApplicationRecord class << self include AuthValues + include Queries # Generates a user from omniauth. def from_omniauth(auth) @@ -69,48 +70,46 @@ class User < ApplicationRecord u.save! end end - end - def self.admins_search(string) - return all if string.blank? + def admins_search(string) + return all if string.blank? - active_database = Rails.configuration.database_configuration[Rails.env]["adapter"] - # Postgres requires created_at to be cast to a string - created_at_query = if active_database == "postgresql" - "created_at::text" - else - "created_at" + like = like_text # Get the correct like clause to use based on db adapter + + search_query = "users.name #{like} :search OR email #{like} :search OR username #{like} :search" \ + " OR users.#{created_at_text} #{like} :search OR users.provider #{like} :search" \ + " OR roles.name #{like} :search" + + search_param = "%#{sanitize_sql_like(string)}%" + where(search_query, search: search_param) end - search_query = "users.name LIKE :search OR email LIKE :search OR username LIKE :search" \ - " OR users.#{created_at_query} LIKE :search OR users.provider LIKE :search" \ - " OR roles.name LIKE :search" + def admins_order(column, direction) + # Arel.sql to avoid sql injection + order(Arel.sql("users.#{column} #{direction}")) + end - search_param = "%#{sanitize_sql_like(string)}%" - where(search_query, search: search_param) - end + def shared_list_search(string) + return all if string.blank? - def self.admins_order(column, direction) - # Arel.sql to avoid sql injection - order(Arel.sql("users.#{column} #{direction}")) - end + like = like_text # Get the correct like clause to use based on db adapter - def self.shared_list_search(string) - return all if string.blank? + search_query = "users.name #{like} :search OR users.uid #{like} :search" - search_query = "users.name LIKE :search OR users.uid LIKE :search" + search_param = "%#{sanitize_sql_like(string)}%" + where(search_query, search: search_param) + end - search_param = "%#{sanitize_sql_like(string)}%" - where(search_query, search: search_param) - end + def merge_list_search(string) + return all if string.blank? - def self.merge_list_search(string) - return all if string.blank? + like = like_text # Get the correct like clause to use based on db adapter - search_query = "users.name LIKE :search OR users.email LIKE :search" + search_query = "users.name #{like} :search OR users.email #{like} :search" - search_param = "%#{sanitize_sql_like(string)}%" - where(search_query, search: search_param) + search_param = "%#{sanitize_sql_like(string)}%" + where(search_query, search: search_param) + end end # Returns a list of rooms ordered by last session (with nil rooms last)