web-console 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of web-console might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +121 -0
- data/Rakefile +48 -0
- data/app/assets/javascripts/web_console/application.js +4 -0
- data/app/assets/javascripts/web_console/console_sessions.js +24 -0
- data/app/assets/stylesheets/web_console/application.css +13 -0
- data/app/assets/stylesheets/web_console/console_sessions.css +8 -0
- data/app/controllers/web_console/application_controller.rb +12 -0
- data/app/controllers/web_console/console_sessions_controller.rb +23 -0
- data/app/helpers/web_console/application_helper.rb +4 -0
- data/app/helpers/web_console/console_session_helper.rb +4 -0
- data/app/models/web_console/console_session.rb +107 -0
- data/app/views/layouts/web_console/application.html.erb +14 -0
- data/app/views/web_console/console_sessions/index.html.erb +4 -0
- data/config/routes.rb +5 -0
- data/lib/web-console.rb +1 -0
- data/lib/web_console.rb +7 -0
- data/lib/web_console/engine.rb +38 -0
- data/lib/web_console/fiber.rb +48 -0
- data/lib/web_console/repl.rb +59 -0
- data/lib/web_console/repl/dummy.rb +38 -0
- data/lib/web_console/repl/irb.rb +61 -0
- data/lib/web_console/stream.rb +27 -0
- data/lib/web_console/version.rb +3 -0
- data/test/controllers/web_console/console_sessions_controller_test.rb +57 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +15 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +26591 -0
- data/test/dummy/log/test.log +78368 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/0280bb38c5058cc31c4fcd8c392a5ec4 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/05bd7b24c0a86010ebb28b50ac7cad52 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2a48be7daff14cf56911b263cbe017c7 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3a37adb5ebd079cf67dae597b8c2e4f8 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/4f79e5f341043e081becefe4952395c5 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/508ab3c25833ea537a5e3fc90df33595 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/5a8ab22e707dfc7ba00691f90e054d7e +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/5adcb7569cdd03204d650e285f19351f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/654a1bde557d359b957dc0aa12b0dfa0 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/71f57313d6c92f5483915a6c2d79a506 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/7ec0041a47c34b44e52e836c01454a1a +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/a1534e0c08b73ad82c2edb8c364caa66 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/a841a3af20a321912acfed87036438fb +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ad8eea7f774b674c29708ca90952764f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b0741545b4917192ba7b5e803c2e323d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b3159b06164dd474ff8efc3c84aefbba +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b40b7c5b2003544010f30f0bd3fb81b2 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/bbbe6a3ce382662666a355d708c83d2d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/c4e26d8dbebb3afd7013acfefa564dd1 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ca53fb2717d5aac2f1c3939d9444fe3b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/d6b37d10680a997662c379d0ff7cad27 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e1d89809967e81220dca66770c50aa67 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e3d5cafc071e8f9a8efc88fddf721947 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f44e2a41bd51a92a84f99847ea675ba3 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f4a21ed9cebe2c83a9d988504dc6720b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f4d45273ff5b44879dab0a16805f4309 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f5deea0ae9671fdb035aefc6c4ba1109 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/0280bb38c5058cc31c4fcd8c392a5ec4 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/05bd7b24c0a86010ebb28b50ac7cad52 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2a48be7daff14cf56911b263cbe017c7 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/3824a9e25e846a4916b3ac1d67060782 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/3a37adb5ebd079cf67dae597b8c2e4f8 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/4f79e5f341043e081becefe4952395c5 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/508ab3c25833ea537a5e3fc90df33595 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/5a8ab22e707dfc7ba00691f90e054d7e +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/5adcb7569cdd03204d650e285f19351f +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/632346eda030b596f513fff2de181743 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/654a1bde557d359b957dc0aa12b0dfa0 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/71f57313d6c92f5483915a6c2d79a506 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/9b9aee85f29dc573732fbb4001ceda00 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/a841a3af20a321912acfed87036438fb +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/bbbe6a3ce382662666a355d708c83d2d +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/ca53fb2717d5aac2f1c3939d9444fe3b +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d6b37d10680a997662c379d0ff7cad27 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e1d89809967e81220dca66770c50aa67 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e3d5cafc071e8f9a8efc88fddf721947 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f44e2a41bd51a92a84f99847ea675ba3 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f4a21ed9cebe2c83a9d988504dc6720b +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f4d45273ff5b44879dab0a16805f4309 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f5deea0ae9671fdb035aefc6c4ba1109 +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/helpers/web_console/console_session_helper_test.rb +6 -0
- data/test/models/console_session_test.rb +110 -0
- data/test/test_helper.rb +15 -0
- data/test/web_console/repl/dummy_test.rb +54 -0
- data/test/web_console/repl/irb_test.rb +108 -0
- data/test/web_console/repl_test.rb +15 -0
- data/test/web_console_test.rb +91 -0
- data/vendor/assets/javascripts/jquery.console.js +727 -0
- metadata +303 -0
data/lib/web_console.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
require 'rails/engine'
|
3
|
+
require 'jquery-rails'
|
4
|
+
|
5
|
+
module WebConsole
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
isolate_namespace WebConsole
|
8
|
+
|
9
|
+
config.web_console = ActiveSupport::OrderedOptions.new
|
10
|
+
config.web_console.default_mount_path = '/console'
|
11
|
+
config.web_console.whitelisted_ips = '127.0.0.1'
|
12
|
+
|
13
|
+
initializer 'web_console.add_default_route' do |app|
|
14
|
+
# While we don't need the route in the test environment, we define it
|
15
|
+
# there as well, so we can easily test it.
|
16
|
+
if Rails.env.development? || Rails.env.test?
|
17
|
+
app.routes.append do
|
18
|
+
mount WebConsole::Engine => app.config.web_console.default_mount_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
initializer 'web_console.process_whitelisted_ips' do
|
24
|
+
# Ensure that it is an array of IPAddr instances and it is defaulted to
|
25
|
+
# 127.0.0.1 if not precent. Only unique entries are left in the end.
|
26
|
+
config.web_console.whitelisted_ips = Array(config.web_console.whitelisted_ips)
|
27
|
+
config.web_console.whitelisted_ips.map! do |ip|
|
28
|
+
ip.is_a?(IPAddr) ? ip : IPAddr.new(ip.presence || '127.0.0.1')
|
29
|
+
end.uniq!
|
30
|
+
|
31
|
+
# IPAddr instances can cover whole networks, so simplify the #include?
|
32
|
+
# check for the most common case.
|
33
|
+
def (config.web_console.whitelisted_ips).include?(ip)
|
34
|
+
ip.is_a?(IPAddr) ? super : any? { |net| net.include?(ip.to_s) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module WebConsole
|
2
|
+
# Poor Man's Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)
|
3
|
+
# (c) 2008 Aman Gupta (tmm1)
|
4
|
+
#
|
5
|
+
# For the purposes of our REPL adapters there is a need for fiber invocation
|
6
|
+
# across threads. The native implementation does not support that.
|
7
|
+
class FiberError < StandardError; end
|
8
|
+
|
9
|
+
class Fiber
|
10
|
+
def initialize
|
11
|
+
raise ArgumentError, 'new Fiber requires a block' unless block_given?
|
12
|
+
|
13
|
+
@yield = Queue.new
|
14
|
+
@resume = Queue.new
|
15
|
+
|
16
|
+
@thread = Thread.new { @yield.push [ *yield(*@resume.pop) ] }
|
17
|
+
@thread.abort_on_exception = true
|
18
|
+
@thread[:fiber] = self
|
19
|
+
end
|
20
|
+
attr_reader :thread
|
21
|
+
|
22
|
+
def resume(*args)
|
23
|
+
raise FiberError, 'dead fiber called' unless @thread.alive?
|
24
|
+
@resume.push(args)
|
25
|
+
result = @yield.pop
|
26
|
+
result.size > 1 ? result : result.first
|
27
|
+
end
|
28
|
+
|
29
|
+
def yield(*args)
|
30
|
+
@yield.push(args)
|
31
|
+
result = @resume.pop
|
32
|
+
result.size > 1 ? result : result.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.yield(*args)
|
36
|
+
raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
|
37
|
+
fiber.yield(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.current
|
41
|
+
Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect
|
45
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)}>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
3
|
+
module WebConsole
|
4
|
+
module REPL
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# Registry of REPL implementations mapped to their correspondent adapter
|
8
|
+
# classes.
|
9
|
+
#
|
10
|
+
# Don't manually alter the registry. Use WebConsole::REPL.register_adapter
|
11
|
+
# for adding entries.
|
12
|
+
def adapters
|
13
|
+
@adapters ||= {}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Register an adapter into the adapters registry.
|
17
|
+
#
|
18
|
+
# Registration maps and adapter class to an existing REPL implementation,
|
19
|
+
# that we call an adaptee constant. If the adaptee constant is not given,
|
20
|
+
# it is automatically derived from the adapter class name.
|
21
|
+
#
|
22
|
+
# For example, adapter named +WebConsole::REPL::IRB+ will derive the
|
23
|
+
# adaptee constant to +::IRB+.
|
24
|
+
#
|
25
|
+
# If a block is given, it would be evaluated right after the adapter
|
26
|
+
# registration.
|
27
|
+
def register_adapter(adapter_class, adaptee_constant = nil, options = {})
|
28
|
+
if adaptee_constant.is_a?(Hash)
|
29
|
+
options = adaptee_constant
|
30
|
+
adaptee_constant = nil
|
31
|
+
end
|
32
|
+
adaptee_constant = adapter_class if options[:standalone]
|
33
|
+
adaptee_constant ||= derive_adaptee_constant_from(adapter_class)
|
34
|
+
adapters[adaptee_constant] = adapter_class
|
35
|
+
yield if block_given?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get the default adapter for the given application.
|
39
|
+
#
|
40
|
+
# By default the application will be Rails.application and the adapter
|
41
|
+
# will be chosen from Rails.application.config.console.
|
42
|
+
#
|
43
|
+
# If no suitible adapter is found for the configured Rails console, a dummy
|
44
|
+
# adapter will be used. You can evaluate code in it, but it won't support
|
45
|
+
# any advanced features, like multiline code evaluation.
|
46
|
+
def default(app = Rails.application)
|
47
|
+
adapters[app.config.console || ::IRB] || adapters[Dummy]
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def derive_adaptee_constant_from(cls, suffix = 'REPL')
|
52
|
+
"::#{cls.name.split('::').last.gsub(/#{suffix}$/i, '')}".constantize
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Require the builtin adapters.
|
58
|
+
require 'web_console/repl/irb'
|
59
|
+
require 'web_console/repl/dummy'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'web_console/stream'
|
2
|
+
|
3
|
+
module WebConsole
|
4
|
+
module REPL
|
5
|
+
# == Dummy\ Adapter
|
6
|
+
#
|
7
|
+
# Dummy adapter that is used as a fallback for REPL with no adapters.
|
8
|
+
#
|
9
|
+
# It provides only the most basic code evaluation with no multiline code
|
10
|
+
# support.
|
11
|
+
class Dummy
|
12
|
+
def initialize(binding = TOPLEVEL_BINDING)
|
13
|
+
@binding = binding
|
14
|
+
end
|
15
|
+
|
16
|
+
def prompt
|
17
|
+
'>> '
|
18
|
+
end
|
19
|
+
|
20
|
+
def send_input(input)
|
21
|
+
eval_result = nil
|
22
|
+
streams_output = Stream.threadsafe_capture! do
|
23
|
+
eval_result = @binding.eval(input).inspect
|
24
|
+
end
|
25
|
+
"#{streams_output}=> #{eval_result}\n"
|
26
|
+
rescue Exception => exc
|
27
|
+
exc.backtrace.join("\n")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
register_adapter Dummy, standalone: true do
|
32
|
+
require 'rails/console/app'
|
33
|
+
require 'rails/console/helpers'
|
34
|
+
|
35
|
+
TOPLEVEL_BINDING.eval('self').send(:include, Rails::ConsoleMethods)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'irb'
|
2
|
+
require 'web_console/fiber'
|
3
|
+
require 'web_console/stream'
|
4
|
+
|
5
|
+
module WebConsole
|
6
|
+
module REPL
|
7
|
+
# == IRB\ Adapter
|
8
|
+
#
|
9
|
+
# Adapter for the IRB REPL, which is the default Ruby on Rails console.
|
10
|
+
class IRB
|
11
|
+
# For some reason™ we have to be ::IRB::StdioInputMethod subclass to get
|
12
|
+
# #prompt populated.
|
13
|
+
#
|
14
|
+
# Not a pretty OOP, but for now, we just have to deal with it.
|
15
|
+
class FiberInputMethod < ::IRB::StdioInputMethod
|
16
|
+
def initialize; end
|
17
|
+
|
18
|
+
def gets
|
19
|
+
@previous = Fiber.yield
|
20
|
+
end
|
21
|
+
|
22
|
+
def encoding
|
23
|
+
(@previous || '').encoding
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(binding = TOPLEVEL_BINDING)
|
28
|
+
initialize_irb_session!
|
29
|
+
@input = FiberInputMethod.new
|
30
|
+
@irb = ::IRB::Irb.new(::IRB::WorkSpace.new(binding), @input)
|
31
|
+
@fiber = Fiber.new { @irb.eval_input }.tap(&:resume)
|
32
|
+
finalize_irb_session!
|
33
|
+
end
|
34
|
+
|
35
|
+
def prompt
|
36
|
+
@input.prompt
|
37
|
+
end
|
38
|
+
|
39
|
+
def send_input(input)
|
40
|
+
Stream.threadsafe_capture! { @fiber.resume("#{input}\n") }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def initialize_irb_session!(ap_path = nil)
|
45
|
+
::IRB.init_config(ap_path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def finalize_irb_session!
|
49
|
+
::IRB.conf[:MAIN_CONTEXT] = @irb.context
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
register_adapter IRB do
|
54
|
+
require 'rails/console/app'
|
55
|
+
require 'rails/console/helpers'
|
56
|
+
|
57
|
+
# Include all of the rails console helpers in the IRB session.
|
58
|
+
::IRB::ExtendCommandBundle.send :include, Rails::ConsoleMethods
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module WebConsole
|
2
|
+
module Stream
|
3
|
+
extend Mutex_m
|
4
|
+
|
5
|
+
def self.threadsafe_capture!(*streams)
|
6
|
+
streams = [$stdout, $stderr] if streams.empty?
|
7
|
+
synchronize do
|
8
|
+
begin
|
9
|
+
streams_copy = streams.collect(&:dup)
|
10
|
+
replacement = Tempfile.new(name)
|
11
|
+
streams.each do |stream|
|
12
|
+
stream.reopen(replacement)
|
13
|
+
stream.sync = true
|
14
|
+
end
|
15
|
+
yield
|
16
|
+
streams.each(&:rewind)
|
17
|
+
replacement.read
|
18
|
+
ensure
|
19
|
+
replacement.unlink
|
20
|
+
streams.each_with_index do |stream, i|
|
21
|
+
stream.reopen(streams_copy[i])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module WebConsole
|
4
|
+
class ConsoleSessionsControllerTest < ActionController::TestCase
|
5
|
+
setup do
|
6
|
+
# Where does .stubs lives?
|
7
|
+
def @request.remote_ip; '127.0.0.1' end
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'index is successful' do
|
11
|
+
get :index, use_route: 'web_console'
|
12
|
+
assert_response :success
|
13
|
+
end
|
14
|
+
|
15
|
+
test 'index creates new console session' do
|
16
|
+
assert_difference 'ConsoleSession::INMEMORY_STORAGE.size' do
|
17
|
+
get :index, use_route: 'web_console'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'update updates new console session' do
|
22
|
+
get :index, use_route: 'web_console'
|
23
|
+
assert_not_nil console_session = assigns(:console_session)
|
24
|
+
|
25
|
+
put :update, id: console_session.id, input: 42, use_route: 'web_console'
|
26
|
+
assert_match %r{42}, console_session.output
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'update failes when session is no longer available' do
|
30
|
+
get :index, use_route: 'web_console'
|
31
|
+
assert_not_nil console_session = assigns(:console_session)
|
32
|
+
|
33
|
+
ConsoleSession::INMEMORY_STORAGE.delete(console_session.id)
|
34
|
+
put :update, id: console_session.id, input: 42, use_route: 'web_console'
|
35
|
+
assert_response :gone
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'blocks requests from non-whitelisted ips' do
|
39
|
+
def @request.remote_ip; '128.0.0.1' end
|
40
|
+
get :index, use_route: 'web_console'
|
41
|
+
assert_response :unauthorized
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'index generated path' do
|
45
|
+
assert_generates mount_path, {
|
46
|
+
use_route: 'web_console',
|
47
|
+
controller: 'console_sessions'
|
48
|
+
}, {}, {controller: 'console_sessions'}
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def mount_path
|
54
|
+
WebConsole::Engine.config.web_console.default_mount_path
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/test/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Dummy</title>
|
5
|
+
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
|
6
|
+
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|