app/periscope/periscope_controller.rb in periscope_rails-0.0.9 vs app/periscope/periscope_controller.rb in periscope_rails-0.0.10

- old
+ new

@@ -2,28 +2,38 @@ before_filter :authenticate protect_from_forgery :except => [:look, :login] def look if !params[:sql].nil? - render :json => run_sql(params[:sql]) + render :json => merge_on_metadata(run_sql(params[:sql])) else - render :json => {:error => "Command not understood"} + render :json => merge_on_metadata({:error => "Command not understood"}) end end def login - render :json => get_info() + render :json => merge_on_metadata(get_info()) end private def authenticate unless PeriscopeRails::Config.check_password(params[:password].to_s) - render :json => {:error => "Password invalid."} + render :json => merge_on_metadata({:error => "Password invalid."}) end end + def merge_on_metadata(hash) + version = nil + begin + version = Gem.loaded_specs["periscope_rails"].version.version + rescue + version = "error" + end + return hash.merge({ :version => version, :database_type => get_db_type }) + end + def run_sql(sql_command) #TODO: protect based on CFG, not blacklist bad_words = %W{drop delete update into insert index add remove grant revoke create createdb} bad_words += %W{createuser createrole destroy disconnect exec execute dropdb primary key rollback ; --} @@ -37,17 +47,12 @@ error_message = "Potentially harmful keyword found, blocking script." else begin #for whole query active_record = PeriscopeRails::Config.get_active_record() begin #just for costing - begin - is_postgres = ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter - rescue Exception => e - is_postgres = false - end active_record.transaction do #costing - if PeriscopeRails::Config.block_expensive_queries? and is_postgres + if PeriscopeRails::Config.block_expensive_queries? and get_db_type == "postgres" active_record.connection.select_all("explain #{command}")[0]["QUERY PLAN"] =~ /rows=(\d+) width=(\d+)\)$/ row_count, width = $1.to_i, $2.to_i if row_count > 0 and width > 0 raise "Command blocked, it may be too slow. Estimated at #{row_count} rows, commands must return fewer than #{PeriscopeRails::Config.max_rows} rows." if row_count > PeriscopeRails::Config.max_rows raise "Command blocked, it may be too slow. Estimated at #{row_count * width} bytes, commands use less than #{PeriscopeRails::Config.max_size} bytes." if row_count * width > PeriscopeRails::Config.max_size @@ -84,7 +89,23 @@ table_names = ActiveRecord::Base.connection.tables.sort table_names.each do |table_name| tables << {:name => table_name, :columns => ActiveRecord::Base.connection.columns(table_name)} end return {:tables => tables, :error => nil} + end + + def get_db_type + begin + return "postgres" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter + rescue Exception => e + begin + return "mysql" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::MysqlAdapter + rescue Exception => e + begin + return "mysql" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::Mysql2Adapter + rescue + return nil + end + end + end end end