rack-webconsole-pry 0.1.6 → 0.1.7
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 +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
|