periscope_rails 0.0.3 → 0.0.4
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 +94 -94
- data/app/periscope/periscope_controller.rb +76 -60
- data/config/routes.rb +3 -3
- data/lib/periscope_rails/config.rb +51 -11
- data/lib/periscope_rails/engine.rb +3 -3
- data/lib/periscope_rails/version.rb +3 -3
- data/periscope_rails.gemspec +22 -22
- metadata +17 -7
data/Gemfile.lock
CHANGED
@@ -1,94 +1,94 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
periscope_rails (0.0.1)
|
5
|
-
activesupport (~> 3.1.3)
|
6
|
-
rails (~> 3.1.3)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: http://rubygems.org/
|
10
|
-
specs:
|
11
|
-
actionmailer (3.1.3)
|
12
|
-
actionpack (= 3.1.3)
|
13
|
-
mail (~> 2.3.0)
|
14
|
-
actionpack (3.1.3)
|
15
|
-
activemodel (= 3.1.3)
|
16
|
-
activesupport (= 3.1.3)
|
17
|
-
builder (~> 3.0.0)
|
18
|
-
erubis (~> 2.7.0)
|
19
|
-
i18n (~> 0.6)
|
20
|
-
rack (~> 1.3.5)
|
21
|
-
rack-cache (~> 1.1)
|
22
|
-
rack-mount (~> 0.8.2)
|
23
|
-
rack-test (~> 0.6.1)
|
24
|
-
sprockets (~> 2.0.3)
|
25
|
-
activemodel (3.1.3)
|
26
|
-
activesupport (= 3.1.3)
|
27
|
-
builder (~> 3.0.0)
|
28
|
-
i18n (~> 0.6)
|
29
|
-
activerecord (3.1.3)
|
30
|
-
activemodel (= 3.1.3)
|
31
|
-
activesupport (= 3.1.3)
|
32
|
-
arel (~> 2.2.1)
|
33
|
-
tzinfo (~> 0.3.29)
|
34
|
-
activeresource (3.1.3)
|
35
|
-
activemodel (= 3.1.3)
|
36
|
-
activesupport (= 3.1.3)
|
37
|
-
activesupport (3.1.3)
|
38
|
-
multi_json (~> 1.0)
|
39
|
-
arel (2.2.1)
|
40
|
-
builder (3.0.0)
|
41
|
-
erubis (2.7.0)
|
42
|
-
hike (1.2.1)
|
43
|
-
i18n (0.6.0)
|
44
|
-
json (1.6.5)
|
45
|
-
mail (2.3.0)
|
46
|
-
i18n (>= 0.4.0)
|
47
|
-
mime-types (~> 1.16)
|
48
|
-
treetop (~> 1.4.8)
|
49
|
-
mime-types (1.17.2)
|
50
|
-
multi_json (1.1.0)
|
51
|
-
polyglot (0.3.3)
|
52
|
-
rack (1.3.6)
|
53
|
-
rack-cache (1.1)
|
54
|
-
rack (>= 0.4)
|
55
|
-
rack-mount (0.8.3)
|
56
|
-
rack (>= 1.0.0)
|
57
|
-
rack-ssl (1.3.2)
|
58
|
-
rack
|
59
|
-
rack-test (0.6.1)
|
60
|
-
rack (>= 1.0)
|
61
|
-
rails (3.1.3)
|
62
|
-
actionmailer (= 3.1.3)
|
63
|
-
actionpack (= 3.1.3)
|
64
|
-
activerecord (= 3.1.3)
|
65
|
-
activeresource (= 3.1.3)
|
66
|
-
activesupport (= 3.1.3)
|
67
|
-
bundler (~> 1.0)
|
68
|
-
railties (= 3.1.3)
|
69
|
-
railties (3.1.3)
|
70
|
-
actionpack (= 3.1.3)
|
71
|
-
activesupport (= 3.1.3)
|
72
|
-
rack-ssl (~> 1.3.2)
|
73
|
-
rake (>= 0.8.7)
|
74
|
-
rdoc (~> 3.4)
|
75
|
-
thor (~> 0.14.6)
|
76
|
-
rake (0.9.2.2)
|
77
|
-
rdoc (3.12)
|
78
|
-
json (~> 1.4)
|
79
|
-
sprockets (2.0.3)
|
80
|
-
hike (~> 1.2)
|
81
|
-
rack (~> 1.0)
|
82
|
-
tilt (~> 1.1, != 1.3.0)
|
83
|
-
thor (0.14.6)
|
84
|
-
tilt (1.3.3)
|
85
|
-
treetop (1.4.10)
|
86
|
-
polyglot
|
87
|
-
polyglot (>= 0.3.1)
|
88
|
-
tzinfo (0.3.31)
|
89
|
-
|
90
|
-
PLATFORMS
|
91
|
-
x86-mingw32
|
92
|
-
|
93
|
-
DEPENDENCIES
|
94
|
-
periscope_rails!
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
periscope_rails (0.0.1)
|
5
|
+
activesupport (~> 3.1.3)
|
6
|
+
rails (~> 3.1.3)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actionmailer (3.1.3)
|
12
|
+
actionpack (= 3.1.3)
|
13
|
+
mail (~> 2.3.0)
|
14
|
+
actionpack (3.1.3)
|
15
|
+
activemodel (= 3.1.3)
|
16
|
+
activesupport (= 3.1.3)
|
17
|
+
builder (~> 3.0.0)
|
18
|
+
erubis (~> 2.7.0)
|
19
|
+
i18n (~> 0.6)
|
20
|
+
rack (~> 1.3.5)
|
21
|
+
rack-cache (~> 1.1)
|
22
|
+
rack-mount (~> 0.8.2)
|
23
|
+
rack-test (~> 0.6.1)
|
24
|
+
sprockets (~> 2.0.3)
|
25
|
+
activemodel (3.1.3)
|
26
|
+
activesupport (= 3.1.3)
|
27
|
+
builder (~> 3.0.0)
|
28
|
+
i18n (~> 0.6)
|
29
|
+
activerecord (3.1.3)
|
30
|
+
activemodel (= 3.1.3)
|
31
|
+
activesupport (= 3.1.3)
|
32
|
+
arel (~> 2.2.1)
|
33
|
+
tzinfo (~> 0.3.29)
|
34
|
+
activeresource (3.1.3)
|
35
|
+
activemodel (= 3.1.3)
|
36
|
+
activesupport (= 3.1.3)
|
37
|
+
activesupport (3.1.3)
|
38
|
+
multi_json (~> 1.0)
|
39
|
+
arel (2.2.1)
|
40
|
+
builder (3.0.0)
|
41
|
+
erubis (2.7.0)
|
42
|
+
hike (1.2.1)
|
43
|
+
i18n (0.6.0)
|
44
|
+
json (1.6.5)
|
45
|
+
mail (2.3.0)
|
46
|
+
i18n (>= 0.4.0)
|
47
|
+
mime-types (~> 1.16)
|
48
|
+
treetop (~> 1.4.8)
|
49
|
+
mime-types (1.17.2)
|
50
|
+
multi_json (1.1.0)
|
51
|
+
polyglot (0.3.3)
|
52
|
+
rack (1.3.6)
|
53
|
+
rack-cache (1.1)
|
54
|
+
rack (>= 0.4)
|
55
|
+
rack-mount (0.8.3)
|
56
|
+
rack (>= 1.0.0)
|
57
|
+
rack-ssl (1.3.2)
|
58
|
+
rack
|
59
|
+
rack-test (0.6.1)
|
60
|
+
rack (>= 1.0)
|
61
|
+
rails (3.1.3)
|
62
|
+
actionmailer (= 3.1.3)
|
63
|
+
actionpack (= 3.1.3)
|
64
|
+
activerecord (= 3.1.3)
|
65
|
+
activeresource (= 3.1.3)
|
66
|
+
activesupport (= 3.1.3)
|
67
|
+
bundler (~> 1.0)
|
68
|
+
railties (= 3.1.3)
|
69
|
+
railties (3.1.3)
|
70
|
+
actionpack (= 3.1.3)
|
71
|
+
activesupport (= 3.1.3)
|
72
|
+
rack-ssl (~> 1.3.2)
|
73
|
+
rake (>= 0.8.7)
|
74
|
+
rdoc (~> 3.4)
|
75
|
+
thor (~> 0.14.6)
|
76
|
+
rake (0.9.2.2)
|
77
|
+
rdoc (3.12)
|
78
|
+
json (~> 1.4)
|
79
|
+
sprockets (2.0.3)
|
80
|
+
hike (~> 1.2)
|
81
|
+
rack (~> 1.0)
|
82
|
+
tilt (~> 1.1, != 1.3.0)
|
83
|
+
thor (0.14.6)
|
84
|
+
tilt (1.3.3)
|
85
|
+
treetop (1.4.10)
|
86
|
+
polyglot
|
87
|
+
polyglot (>= 0.3.1)
|
88
|
+
tzinfo (0.3.31)
|
89
|
+
|
90
|
+
PLATFORMS
|
91
|
+
x86-mingw32
|
92
|
+
|
93
|
+
DEPENDENCIES
|
94
|
+
periscope_rails!
|
@@ -1,60 +1,76 @@
|
|
1
|
-
class PeriscopeController <
|
2
|
-
before_filter :authenticate
|
3
|
-
protect_from_forgery :except => [:look, :login]
|
4
|
-
|
5
|
-
def look
|
6
|
-
if !params[:sql].nil?
|
7
|
-
render :json => run_sql(params[:sql])
|
8
|
-
else
|
9
|
-
render :json => {:error => "Command not understood"}
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def login
|
14
|
-
render :json => get_info()
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def authenticate
|
20
|
-
unless PeriscopeRails::Config.check_password(params[:password].to_s)
|
21
|
-
render :json => {:error => "Password invalid."}
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def run_sql(sql_command)
|
26
|
-
#TODO: protect based on CFG, not blacklist
|
27
|
-
bad_words = %W{drop delete update into insert index add remove grant revoke create createdb}
|
28
|
-
bad_words += %W{createuser createrole destroy disconnect exec execute dropdb primary key rollback ; --}
|
29
|
-
|
30
|
-
rows = nil
|
31
|
-
error_message = nil
|
32
|
-
command = sql_command.to_s.strip
|
33
|
-
command_words = command.downcase.gsub(/[^a-zA-Z0-9]/, " ").gsub(/\s+/, " ").split(" ")
|
34
|
-
if command == ""
|
35
|
-
#nothing
|
36
|
-
elsif (command_words & bad_words).size > 0
|
37
|
-
error_message = "Potentially harmful keyword found, blocking script."
|
38
|
-
else
|
39
|
-
begin
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
1
|
+
class PeriscopeController < ApplicationController
|
2
|
+
before_filter :authenticate
|
3
|
+
protect_from_forgery :except => [:look, :login]
|
4
|
+
|
5
|
+
def look
|
6
|
+
if !params[:sql].nil?
|
7
|
+
render :json => run_sql(params[:sql])
|
8
|
+
else
|
9
|
+
render :json => {:error => "Command not understood"}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def login
|
14
|
+
render :json => get_info()
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def authenticate
|
20
|
+
unless PeriscopeRails::Config.check_password(params[:password].to_s)
|
21
|
+
render :json => {:error => "Password invalid."}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_sql(sql_command)
|
26
|
+
#TODO: protect based on CFG, not blacklist
|
27
|
+
bad_words = %W{drop delete update into insert index add remove grant revoke create createdb}
|
28
|
+
bad_words += %W{createuser createrole destroy disconnect exec execute dropdb primary key rollback ; --}
|
29
|
+
|
30
|
+
rows = nil
|
31
|
+
error_message = nil
|
32
|
+
command = sql_command.to_s.strip
|
33
|
+
command_words = command.downcase.gsub(/[^a-zA-Z0-9]/, " ").gsub(/\s+/, " ").split(" ")
|
34
|
+
if command == ""
|
35
|
+
#nothing
|
36
|
+
elsif (command_words & bad_words).size > 0
|
37
|
+
error_message = "Potentially harmful keyword found, blocking script."
|
38
|
+
else
|
39
|
+
begin
|
40
|
+
#custom_db_creds = PeriscopeRails::Config.get_db_creds()
|
41
|
+
#if custom_db_creds.nil?
|
42
|
+
# active_record = ActiveRecord::Base
|
43
|
+
#else
|
44
|
+
# # TODO: Establish this connection once rather than every time a query is issued
|
45
|
+
# active_record = Class.new(ActiveRecord::Base)
|
46
|
+
# custom_db_config = ActiveRecord::Base.connection_config.merge(custom_db_creds)
|
47
|
+
# active_record.establish_connection(custom_db_config)
|
48
|
+
#end
|
49
|
+
active_record = PeriscopeRails::Config.get_active_record()
|
50
|
+
active_record.transaction do
|
51
|
+
rows = active_record.connection.select_all(command)
|
52
|
+
rows.each do |row|
|
53
|
+
row.each_key do |column|
|
54
|
+
if PeriscopeRails::Config.matches_filter(column)
|
55
|
+
row[column] = '[FILTERED]'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
raise "OK" #abort all transactions for extra protection
|
60
|
+
end
|
61
|
+
rescue Exception => e
|
62
|
+
error_message = e.message unless e.message == "OK"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
return {:error => error_message, :data => rows}
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_info
|
69
|
+
tables = []
|
70
|
+
table_names = ActiveRecord::Base.connection.tables.sort
|
71
|
+
table_names.each do |table_name|
|
72
|
+
tables << {:name => table_name, :columns => ActiveRecord::Base.connection.columns(table_name)}
|
73
|
+
end
|
74
|
+
return {:tables => tables, :error => nil}
|
75
|
+
end
|
76
|
+
end
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Rails.application.routes.draw do
|
2
|
-
post "periscope/login" => "periscope#login"
|
3
|
-
post "periscope/look" => "periscope#look"
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
post "periscope/login" => "periscope#login"
|
3
|
+
post "periscope/look" => "periscope#look"
|
4
4
|
end
|
@@ -1,11 +1,51 @@
|
|
1
|
-
module PeriscopeRails
|
2
|
-
class Config
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
+
def self.set_password(password)
|
13
|
+
@@password = password
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.set_filter(options)
|
17
|
+
@@filter = options[:filter] if options[:filter] and options[:filter].class == Array
|
18
|
+
@@filter_matchtype = options[:matchtype] if options.has_key?(:matchtype) and VALID_MATCHTYPES.include?(options[:matchtype])
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.use_db_credentials(options)
|
22
|
+
@@db_username = options[:username] if options[:username] and options[:username].class == String
|
23
|
+
@@db_password = options[:password] if options[:password] and options[:password].class == String
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.check_password(password)
|
27
|
+
return @@password == password
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.matches_filter(text)
|
31
|
+
filter = @@filter || Rails.application.config.filter_parameters
|
32
|
+
filter.each do |filtered_word|
|
33
|
+
if (@@filter_matchtype == 'fuzzy' and text.include?(filtered_word.to_s)) or
|
34
|
+
(@@filter_matchtype == 'exact' and text == filtered_word.to_s)
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return false
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.get_active_record
|
42
|
+
return ActiveRecord::Base if @@db_username.nil?
|
43
|
+
return @@active_record unless @@active_record.nil?
|
44
|
+
@@active_record = Class.new(ActiveRecord::Base)
|
45
|
+
config = ActiveRecord::Base.connection_config.merge({:username => @@db_username, :password => @@db_password})
|
46
|
+
@@active_record.establish_connection(config)
|
47
|
+
return @@active_record
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module PeriscopeRails
|
2
|
-
class Engine < Rails::Engine
|
3
|
-
end
|
1
|
+
module PeriscopeRails
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
end
|
4
4
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
module PeriscopeRails
|
2
|
-
VERSION = "0.0.
|
3
|
-
end
|
1
|
+
module PeriscopeRails
|
2
|
+
VERSION = "0.0.4"
|
3
|
+
end
|
data/periscope_rails.gemspec
CHANGED
@@ -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 = "0.0.
|
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 = "0.0.4"
|
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.
|
4
|
+
version: 0.0.4
|
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-04-
|
13
|
+
date: 2012-04-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
17
|
-
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:
|
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:
|
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:
|
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.
|
124
|
+
rubygems_version: 1.8.21
|
115
125
|
signing_key:
|
116
126
|
specification_version: 3
|
117
127
|
summary: Rails API for Periscope Database Viewer
|