rack-webconsole 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-webconsole (0.0.5)
4
+ rack-webconsole (0.1.0)
5
5
  json
6
6
  rack
7
7
 
data/History ADDED
@@ -0,0 +1,9 @@
1
+ === 0.1.0 / 2011-07-27
2
+
3
+ + The request object is now exposed in the console through #request method
4
+ + Various UI enhancements
5
+ ! Fix bug where Sandbox locals were much more than those defined by the user.
6
+
7
+ === 0.0.5 / 2011-07-26
8
+
9
+ ! Protection against CSRF attacks.
data/Readme.md CHANGED
@@ -71,7 +71,8 @@ And it works! Fire up the server, go to any page and press the ` ` ` key.
71
71
 
72
72
  In the console you can issue whatever Ruby commands you want, except multiline commands. Local variables are kept, so you can get a more IRB-esque feeling.
73
73
 
74
- To reset all local variables, just issue the `reload!` command.
74
+ * `reload!` resets all local variables
75
+ * `request` returns the current page request object
75
76
 
76
77
  ##Under the hood
77
78
 
@@ -95,6 +96,3 @@ You can also build the documentation with the following command:
95
96
  ## Copyright
96
97
 
97
98
  Copyright (c) 2011 Codegram. See LICENSE for details.
98
-
99
-
100
-
@@ -47,7 +47,11 @@ module Rack
47
47
  private
48
48
 
49
49
  def asset(file)
50
- ::File.read(::File.join(::File.dirname(__FILE__), '..', '..', '..', 'public', file))
50
+ @assets ||= {}
51
+ output = ::File.open(::File.join(::File.dirname(__FILE__), '..', '..', '..', 'public', file), 'r:UTF-8') do |f|
52
+ f.read
53
+ end
54
+ @assets[file] ||= output
51
55
  end
52
56
  end
53
57
  end
@@ -35,6 +35,9 @@ module Rack
35
35
  # Regenerate the security token
36
36
  Webconsole::Repl.reset_token
37
37
 
38
+ # Expose the request object to the Repl
39
+ Webconsole::Repl.request = Rack::Request.new(env)
40
+
38
41
  # Inject the html, css and js code to the view
39
42
  response_body.gsub!('</body>', "#{code}</body>")
40
43
 
@@ -1,5 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'json'
3
+ require 'digest/sha1'
4
+
3
5
  module Rack
4
6
  class Webconsole
5
7
  # {Repl} is a Rack middleware acting as a Ruby evaluator application.
@@ -9,7 +11,9 @@ module Rack
9
11
  # variables and stores them in an instance variable for further retrieval.
10
12
  #
11
13
  class Repl
12
- @@token = nil
14
+ @@request = nil
15
+ @@token = nil
16
+
13
17
  class << self
14
18
  # Returns the autogenerated security token
15
19
  #
@@ -22,6 +26,20 @@ module Rack
22
26
  def reset_token
23
27
  @@token = Digest::SHA1.hexdigest("#{rand(36**8)}#{Time.now}")[4..20]
24
28
  end
29
+
30
+ # Returns the original request for inspection purposes.
31
+ #
32
+ # @return [Rack::Request] the original request
33
+ def request
34
+ @@request
35
+ end
36
+
37
+ # Sets the original request for inspection purposes.
38
+ #
39
+ # @param [Rack::Request] the original request
40
+ def request=(request)
41
+ @@request = request
42
+ end
25
43
  end
26
44
 
27
45
  # Honor the Rack contract by saving the passed Rack application in an ivar.
@@ -57,7 +75,7 @@ module Rack
57
75
 
58
76
  result = $sandbox.instance_eval """
59
77
  result = (#{params['query']})
60
- ls = (local_variables.map(&:to_sym) - [#{boilerplate.join(', ')}])
78
+ ls = (local_variables.map(&:to_sym) - [#{boilerplate.map(&:inspect).join(', ')}])
61
79
  @locals ||= {}
62
80
  @locals.update(ls.inject({}) do |hash, value|
63
81
  hash.update({value => eval(value.to_s)})
@@ -21,6 +21,13 @@ module Rack
21
21
  $sandbox = Sandbox.new
22
22
  'ok'
23
23
  end
24
+
25
+ # Returns the current page request object for inspection purposes.
26
+ #
27
+ # @return [Rack::Request] the current page request object.
28
+ def request
29
+ Webconsole::Repl.request
30
+ end
24
31
  end
25
32
  end
26
33
  end
@@ -2,6 +2,6 @@
2
2
  module Rack
3
3
  class Webconsole
4
4
  # rack-webconsole version number.
5
- VERSION = "0.0.5"
5
+ VERSION = "0.1.0"
6
6
  end
7
7
  end
@@ -1,45 +1,83 @@
1
- #console {
1
+ #rack-webconsole {
2
2
  opacity: 0.9;
3
3
  z-index: 999;
4
4
  background: #000;
5
5
  color: #DDD;
6
6
  font-family: monospace;
7
- padding-left: 15px;
8
- padding-top: 10px;
9
- height: 25%;
7
+ height: 40%;
10
8
  position: fixed;
11
9
  width: 100%;
12
10
  bottom: 0px;
13
11
  left: 0px;
14
12
  right:0px;
15
- border-top: 3px solid #DEDEDE;
16
- overflow: hidden;
13
+ outline-top: 3px solid #DEDEDE;
14
+ box-shadow: 0px -4px 5px rgba(0,0,0,0.5);
15
+ -moz-box-shadow: 0px -4px 5px rgba(0,0,0,0.5);
16
+ -webkit-box-shadow: 0px -4px 5px rgba(0,0,0,0.5);
17
+ font-size: 11px;
18
+ }
19
+ #rack-webconsole div.query{
20
+ margin-top: 10px;
21
+ font-weight: bold;
17
22
  padding-top: 10px;
23
+ border-top: 1px dashed #333;
24
+ margin-bottom: 5px;
25
+ }
26
+ #rack-webconsole div.query:first-child{
27
+ margin-top: 0px;
28
+ padding-top: 0px;
29
+ border-top: none;
18
30
  }
19
- #console form div, #console form span {
31
+ #rack-webconsole div.result{
32
+ font-weight: normal;
33
+ }
34
+ #rack-webconsole form div, #console form span {
20
35
  font-size: 14px;
21
- background: #000;
22
36
  border: 0px;
23
37
  font-family: monospace;
24
38
  color: #FFF;
25
39
  }
26
- #console form div.results{
40
+ #rack-webconsole form div.results_wrapper{
41
+ height: 100%;
42
+ width: 100%;
27
43
  position: absolute;
28
- bottom: 40px;
29
- margin-bottom: -10px;
44
+ overflow-x: auto;
45
+ }
46
+ #rack-webconsole form div.results{
47
+ padding: 10px;
48
+ padding-bottom: 40px;
30
49
  }
31
- #console form div.input{
32
- width: 97%;
50
+ #rack-webconsole .prompt{
51
+ width: 30px;
52
+ text-align: center;
53
+ display: block;
54
+ float: left;
55
+ height: 25px;
56
+ line-height: 25px;
57
+ }
58
+ #rack-webconsole form div.input{
59
+ width: 100%;
33
60
  position: absolute;
34
- bottom: 10px;
61
+ bottom: 0px;
62
+ height: 30px;
63
+ padding-top: 10px;
64
+ background: #000;
35
65
  }
36
- #console form div.input input{
66
+ #rack-webconsole form div.input input{
67
+ -webkit-box-sizing: border-box;
68
+ -moz-box-sizing: border-box;
69
+ box-sizing: border-box;
37
70
  margin-top: 0px;
38
71
  margin-bottom: 0px;
39
- width: 97%;
72
+ width: 100%;
40
73
  font-size: 14px;
41
- background: #000;
74
+ background: transparent;
42
75
  border: 0px;
43
76
  font-family: monospace;
44
77
  color: #FFF;
45
78
  }
79
+ #rack-webconsole .input .input_box{
80
+ margin-left: 30px;
81
+ margin-right: 10px;
82
+ display: block;
83
+ }
@@ -1,11 +1,15 @@
1
- <div id="console">
1
+ <div id="rack-webconsole">
2
2
  <form accept-charset="UTF-8" action="/webconsole" method="post">
3
3
  <input name="utf8" type="hidden" value="✓"/>
4
- <div class="results">
4
+ <div class="results_wrapper">
5
+ <div class="results">
6
+ </div>
5
7
  </div>
6
8
  <div class="input">
7
- <span>>></span>
8
- <input id="query" name="query" type="text" />
9
+ <span class="prompt">>></span>
10
+ <span class="input_box">
11
+ <input id="query" name="query" type="text" />
12
+ </div>
9
13
  </div>
10
14
  </form>
11
15
  </div>
data/public/webconsole.js CHANGED
@@ -1,19 +1,22 @@
1
1
  $(document).ready(function() {
2
- $("#console").hide();
2
+ $("#rack-webconsole").hide();
3
3
  $(this).keypress(function(event) {
4
4
  if (event.which == 96) {
5
- $("#console").slideToggle('fast', function() {
5
+ $("#rack-webconsole").slideToggle('fast', function() {
6
6
  if ($(this).is(':visible')) {
7
- $("#console form input").focus();
7
+ $("#rack-webconsole form input").focus();
8
+ $("#rack-webconsole .results_wrapper").scrollTop(
9
+ $("#rack-webconsole .results").height()
10
+ );
8
11
  } else {
9
- $("#console form input").blur();
12
+ $("#rack-webconsole form input").blur();
10
13
  }
11
14
  });
12
15
  event.preventDefault();
13
16
  }
14
17
  });
15
18
  });
16
- $('#console form').submit(function(e){
19
+ $('#rack-webconsole form').submit(function(e){
17
20
  e.preventDefault();
18
21
  });
19
22
  String.prototype.escapeHTML = function () {
@@ -25,9 +28,9 @@ String.prototype.escapeHTML = function () {
25
28
  );
26
29
  };
27
30
 
28
- $("#console form input").keyup(function(event) {
31
+ $("#rack-webconsole form input").keyup(function(event) {
29
32
  if(event.which == 13) {
30
- /*$.post('/webconsole', $("#console form").serialize());*/
33
+ /*$.post('/webconsole', $("#rack-webconsole form").serialize());*/
31
34
  var query = $("#query").val();
32
35
  $.ajax({
33
36
  url: '/webconsole',
@@ -35,9 +38,12 @@ $("#console form input").keyup(function(event) {
35
38
  dataType: 'json',
36
39
  data: ({query: query, token: "TOKEN"}),
37
40
  success: function (data) {
38
- var q = "<div>>> " + query.escapeHTML() + "</div>";
39
- var r = "<div>=> " + data.result.escapeHTML() + "</div>";
40
- $("#console .results").append(q + r);
41
+ var q = "<div class='query'>>> " + query.escapeHTML() + "</div>";
42
+ var r = "<div class='result'>=> " + data.result.escapeHTML() + "</div>";
43
+ $("#rack-webconsole .results").append(q + r);
44
+ $("#rack-webconsole .results_wrapper").scrollTop(
45
+ $("#rack-webconsole .results").height()
46
+ );
41
47
  $("#query").val('');
42
48
  }
43
49
  });
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  class AssetClass
@@ -34,7 +35,7 @@ module Rack
34
35
  asset_class = AssetClass.new
35
36
  js = asset_class.js_code
36
37
 
37
- js.must_match /\$\("#console"\)/
38
+ js.must_match /\$\("#rack-webconsole"\)/
38
39
  js.must_match /escapeHTML/
39
40
  end
40
41
  end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
  require 'ostruct'
3
4
 
@@ -66,6 +67,19 @@ module Rack
66
67
  response.must_match /escapeHTML/m # js
67
68
  end
68
69
 
70
+ it 'exposes the request object to the console' do
71
+ valid_html = "<!DOCTYPE html>\n<html>\n<head>\n <title>Testapp</title>\n <link href=\"/assets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n <script src=\"/assets/application.js\" type=\"text/javascript\"></script>\n <meta content=\"authenticity_token\" name=\"csrf-param\" />\n<meta content=\"26Ls63zdKBiCXoqU5CuG6KqVbeMYydRqOuovP+DXx8g=\" name=\"csrf-token\" />\n</head>\n<body>\n\n<h1> Hello bitches </h1>\n\n<p> Lorem ipsum dolor sit amet. </p>\n\n\n</body>\n</html>\n"
72
+
73
+ @app = lambda { |env| [200, {'Content-Type' => 'text/html'}, OpenStruct.new({:body => valid_html})] }
74
+
75
+ env = {'PATH_INFO' => '/some_path'}
76
+ assets = Webconsole::Assets.new(@app)
77
+
78
+ assets.call(env)
79
+
80
+ Webconsole::Repl.request.env['PATH_INFO'].must_equal '/some_path'
81
+ end
82
+
69
83
  end
70
84
  end
71
85
 
@@ -43,6 +43,7 @@ module Rack
43
43
 
44
44
  JSON.parse(response)['result'].must_equal "32"
45
45
  $sandbox.instance_variable_get(:@locals)[:a].must_equal 4
46
+ $sandbox.instance_variable_get(:@locals).size.must_equal 1
46
47
  end
47
48
 
48
49
  it "returns any found errors prepended with 'Error:'" do
@@ -92,6 +93,13 @@ module Rack
92
93
  Webconsole::Repl.token.must_be_kind_of String
93
94
  end
94
95
  end
96
+ describe '#request= and #request' do
97
+ it 'returns the request object' do
98
+ request = stub
99
+ Webconsole::Repl.request = request
100
+ Webconsole::Repl.request.must_equal request
101
+ end
102
+ end
95
103
  end
96
104
 
97
105
  end
@@ -36,5 +36,15 @@ module Rack
36
36
  end
37
37
  end
38
38
 
39
+ describe "request" do
40
+ it 'returns the request object' do
41
+ @sandbox = Webconsole::Sandbox.new
42
+ request = Rack::Request.new({'PATH_INFO' => '/some_path'})
43
+ Webconsole::Repl.request = request
44
+
45
+ @sandbox.request.must_equal request
46
+ end
47
+ end
48
+
39
49
  end
40
50
  end
metadata CHANGED
@@ -1,119 +1,153 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rack-webconsole
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.5
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Josep M. Bach
9
14
  - Josep Jaume Rey
10
15
  - Oriol Gual
11
16
  autorequire:
12
17
  bindir: bin
13
18
  cert_chain: []
14
- date: 2011-07-25 00:00:00.000000000 +02:00
19
+
20
+ date: 2011-07-27 00:00:00 +02:00
15
21
  default_executable:
16
- dependencies:
17
- - !ruby/object:Gem::Dependency
18
- name: rack
19
- requirement: &2151839300 !ruby/object:Gem::Requirement
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ requirement: &id001 !ruby/object:Gem::Requirement
20
25
  none: false
21
- requirements:
22
- - - ! '>='
23
- - !ruby/object:Gem::Version
24
- version: '0'
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ prerelease: false
25
34
  type: :runtime
35
+ name: rack
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
26
47
  prerelease: false
27
- version_requirements: *2151839300
28
- - !ruby/object:Gem::Dependency
48
+ type: :runtime
29
49
  name: json
30
- requirement: &2151838600 !ruby/object:Gem::Requirement
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ requirement: &id003 !ruby/object:Gem::Requirement
31
53
  none: false
32
- requirements:
33
- - - ! '>='
34
- - !ruby/object:Gem::Version
35
- version: '0'
36
- type: :runtime
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
37
61
  prerelease: false
38
- version_requirements: *2151838600
39
- - !ruby/object:Gem::Dependency
62
+ type: :development
40
63
  name: minitest
41
- requirement: &2151838060 !ruby/object:Gem::Requirement
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ requirement: &id004 !ruby/object:Gem::Requirement
42
67
  none: false
43
- requirements:
44
- - - ! '>='
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
- type: :development
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
48
75
  prerelease: false
49
- version_requirements: *2151838060
50
- - !ruby/object:Gem::Dependency
76
+ type: :development
51
77
  name: purdytest
52
- requirement: &2151837520 !ruby/object:Gem::Requirement
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ requirement: &id005 !ruby/object:Gem::Requirement
53
81
  none: false
54
- requirements:
55
- - - ! '>='
56
- - !ruby/object:Gem::Version
57
- version: '0'
58
- type: :development
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
59
89
  prerelease: false
60
- version_requirements: *2151837520
61
- - !ruby/object:Gem::Dependency
90
+ type: :development
62
91
  name: mocha
63
- requirement: &2151836720 !ruby/object:Gem::Requirement
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ requirement: &id006 !ruby/object:Gem::Requirement
64
95
  none: false
65
- requirements:
66
- - - ! '>='
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- type: :development
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
70
103
  prerelease: false
71
- version_requirements: *2151836720
72
- - !ruby/object:Gem::Dependency
104
+ type: :development
73
105
  name: yard
74
- requirement: &2151836080 !ruby/object:Gem::Requirement
106
+ version_requirements: *id006
107
+ - !ruby/object:Gem::Dependency
108
+ requirement: &id007 !ruby/object:Gem::Requirement
75
109
  none: false
76
- requirements:
77
- - - ! '>='
78
- - !ruby/object:Gem::Version
79
- version: '0'
80
- type: :development
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
81
117
  prerelease: false
82
- version_requirements: *2151836080
83
- - !ruby/object:Gem::Dependency
118
+ type: :development
84
119
  name: bluecloth
85
- requirement: &2151835520 !ruby/object:Gem::Requirement
120
+ version_requirements: *id007
121
+ - !ruby/object:Gem::Dependency
122
+ requirement: &id008 !ruby/object:Gem::Requirement
86
123
  none: false
87
- requirements:
88
- - - ! '>='
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- type: :development
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
92
131
  prerelease: false
93
- version_requirements: *2151835520
94
- - !ruby/object:Gem::Dependency
95
- name: rake
96
- requirement: &2151834600 !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
132
  type: :development
103
- prerelease: false
104
- version_requirements: *2151834600
133
+ name: rake
134
+ version_requirements: *id008
105
135
  description: Rack-based console inside your web applications
106
- email:
136
+ email:
107
137
  - info@codegram.com
108
138
  executables: []
139
+
109
140
  extensions: []
141
+
110
142
  extra_rdoc_files: []
111
- files:
143
+
144
+ files:
112
145
  - .gitignore
113
146
  - .rvmrc
114
147
  - .travis.yml
115
148
  - Gemfile
116
149
  - Gemfile.lock
150
+ - History
117
151
  - Rakefile
118
152
  - Readme.md
119
153
  - lib/rack-webconsole.rb
@@ -138,35 +172,38 @@ files:
138
172
  has_rdoc: true
139
173
  homepage: http://github.com/codegram/rack-webconsole
140
174
  licenses: []
175
+
141
176
  post_install_message:
142
177
  rdoc_options: []
143
- require_paths:
178
+
179
+ require_paths:
144
180
  - lib
145
- required_ruby_version: !ruby/object:Gem::Requirement
181
+ required_ruby_version: !ruby/object:Gem::Requirement
146
182
  none: false
147
- requirements:
148
- - - ! '>='
149
- - !ruby/object:Gem::Version
150
- version: '0'
151
- segments:
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ hash: 3
187
+ segments:
152
188
  - 0
153
- hash: -1999695551081588916
154
- required_rubygems_version: !ruby/object:Gem::Requirement
189
+ version: "0"
190
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
191
  none: false
156
- requirements:
157
- - - ! '>='
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- segments:
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ hash: 3
196
+ segments:
161
197
  - 0
162
- hash: -1999695551081588916
198
+ version: "0"
163
199
  requirements: []
200
+
164
201
  rubyforge_project: rack-webconsole
165
- rubygems_version: 1.6.2
202
+ rubygems_version: 1.6.0
166
203
  signing_key:
167
204
  specification_version: 3
168
205
  summary: Rack-based console inside your web applications
169
- test_files:
206
+ test_files:
170
207
  - spec/rack/webconsole/asset_helpers_spec.rb
171
208
  - spec/rack/webconsole/assets_spec.rb
172
209
  - spec/rack/webconsole/repl_spec.rb