From 818596ae36724d861a9f704d4d6c697b982df34d Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Tue, 25 Aug 2015 08:23:52 +0000 Subject: [PATCH] VRFS-3451 musician_search verifying instrument and genres inputs --- ruby/lib/jam_ruby/models/base_search.rb | 34 +++++++++++++------ .../jam_ruby/models/musician_instrument.rb | 7 +++- .../jam_ruby/models/musician_search_spec.rb | 3 +- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/ruby/lib/jam_ruby/models/base_search.rb b/ruby/lib/jam_ruby/models/base_search.rb index f08c46a7d..ed2feefb7 100644 --- a/ruby/lib/jam_ruby/models/base_search.rb +++ b/ruby/lib/jam_ruby/models/base_search.rb @@ -102,26 +102,38 @@ module JamRuby def self.search_target_class end - # FIXME: SQL INJECTION def _genres(rel, query_data=json) gids = query_data[KEY_GENRES] unless gids.blank? - gidsql = gids.join("','") - gpsql = "SELECT player_id FROM genre_players WHERE (player_type = '#{self.class.search_target_class.name}' AND genre_id IN ('#{gidsql}'))" - rel = rel.where("#{self.class.search_target_class.table_name}.id IN (#{gpsql})") + allgids = Genre.order(:id).pluck(:id) + gids = gids.select { |gg| allgids.index(gg).present? } + + unless gids.blank? + gidsql = gids.join("','") + gpsql = "SELECT player_id FROM genre_players WHERE (player_type = '#{self.class.search_target_class.name}' AND genre_id IN ('#{gidsql}'))" + rel = rel.where("#{self.class.search_target_class.table_name}.id IN (#{gpsql})") + end end rel end - # FIXME: SQL INJECTION def _instruments(rel, query_data=json) unless (instruments = query_data[KEY_INSTRUMENTS]).blank? - instsql = "SELECT player_id FROM musicians_instruments WHERE ((" - instsql += instruments.collect do |inst| - "instrument_id = '#{inst['instrument_id']}' AND proficiency_level = #{inst['proficiency_level']}" - end.join(") OR (") - instsql += "))" - rel = rel.where("#{self.class.search_target_class.table_name}.id IN (#{instsql})") + instrids = Instrument.order(:id).pluck(:id) + instruments = instruments.select { |ii| instrids.index(ii['instrument_id']).present? } + + unless instruments.blank? + instsql = "SELECT player_id FROM musicians_instruments WHERE ((" + instsql += instruments.collect do |inst| + unless MusicianInstrument::PROFICIENCY_RANGE === (proflvl=inst['proficiency_level'].to_i) + proflvl = MusicianInstrument::LEVEL_INTERMEDIATE + end + "instrument_id = '#{inst['instrument_id']}' AND proficiency_level = #{proflvl}" + end.join(") OR (") + instsql += "))" + + rel = rel.where("#{self.class.search_target_class.table_name}.id IN (#{instsql})") + end end rel end diff --git a/ruby/lib/jam_ruby/models/musician_instrument.rb b/ruby/lib/jam_ruby/models/musician_instrument.rb index 445070da6..db4b318f4 100644 --- a/ruby/lib/jam_ruby/models/musician_instrument.rb +++ b/ruby/lib/jam_ruby/models/musician_instrument.rb @@ -13,8 +13,13 @@ module JamRuby belongs_to :player, polymorphic: true belongs_to :instrument, :class_name => "JamRuby::Instrument" + LEVEL_BEGIN = 1 + LEVEL_INTERMEDIATE = 2 + LEVEL_EXPERT = 3 + PROFICIENCY_RANGE = (LEVEL_BEGIN..LEVEL_EXPERT) + def description @description = self.instrument.description end end -end \ No newline at end of file +end diff --git a/ruby/spec/jam_ruby/models/musician_search_spec.rb b/ruby/spec/jam_ruby/models/musician_search_spec.rb index e3ef230a5..bfd46c1c2 100644 --- a/ruby/spec/jam_ruby/models/musician_search_spec.rb +++ b/ruby/spec/jam_ruby/models/musician_search_spec.rb @@ -173,7 +173,8 @@ describe 'Musician Search Model' do it "gets expected number of users" do instjson = [{ instrument_id: Instrument.first.id, proficiency_level: 2 }, - { instrument_id: Instrument.first(2)[1].id, proficiency_level: 2 } + { instrument_id: Instrument.first(2)[1].id, proficiency_level: 2 }, + { instrument_id: 'foo', proficiency_level: 2 }, ] search.update_json_value(MusicianSearch::KEY_INSTRUMENTS, instjson) expect(search.do_search.count).to eq(3)