rack-webconsole 0.0.5 → 0.1.0

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,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