periscope_rails 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lock CHANGED
@@ -1,92 +1,92 @@
1
- PATH
2
- remote: .
3
- specs:
4
- periscope_rails (0.0.10)
5
- activesupport (~> 3.0)
6
- rails (~> 3.0)
7
-
8
- GEM
9
- remote: http://rubygems.org/
10
- specs:
11
- actionmailer (3.2.6)
12
- actionpack (= 3.2.6)
13
- mail (~> 2.4.4)
14
- actionpack (3.2.6)
15
- activemodel (= 3.2.6)
16
- activesupport (= 3.2.6)
17
- builder (~> 3.0.0)
18
- erubis (~> 2.7.0)
19
- journey (~> 1.0.1)
20
- rack (~> 1.4.0)
21
- rack-cache (~> 1.2)
22
- rack-test (~> 0.6.1)
23
- sprockets (~> 2.1.3)
24
- activemodel (3.2.6)
25
- activesupport (= 3.2.6)
26
- builder (~> 3.0.0)
27
- activerecord (3.2.6)
28
- activemodel (= 3.2.6)
29
- activesupport (= 3.2.6)
30
- arel (~> 3.0.2)
31
- tzinfo (~> 0.3.29)
32
- activeresource (3.2.6)
33
- activemodel (= 3.2.6)
34
- activesupport (= 3.2.6)
35
- activesupport (3.2.6)
36
- i18n (~> 0.6)
37
- multi_json (~> 1.0)
38
- arel (3.0.2)
39
- builder (3.0.0)
40
- erubis (2.7.0)
41
- hike (1.2.1)
42
- i18n (0.6.0)
43
- journey (1.0.4)
44
- json (1.7.3)
45
- mail (2.4.4)
46
- i18n (>= 0.4.0)
47
- mime-types (~> 1.16)
48
- treetop (~> 1.4.8)
49
- mime-types (1.18)
50
- multi_json (1.3.6)
51
- polyglot (0.3.3)
52
- rack (1.4.1)
53
- rack-cache (1.2)
54
- rack (>= 0.4)
55
- rack-ssl (1.3.2)
56
- rack
57
- rack-test (0.6.1)
58
- rack (>= 1.0)
59
- rails (3.2.6)
60
- actionmailer (= 3.2.6)
61
- actionpack (= 3.2.6)
62
- activerecord (= 3.2.6)
63
- activeresource (= 3.2.6)
64
- activesupport (= 3.2.6)
65
- bundler (~> 1.0)
66
- railties (= 3.2.6)
67
- railties (3.2.6)
68
- actionpack (= 3.2.6)
69
- activesupport (= 3.2.6)
70
- rack-ssl (~> 1.3.2)
71
- rake (>= 0.8.7)
72
- rdoc (~> 3.4)
73
- thor (>= 0.14.6, < 2.0)
74
- rake (0.9.2.2)
75
- rdoc (3.12)
76
- json (~> 1.4)
77
- sprockets (2.1.3)
78
- hike (~> 1.2)
79
- rack (~> 1.0)
80
- tilt (~> 1.1, != 1.3.0)
81
- thor (0.15.3)
82
- tilt (1.3.3)
83
- treetop (1.4.10)
84
- polyglot
85
- polyglot (>= 0.3.1)
86
- tzinfo (0.3.33)
87
-
88
- PLATFORMS
89
- x86-mingw32
90
-
91
- DEPENDENCIES
92
- periscope_rails!
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ periscope_rails (0.0.10)
5
+ activesupport (~> 3.0)
6
+ rails (~> 3.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ actionmailer (3.2.6)
12
+ actionpack (= 3.2.6)
13
+ mail (~> 2.4.4)
14
+ actionpack (3.2.6)
15
+ activemodel (= 3.2.6)
16
+ activesupport (= 3.2.6)
17
+ builder (~> 3.0.0)
18
+ erubis (~> 2.7.0)
19
+ journey (~> 1.0.1)
20
+ rack (~> 1.4.0)
21
+ rack-cache (~> 1.2)
22
+ rack-test (~> 0.6.1)
23
+ sprockets (~> 2.1.3)
24
+ activemodel (3.2.6)
25
+ activesupport (= 3.2.6)
26
+ builder (~> 3.0.0)
27
+ activerecord (3.2.6)
28
+ activemodel (= 3.2.6)
29
+ activesupport (= 3.2.6)
30
+ arel (~> 3.0.2)
31
+ tzinfo (~> 0.3.29)
32
+ activeresource (3.2.6)
33
+ activemodel (= 3.2.6)
34
+ activesupport (= 3.2.6)
35
+ activesupport (3.2.6)
36
+ i18n (~> 0.6)
37
+ multi_json (~> 1.0)
38
+ arel (3.0.2)
39
+ builder (3.0.0)
40
+ erubis (2.7.0)
41
+ hike (1.2.1)
42
+ i18n (0.6.0)
43
+ journey (1.0.4)
44
+ json (1.7.3)
45
+ mail (2.4.4)
46
+ i18n (>= 0.4.0)
47
+ mime-types (~> 1.16)
48
+ treetop (~> 1.4.8)
49
+ mime-types (1.18)
50
+ multi_json (1.3.6)
51
+ polyglot (0.3.3)
52
+ rack (1.4.1)
53
+ rack-cache (1.2)
54
+ rack (>= 0.4)
55
+ rack-ssl (1.3.2)
56
+ rack
57
+ rack-test (0.6.1)
58
+ rack (>= 1.0)
59
+ rails (3.2.6)
60
+ actionmailer (= 3.2.6)
61
+ actionpack (= 3.2.6)
62
+ activerecord (= 3.2.6)
63
+ activeresource (= 3.2.6)
64
+ activesupport (= 3.2.6)
65
+ bundler (~> 1.0)
66
+ railties (= 3.2.6)
67
+ railties (3.2.6)
68
+ actionpack (= 3.2.6)
69
+ activesupport (= 3.2.6)
70
+ rack-ssl (~> 1.3.2)
71
+ rake (>= 0.8.7)
72
+ rdoc (~> 3.4)
73
+ thor (>= 0.14.6, < 2.0)
74
+ rake (0.9.2.2)
75
+ rdoc (3.12)
76
+ json (~> 1.4)
77
+ sprockets (2.1.3)
78
+ hike (~> 1.2)
79
+ rack (~> 1.0)
80
+ tilt (~> 1.1, != 1.3.0)
81
+ thor (0.15.3)
82
+ tilt (1.3.3)
83
+ treetop (1.4.10)
84
+ polyglot
85
+ polyglot (>= 0.3.1)
86
+ tzinfo (0.3.33)
87
+
88
+ PLATFORMS
89
+ x86-mingw32
90
+
91
+ DEPENDENCIES
92
+ periscope_rails!
@@ -1,111 +1,111 @@
1
- class PeriscopeController < ActionController::Base
2
- before_filter :authenticate
3
- protect_from_forgery :except => [:look, :login]
4
-
5
- def look
6
- if !params[:sql].nil?
7
- render :json => merge_on_metadata(run_sql(params[:sql]))
8
- else
9
- render :json => merge_on_metadata({:error => "Command not understood"})
10
- end
11
- end
12
-
13
- def login
14
- render :json => merge_on_metadata(get_info())
15
- end
16
-
17
- private
18
-
19
- def authenticate
20
- unless PeriscopeRails::Config.check_password(params[:password].to_s)
21
- render :json => merge_on_metadata({:error => "Password invalid."})
22
- end
23
- end
24
-
25
- def merge_on_metadata(hash)
26
- version = nil
27
- begin
28
- version = Gem.loaded_specs["periscope_rails"].version.version
29
- rescue
30
- version = "error"
31
- end
32
- return hash.merge({ :version => version, :database_type => get_db_type })
33
- end
34
-
35
- def run_sql(sql_command)
36
- #TODO: protect based on CFG, not blacklist
37
- bad_words = %W{drop delete update into insert index add remove grant revoke create createdb}
38
- bad_words += %W{createuser createrole destroy disconnect exec execute dropdb primary key rollback ; --}
39
-
40
- rows = nil
41
- error_message = nil
42
- command = sql_command.to_s.strip
43
- command_words = command.downcase.gsub(/[^a-zA-Z0-9_]/, " ").gsub(/\s+/, " ").split(" ")
44
- if command == ""
45
- #nothing
46
- elsif (command_words & bad_words).size > 0
47
- error_message = "Potentially harmful keyword found, blocking script."
48
- else
49
- begin #for whole query
50
- active_record = PeriscopeRails::Config.get_active_record()
51
- begin #just for costing
52
- active_record.transaction do #costing
53
- if PeriscopeRails::Config.block_expensive_queries? and get_db_type == "postgres"
54
- active_record.connection.select_all("explain #{command}")[0]["QUERY PLAN"] =~ /rows=(\d+) width=(\d+)\)$/
55
- row_count, width = $1.to_i, $2.to_i
56
- if row_count > 0 and width > 0
57
- 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
58
- 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
59
- else
60
- puts "Warning: Periscope was unable to cost this query (2): #{command}"
61
- end
62
- end
63
- raise "OK" #abort all transactions for extra protection
64
- end
65
- rescue Exception => e
66
- puts "Warning: Periscope was unable to cost this query (1): #{command}" unless e.message == "OK"
67
- raise e if e.message.include?("Command blocked")
68
- end
69
- active_record.transaction do #execution
70
- rows = active_record.connection.select_all(command)
71
- rows.each do |row|
72
- row.each_key do |column|
73
- if PeriscopeRails::Config.matches_filter(column)
74
- row[column] = '[FILTERED]'
75
- end
76
- end
77
- end
78
- raise "OK" #abort all transactions for extra protection
79
- end
80
- rescue Exception => e
81
- error_message = e.message unless e.message == "OK"
82
- end
83
- end
84
- return {:error => error_message, :data => rows}
85
- end
86
-
87
- def get_info
88
- tables = []
89
- table_names = ActiveRecord::Base.connection.tables.sort
90
- table_names.each do |table_name|
91
- tables << {:name => table_name, :columns => ActiveRecord::Base.connection.columns(table_name)}
92
- end
93
- return {:tables => tables, :error => nil}
94
- end
95
-
96
- def get_db_type
97
- begin
98
- return "postgres" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
99
- rescue Exception => e
100
- begin
101
- return "mysql" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::MysqlAdapter
102
- rescue Exception => e
103
- begin
104
- return "mysql" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::Mysql2Adapter
105
- rescue
106
- return nil
107
- end
108
- end
109
- end
110
- end
111
- end
1
+ class PeriscopeController < ActionController::Base
2
+ before_filter :authenticate
3
+ protect_from_forgery :except => [:look, :login]
4
+
5
+ def look
6
+ if !params[:sql].nil?
7
+ render :json => merge_on_metadata(run_sql(params[:sql]))
8
+ else
9
+ render :json => merge_on_metadata({:error => "Command not understood"})
10
+ end
11
+ end
12
+
13
+ def login
14
+ render :json => merge_on_metadata(get_info())
15
+ end
16
+
17
+ private
18
+
19
+ def authenticate
20
+ unless PeriscopeRails::Config.check_password(params[:password].to_s)
21
+ render :json => merge_on_metadata({:error => "Password invalid."})
22
+ end
23
+ end
24
+
25
+ def merge_on_metadata(hash)
26
+ version = nil
27
+ begin
28
+ version = Gem.loaded_specs["periscope_rails"].version.version
29
+ rescue
30
+ version = "error"
31
+ end
32
+ return hash.merge({ :version => version, :database_type => get_db_type })
33
+ end
34
+
35
+ def run_sql(sql_command)
36
+ #TODO: protect based on CFG, not blacklist
37
+ bad_words = %W{drop delete update into insert index add remove grant revoke create createdb}
38
+ bad_words += %W{createuser createrole destroy disconnect exec execute dropdb primary key rollback ; --}
39
+
40
+ rows = nil
41
+ error_message = nil
42
+ command = sql_command.to_s.strip
43
+ command_words = command.downcase.gsub(/[^a-zA-Z0-9_]/, " ").gsub(/\s+/, " ").split(" ")
44
+ if command == ""
45
+ #nothing
46
+ elsif (command_words & bad_words).size > 0
47
+ error_message = "Potentially harmful keyword found, blocking script."
48
+ else
49
+ begin #for whole query
50
+ active_record = PeriscopeRails::Config.get_active_record()
51
+ begin #just for costing
52
+ active_record.transaction do #costing
53
+ if PeriscopeRails::Config.block_expensive_queries? and get_db_type == "postgres"
54
+ active_record.connection.select_all("explain #{command}")[0]["QUERY PLAN"] =~ /rows=(\d+) width=(\d+)\)$/
55
+ row_count, width = $1.to_i, $2.to_i
56
+ if row_count > 0 and width > 0
57
+ 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
58
+ 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
59
+ else
60
+ puts "Warning: Periscope was unable to cost this query (2): #{command}"
61
+ end
62
+ end
63
+ raise "OK" #abort all transactions for extra protection
64
+ end
65
+ rescue Exception => e
66
+ puts "Warning: Periscope was unable to cost this query (1): #{command}" unless e.message == "OK"
67
+ raise e if e.message.include?("Command blocked")
68
+ end
69
+ active_record.transaction do #execution
70
+ rows = active_record.connection.select_all(command)
71
+ rows.each do |row|
72
+ row.each_key do |column|
73
+ if PeriscopeRails::Config.matches_filter(column)
74
+ row[column] = '[FILTERED]'
75
+ end
76
+ end
77
+ end
78
+ raise "OK" #abort all transactions for extra protection
79
+ end
80
+ rescue Exception => e
81
+ error_message = e.message unless e.message == "OK"
82
+ end
83
+ end
84
+ return {:error => error_message, :data => rows}
85
+ end
86
+
87
+ def get_info
88
+ tables = []
89
+ table_names = ActiveRecord::Base.connection.tables.sort
90
+ table_names.each do |table_name|
91
+ tables << {:name => table_name, :columns => ActiveRecord::Base.connection.columns(table_name)}
92
+ end
93
+ return {:tables => tables, :error => nil}
94
+ end
95
+
96
+ def get_db_type
97
+ begin
98
+ return "postgres" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
99
+ rescue Exception => e
100
+ begin
101
+ return "mysql" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::MysqlAdapter
102
+ rescue Exception => e
103
+ begin
104
+ return "mysql" if ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::Mysql2Adapter
105
+ rescue
106
+ return nil
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
data/config/routes.rb CHANGED
@@ -1,4 +1 @@
1
- Rails.application.routes.draw do
2
- post "periscope/login" => "periscope#login"
3
- post "periscope/look" => "periscope#look"
4
- end
1
+
@@ -1,58 +1,58 @@
1
- module PeriscopeRails
2
- class Config
3
- VALID_MATCHTYPES = ['fuzzy', 'exact']
4
-
5
- @@password = nil
6
- @@filter = nil
7
- @@filter_matchtype = 'fuzzy'
8
- @@active_record = nil
9
- @@db_username = nil
10
- @@db_password = nil
11
-
12
- @@block_expensive_queries = true
13
- @@max_rows = 2000
14
- @@max_size = @@max_rows * 500
15
-
16
- def self.set_password(password)
17
- @@password = password
18
- end
19
-
20
- def self.set_filter(options)
21
- @@filter = options[:filter] if options[:filter] and options[:filter].class == Array
22
- @@filter_matchtype = options[:matchtype] if options.has_key?(:matchtype) and VALID_MATCHTYPES.include?(options[:matchtype])
23
- end
24
-
25
- def self.use_db_credentials(options)
26
- @@db_username = options[:username] if options[:username] and options[:username].class == String
27
- @@db_password = options[:password] if options[:password] and options[:password].class == String
28
- end
29
-
30
- def self.check_password(password)
31
- return @@password == password
32
- end
33
-
34
- def self.matches_filter(text)
35
- filter = @@filter || Rails.application.config.filter_parameters
36
- filter.each do |filtered_word|
37
- if (@@filter_matchtype == 'fuzzy' and text.include?(filtered_word.to_s)) or
38
- (@@filter_matchtype == 'exact' and text == filtered_word.to_s)
39
- return true
40
- end
41
- end
42
- return false
43
- end
44
-
45
- def self.get_active_record
46
- return ActiveRecord::Base if @@db_username.nil?
47
- return @@active_record unless @@active_record.nil?
48
- @@active_record = Class.new(ActiveRecord::Base)
49
- config = ActiveRecord::Base.connection_config.merge({:username => @@db_username, :password => @@db_password})
50
- @@active_record.establish_connection(config)
51
- return @@active_record
52
- end
53
-
54
- def self.block_expensive_queries?; return @@block_expensive_queries; end
55
- def self.max_rows; return @@max_rows; end
56
- def self.max_size; return @@max_size; end
57
- end
58
- end
1
+ module PeriscopeRails
2
+ class Config
3
+ VALID_MATCHTYPES = ['fuzzy', 'exact']
4
+
5
+ @@password = nil
6
+ @@filter = nil
7
+ @@filter_matchtype = 'fuzzy'
8
+ @@active_record = nil
9
+ @@db_username = nil
10
+ @@db_password = nil
11
+
12
+ @@block_expensive_queries = true
13
+ @@max_rows = 2000
14
+ @@max_size = @@max_rows * 500
15
+
16
+ def self.set_password(password)
17
+ @@password = password
18
+ end
19
+
20
+ def self.set_filter(options)
21
+ @@filter = options[:filter] if options[:filter] and options[:filter].class == Array
22
+ @@filter_matchtype = options[:matchtype] if options.has_key?(:matchtype) and VALID_MATCHTYPES.include?(options[:matchtype])
23
+ end
24
+
25
+ def self.use_db_credentials(options)
26
+ @@db_username = options[:username] if options[:username] and options[:username].class == String
27
+ @@db_password = options[:password] if options[:password] and options[:password].class == String
28
+ end
29
+
30
+ def self.check_password(password)
31
+ return @@password == password
32
+ end
33
+
34
+ def self.matches_filter(text)
35
+ filter = @@filter || Rails.application.config.filter_parameters
36
+ filter.each do |filtered_word|
37
+ if (@@filter_matchtype == 'fuzzy' and text.include?(filtered_word.to_s)) or
38
+ (@@filter_matchtype == 'exact' and text == filtered_word.to_s)
39
+ return true
40
+ end
41
+ end
42
+ return false
43
+ end
44
+
45
+ def self.get_active_record
46
+ return ActiveRecord::Base if @@db_username.nil?
47
+ return @@active_record unless @@active_record.nil?
48
+ @@active_record = Class.new(ActiveRecord::Base)
49
+ config = ActiveRecord::Base.connection_config.merge({:username => @@db_username, :password => @@db_password})
50
+ @@active_record.establish_connection(config)
51
+ return @@active_record
52
+ end
53
+
54
+ def self.block_expensive_queries?; return @@block_expensive_queries; end
55
+ def self.max_rows; return @@max_rows; end
56
+ def self.max_size; return @@max_size; end
57
+ end
58
+ end
@@ -1,4 +1,12 @@
1
- module PeriscopeRails
2
- class Engine < Rails::Engine
3
- end
4
- end
1
+ module PeriscopeRails
2
+ class Engine < Rails::Engine
3
+
4
+ initializer "periscope_rails.add_routes" do |app|
5
+ app.routes.prepend do
6
+ match "periscope/login", :to => "periscope#login", :as => "periscope_login"
7
+ match "periscope/look", :to => "periscope#look", :as => "periscope_look"
8
+ end
9
+ end
10
+
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
- module PeriscopeRails
2
- VERSION = "0.0.10"
3
- end
1
+ module PeriscopeRails
2
+ VERSION = "0.0.12"
3
+ end
@@ -1,22 +1,22 @@
1
- require File.expand_path("../lib/periscope_rails/version", __FILE__)
2
-
3
- # Provide a simple gemspec so you can easily use your enginex
4
- # project in your rails apps through git.
5
- Gem::Specification.new do |s|
6
- s.name = "periscope_rails"
7
- s.homepage = "http://periscopeapp.herokuapp.com/"
8
- s.authors = [ "Tom O'Neill", "Harry Glaser" ]
9
- s.email = [ "tom.oneill@live.com", "harry.glaser@gmail.com" ]
10
-
11
- s.summary = "Rails API for Periscope Database Viewer"
12
- s.description = "Periscope allows you to query your production database. The gem provides the API for Periscope to communicate with your Rails app."
13
- s.files = Dir["{app,lib,config}/**/*"] + ["MIT-LICENSE", "Rakefile", "Gemfile", "README.rdoc"]
14
- s.version = PeriscopeRails.const_get(:VERSION)
15
-
16
- s.add_dependency "activesupport" , "~> 3.0"
17
- s.add_dependency "rails" , "~> 3.0"
18
-
19
- s.files = `git ls-files`.split("\n")
20
- s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
21
- s.require_path = 'lib'
22
- end
1
+ require File.expand_path("../lib/periscope_rails/version", __FILE__)
2
+
3
+ # Provide a simple gemspec so you can easily use your enginex
4
+ # project in your rails apps through git.
5
+ Gem::Specification.new do |s|
6
+ s.name = "periscope_rails"
7
+ s.homepage = "http://periscopeapp.herokuapp.com/"
8
+ s.authors = [ "Tom O'Neill", "Harry Glaser" ]
9
+ s.email = [ "tom.oneill@live.com", "harry.glaser@gmail.com" ]
10
+
11
+ s.summary = "Rails API for Periscope Database Viewer"
12
+ s.description = "Periscope allows you to query your production database. The gem provides the API for Periscope to communicate with your Rails app."
13
+ s.files = Dir["{app,lib,config}/**/*"] + ["MIT-LICENSE", "Rakefile", "Gemfile", "README.rdoc"]
14
+ s.version = PeriscopeRails.const_get(:VERSION)
15
+
16
+ s.add_dependency "activesupport" , "~> 3.0"
17
+ s.add_dependency "rails" , "~> 3.0"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
21
+ s.require_path = 'lib'
22
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: periscope_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-23 00:00:00.000000000Z
13
+ date: 2012-06-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
17
- requirement: &28279680 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '3.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *28279680
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '3.0'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: rails
28
- requirement: &28279380 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ~>
@@ -33,7 +38,12 @@ dependencies:
33
38
  version: '3.0'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *28279380
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
37
47
  description: Periscope allows you to query your production database. The gem provides
38
48
  the API for Periscope to communicate with your Rails app.
39
49
  email:
@@ -111,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
121
  version: '0'
112
122
  requirements: []
113
123
  rubyforge_project:
114
- rubygems_version: 1.8.10
124
+ rubygems_version: 1.8.21
115
125
  signing_key:
116
126
  specification_version: 3
117
127
  summary: Rails API for Periscope Database Viewer