rack-webconsole-pry 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/rack/webconsole.rb +3 -1
- data/lib/rack/webconsole/assets.rb +5 -4
- data/lib/rack/webconsole/repl.rb +15 -6
- data/lib/rack/webconsole/version.rb +1 -1
- data/public/webconsole.js +43 -53
- data/spec/rack/webconsole/assets_spec.rb +2 -3
- data/spec/rack/webconsole/repl_spec.rb +6 -12
- data/spec/rack/webconsole_spec.rb +3 -3
- metadata +4 -4
data/Gemfile.lock
CHANGED
data/lib/rack/webconsole.rb
CHANGED
@@ -51,7 +51,9 @@ module Rack
|
|
51
51
|
#
|
52
52
|
# @param [String] value key code used at keypress event to start web console.
|
53
53
|
def key_code=(value)
|
54
|
-
value = value
|
54
|
+
value = [value] unless value.kind_of?(Array)
|
55
|
+
value.map! {|v| v.to_i }
|
56
|
+
value = MultiJson::encode(value)
|
55
57
|
@@config[:key_code] = value
|
56
58
|
end
|
57
59
|
end
|
@@ -33,13 +33,14 @@ module Rack
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# Regenerate the security token
|
36
|
-
Webconsole::Repl.reset_token
|
36
|
+
token = Webconsole::Repl.reset_token(self, env)
|
37
37
|
|
38
38
|
# Expose the request object to the Repl
|
39
39
|
Webconsole::Repl.request = Rack::Request.new(env)
|
40
40
|
|
41
41
|
# Inject the html, css and js code to the view
|
42
|
-
|
42
|
+
c = code(token)
|
43
|
+
response_body.gsub!('</body>', "#{c}</body>")
|
43
44
|
|
44
45
|
headers['Content-Length'] = response_body.bytesize.to_s
|
45
46
|
|
@@ -53,10 +54,10 @@ module Rack
|
|
53
54
|
# secure.
|
54
55
|
#
|
55
56
|
# @return [String] the injectable code.
|
56
|
-
def code
|
57
|
+
def code token
|
57
58
|
html_code <<
|
58
59
|
css_code <<
|
59
|
-
render(js_code, :TOKEN =>
|
60
|
+
render(js_code, :TOKEN => token, :KEY_CODE => Webconsole.key_code)
|
60
61
|
end
|
61
62
|
|
62
63
|
private
|
data/lib/rack/webconsole/repl.rb
CHANGED
@@ -13,19 +13,28 @@ module Rack
|
|
13
13
|
#
|
14
14
|
class Repl
|
15
15
|
@@request = nil
|
16
|
-
@@
|
16
|
+
@@tokens = {}
|
17
17
|
|
18
18
|
class << self
|
19
|
+
def clear_tokens
|
20
|
+
@@tokens.each_pair do |k, v|
|
21
|
+
@@tokens.delete(k) if v <= Time.now
|
22
|
+
end
|
23
|
+
end
|
19
24
|
# Returns the autogenerated security token
|
20
25
|
#
|
21
26
|
# @return [String] the autogenerated token
|
22
|
-
def token
|
23
|
-
|
27
|
+
def token_valid? token
|
28
|
+
clear_tokens
|
29
|
+
@@tokens.keys.include?(token)
|
24
30
|
end
|
25
31
|
|
26
32
|
# Regenerates the token.
|
27
|
-
def reset_token
|
28
|
-
|
33
|
+
def reset_token(app, env)
|
34
|
+
clear_tokens
|
35
|
+
token = Digest::SHA1.hexdigest("#{rand(36**8)}#{Time.now}")[4..20]
|
36
|
+
@@tokens[token] = Time.now + 30 * 60
|
37
|
+
token
|
29
38
|
end
|
30
39
|
|
31
40
|
# Returns the original request for inspection purposes.
|
@@ -111,7 +120,7 @@ module Rack
|
|
111
120
|
private
|
112
121
|
|
113
122
|
def check_legitimate(req)
|
114
|
-
req.post? &&
|
123
|
+
req.post? && Repl.token_valid?(req.params['token'])
|
115
124
|
end
|
116
125
|
end
|
117
126
|
end
|
data/public/webconsole.js
CHANGED
@@ -10,81 +10,71 @@
|
|
10
10
|
e.preventDefault();
|
11
11
|
});
|
12
12
|
|
13
|
-
function componentToHex(c) {
|
14
|
-
var hex = c.toString(16);
|
15
|
-
return hex.length == 1 ? "0" + hex : hex;
|
16
|
-
}
|
17
|
-
|
18
|
-
function rgbToHex(r, g, b) {
|
19
|
-
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
|
20
|
-
}
|
21
13
|
var prevStyle = {
|
22
14
|
color: "#ffffff",
|
23
15
|
bold: false,
|
24
16
|
underline: false
|
25
17
|
}
|
18
|
+
|
19
|
+
// colors
|
20
|
+
var colors = {
|
21
|
+
30: "#eeeeee",
|
22
|
+
31: "#ff6c60",
|
23
|
+
32: "#a8ff60",
|
24
|
+
33: "#ffffb6",
|
25
|
+
34: "#96cbfe",
|
26
|
+
35: "#ff73fd",
|
27
|
+
36: "#c6c5fe",
|
28
|
+
37: "#eeeeee"
|
29
|
+
}
|
30
|
+
var boldColors = {
|
31
|
+
30: "#7c7c7c",
|
32
|
+
31: "#ffb6b0",
|
33
|
+
32: "#ceffac",
|
34
|
+
33: "#ffffcb",
|
35
|
+
34: "#b5dcfe",
|
36
|
+
35: "#ff9cfe",
|
37
|
+
36: "#dfdffe",
|
38
|
+
37: "#ffffff"
|
39
|
+
}
|
40
|
+
|
41
|
+
function resetBashStyle()
|
42
|
+
{
|
43
|
+
prevStyle = {
|
44
|
+
color: colors[37],
|
45
|
+
bold: 'normal',
|
46
|
+
underline: 'none'
|
47
|
+
};
|
48
|
+
}
|
26
49
|
function bashColorToHtml(bcolor)
|
27
50
|
{
|
28
|
-
// colors
|
29
|
-
var textColor = rgbToHex(238, 238, 238);
|
30
|
-
var boldColor = rgbToHex(255, 255, 255);
|
31
|
-
var strColors = "[0;30m 238 238 238 \
|
32
|
-
[1;37m 255 255 255 \
|
33
|
-
[0;34m 150 203 254 \
|
34
|
-
[1;34m 181 220 254 \
|
35
|
-
[0;32m 168 255 96 \
|
36
|
-
[1;32m 206 255 172 \
|
37
|
-
[0;36m 198 197 254 \
|
38
|
-
[1;36m 223 223 254 \
|
39
|
-
[0;31m 255 108 96 \
|
40
|
-
[1;31m 255 182 176 \
|
41
|
-
[0;35m 255 115 253 \
|
42
|
-
[1;35m 255 156 254 \
|
43
|
-
[0;33m 255 255 182 \
|
44
|
-
[1;33m 255 255 203 \
|
45
|
-
[1;30m 124 124 124 \
|
46
|
-
[0;37m 238 238 238";
|
47
|
-
var colors = {};
|
48
|
-
var boldColors = {};
|
49
|
-
var matcher = /\[([0-9;]+)m\s+(\d+)\s+(\d+)\s+(\d+)/gm;
|
50
|
-
while ((r = matcher.exec(strColors)) != null) {
|
51
|
-
components = r[1].split(";")
|
52
|
-
if (components[0] == "0")
|
53
|
-
colors[components[1]] = rgbToHex(parseInt(r[2]), parseInt(r[3]), parseInt(r[4]));
|
54
|
-
else
|
55
|
-
boldColors[components[1]] = rgbToHex(parseInt(r[2]), parseInt(r[3]), parseInt(r[4]));
|
56
|
-
}
|
57
51
|
// set values
|
58
|
-
all = bcolor.split(/;/g)
|
59
|
-
if (all.indexOf("0")
|
52
|
+
var all = bcolor.split(/;/g)
|
53
|
+
if (all.indexOf("0") > 0) // ignore anything before 0, since 0 resets
|
60
54
|
all.splice(0, all.indexOf("0"));
|
61
55
|
if (all.indexOf("0") >= 0)
|
62
|
-
|
63
|
-
color: textColor,
|
64
|
-
bold: false,
|
65
|
-
underline: false
|
66
|
-
};
|
56
|
+
resetBashStyle();
|
67
57
|
if (all.indexOf("1") >= 0)
|
68
|
-
prevStyle['bold'] =
|
58
|
+
prevStyle['bold'] = 'bold';
|
69
59
|
if (all.indexOf("4") >= 0)
|
70
|
-
prevStyle['underline'] =
|
71
|
-
if (prevStyle['bold'])
|
60
|
+
prevStyle['underline'] = 'underline';
|
61
|
+
if (prevStyle['bold'] == 'bold')
|
72
62
|
colorMap = boldColors;
|
73
63
|
else
|
74
64
|
colorMap = colors;
|
75
65
|
$.each(all, function(idx, val) {
|
76
|
-
|
77
|
-
|
66
|
+
var i = parseInt(val);
|
67
|
+
if (i > 10 && colorMap[i] != undefined)
|
68
|
+
prevStyle['color'] = colorMap[i];
|
78
69
|
});
|
79
|
-
return 'color:'+prevStyle['color']+';font-weight:'+
|
80
|
-
';text-decoration:'+
|
70
|
+
return 'color:'+prevStyle['color']+';font-weight:'+prevStyle['bold']+
|
71
|
+
';text-decoration:'+prevStyle['underline'];
|
81
72
|
}
|
82
73
|
function parseBashString(str)
|
83
74
|
{
|
84
75
|
str = str.replace(/\u001B\[([0-9;]+)m/g, function(fm, sm) {
|
85
76
|
return '</span><span style="'+bashColorToHtml(sm)+'">';
|
86
|
-
});
|
87
|
-
str = str.replace(/\n/g, "<br>");
|
77
|
+
}).replace(/\n/g, "<br>");
|
88
78
|
return '<span>'+str+'</span>';
|
89
79
|
}
|
90
80
|
$("#rack-webconsole form input").keyup(function(event) {
|
@@ -13,14 +13,13 @@ module Rack
|
|
13
13
|
|
14
14
|
describe "#code" do
|
15
15
|
it 'injects the token and key_code' do
|
16
|
-
Webconsole::Repl.stubs(:token).returns('fake_generated_token')
|
17
16
|
Webconsole.key_code = "96"
|
18
17
|
|
19
18
|
@assets = Webconsole::Assets.new(nil)
|
20
|
-
assets_code = @assets.code
|
19
|
+
assets_code = @assets.code 'fake_generated_token'
|
21
20
|
|
22
21
|
assets_code.must_match /fake_generated_token/
|
23
|
-
assets_code.must_match
|
22
|
+
assets_code.must_match /\[96\]/
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
@@ -15,8 +15,8 @@ module Rack
|
|
15
15
|
it 'evaluates the :query param in a sandbox and returns the result' do
|
16
16
|
@app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
|
17
17
|
env = {}
|
18
|
-
Webconsole::Repl.stubs(:
|
19
|
-
request = OpenStruct.new(:params => {'query' => 'a = 4; a * 2'
|
18
|
+
Webconsole::Repl.stubs(:token_valid?).returns(true)
|
19
|
+
request = OpenStruct.new(:params => {'query' => 'a = 4; a * 2'}, :post? => true)
|
20
20
|
Rack::Request.stubs(:new).returns request
|
21
21
|
|
22
22
|
@repl = Webconsole::Repl.new(@app)
|
@@ -29,8 +29,8 @@ module Rack
|
|
29
29
|
it 'maintains local state in subsequent calls thanks to an evil global variable' do
|
30
30
|
@app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
|
31
31
|
env = {}
|
32
|
-
Webconsole::Repl.stubs(:
|
33
|
-
request = OpenStruct.new(:params => {'query' => 'a = 4'
|
32
|
+
Webconsole::Repl.stubs(:token_valid?).returns(true)
|
33
|
+
request = OpenStruct.new(:params => {'query' => 'a = 4'}, :post? => true)
|
34
34
|
Rack::Request.stubs(:new).returns request
|
35
35
|
@repl = Webconsole::Repl.new(@app)
|
36
36
|
|
@@ -47,8 +47,8 @@ module Rack
|
|
47
47
|
it "returns any found errors prepended with 'Error:'" do
|
48
48
|
@app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
|
49
49
|
env = {}
|
50
|
-
Webconsole::Repl.stubs(:
|
51
|
-
request = OpenStruct.new(:params => {'query' => 'unknown_method'
|
50
|
+
Webconsole::Repl.stubs(:token_valid?).returns(true)
|
51
|
+
request = OpenStruct.new(:params => {'query' => 'unknown_method'}, :post? => true)
|
52
52
|
Rack::Request.stubs(:new).returns request
|
53
53
|
@repl = Webconsole::Repl.new(@app)
|
54
54
|
|
@@ -85,12 +85,6 @@ module Rack
|
|
85
85
|
end
|
86
86
|
|
87
87
|
describe 'class methods' do
|
88
|
-
describe '#reset_token and #token' do
|
89
|
-
it 'returns the security token' do
|
90
|
-
Webconsole::Repl.reset_token
|
91
|
-
Webconsole::Repl.token.must_be_kind_of String
|
92
|
-
end
|
93
|
-
end
|
94
88
|
describe '#request= and #request' do
|
95
89
|
it 'returns the request object' do
|
96
90
|
request = stub
|
@@ -43,13 +43,13 @@ module Rack
|
|
43
43
|
Webconsole.inject_jquery.must_equal true
|
44
44
|
end
|
45
45
|
it '#key_code accessors' do
|
46
|
-
Webconsole.key_code.must_equal "96"
|
46
|
+
Webconsole.key_code.must_equal "[96]"
|
47
47
|
Webconsole.key_code = "97"
|
48
|
-
Webconsole.key_code.must_equal "97"
|
48
|
+
Webconsole.key_code.must_equal "[97]"
|
49
49
|
end
|
50
50
|
it '#key_code setter cast parameter type' do
|
51
51
|
Webconsole.key_code = 96
|
52
|
-
Webconsole.key_code.must_equal "96"
|
52
|
+
Webconsole.key_code.must_equal "[96]"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-webconsole-pry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-06-
|
15
|
+
date: 2012-06-11 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rack
|
@@ -203,7 +203,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
203
203
|
version: '0'
|
204
204
|
segments:
|
205
205
|
- 0
|
206
|
-
hash:
|
206
|
+
hash: -3970192323891586303
|
207
207
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
208
|
none: false
|
209
209
|
requirements:
|
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
212
|
version: '0'
|
213
213
|
segments:
|
214
214
|
- 0
|
215
|
-
hash:
|
215
|
+
hash: -3970192323891586303
|
216
216
|
requirements: []
|
217
217
|
rubyforge_project: rack-webconsole-pry
|
218
218
|
rubygems_version: 1.8.24
|