web_sandbox_console 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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +36 -0
- data/app/assets/config/web_sandbox_console_manifest.js +2 -0
- data/app/assets/javascripts/web_sandbox_console/application.js +16 -0
- data/app/assets/javascripts/web_sandbox_console/home.js +2 -0
- data/app/assets/stylesheets/web_sandbox_console/application.css +69 -0
- data/app/assets/stylesheets/web_sandbox_console/home.css +4 -0
- data/app/controllers/web_sandbox_console/application_controller.rb +15 -0
- data/app/controllers/web_sandbox_console/home_controller.rb +15 -0
- data/app/helpers/web_sandbox_console/application_helper.rb +4 -0
- data/app/helpers/web_sandbox_console/home_helper.rb +4 -0
- data/app/jobs/web_sandbox_console/application_job.rb +4 -0
- data/app/mailers/web_sandbox_console/application_mailer.rb +6 -0
- data/app/models/web_sandbox_console/application_record.rb +5 -0
- data/app/views/layouts/web_sandbox_console/application.html.erb +14 -0
- data/app/views/web_sandbox_console/home/eval_code.js.erb +4 -0
- data/app/views/web_sandbox_console/home/index.html.erb +15 -0
- data/config/routes.rb +5 -0
- data/lib/generators/web_sandbox_console/USAGE +8 -0
- data/lib/generators/web_sandbox_console/templates/web_sandbox_console.rb +22 -0
- data/lib/generators/web_sandbox_console/web_sandbox_console_generator.rb +8 -0
- data/lib/tasks/web_sandbox_console_tasks.rake +4 -0
- data/lib/web_sandbox_console/common.rb +19 -0
- data/lib/web_sandbox_console/configuration.rb +48 -0
- data/lib/web_sandbox_console/engine.rb +6 -0
- data/lib/web_sandbox_console/safe_ruby.rb +70 -0
- data/lib/web_sandbox_console/sandbox.rb +47 -0
- data/lib/web_sandbox_console/version.rb +3 -0
- data/lib/web_sandbox_console.rb +18 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 69751d9ed5eefe3885a9c45e9897858d69546627b6eb9898ab8b77fcea429027
|
4
|
+
data.tar.gz: 01a2f21f2aee4e4ec9cbdaadf79053b55b51abaeff142064c4e0865331f83d12
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f9a54707f95d100575ec671f5c44c331761b98a6f89205cb7fedf0a7762be281d29051f34041f677fa3f4cb859090c9d341d6300f3a081d37d2ba05f4145aab
|
7
|
+
data.tar.gz: 49a29b84ba6790c2fa91fc6b6759d38b13647002f71247da0b72c5278e1356b925b6a79e824e1aba0094d92bda24e443aba5b8dc838057a131fb140e94c2deb9
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2020 dongmingyan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# WebSandboxConsole
|
2
|
+
工作中许多时候,都需要我们连到服务器进入rails c下查询或一些数据。当运维人员时间比较充足的时候,情况还相对较好;如果一个运维人员,同时负责许多台服务器,让其帮忙负责查询就会浪费很大的一部分时间;为了解决这个问题,我想找到一种即安全、又方便的查询控制台,搜索了一些gem后,发现并没有符合我预期的gem,于是决定写一个相关功能的gem,旨在提供一个安全、方便的web 控制台.
|
3
|
+
|
4
|
+
这个控制台提供一个类似沙盒的安全环境,这里做的所有数据操作,都会回滚(不会真正写入数据库);你可以配置 ip 白名单、基本认证,来增加访问安全性;另外在这个沙盒中,内置禁止了linux命令的执行,所以不用担心,ruby越界去做了linux的相关事情,当然还禁止了文件的新建、删除、目录的新建、删除等一系列方法;如果你需要更强的限制,你还可以去配置你想禁止使用的哪些方法等等,具体看配置文件。
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
使用过程相当简单,和一般的gem,安装后你不用特殊去配置任何东西,就可以正常使用。所有的配置选项都是可选的。
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
在 Gemfile 中添加:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'web_sandbox_console'
|
14
|
+
```
|
15
|
+
|
16
|
+
然后执行:
|
17
|
+
```bash
|
18
|
+
$ bundle
|
19
|
+
```
|
20
|
+
|
21
|
+
此时,如果是在本地,你访问 `http://localhost:3000/web_sandbox_console` 就能看到web控制台了。
|
22
|
+
|
23
|
+
## 配置
|
24
|
+
在bundle后 你就可以正常使用gem了,如果你需要配置的话,才用来看这步
|
25
|
+
|
26
|
+
在 rails 项目路径下,执行:
|
27
|
+
```bash
|
28
|
+
$ rails g web_sandbox_console
|
29
|
+
```
|
30
|
+
|
31
|
+
这会在项目路径下,创建如下文件(文件中已详细说明用法)
|
32
|
+
```ruby
|
33
|
+
# config/initializers/web_sandbox_console.rb
|
34
|
+
|
35
|
+
# web_sandbox_console 配置文件
|
36
|
+
# 以下配置 都是可选的 缺少的情况下用默认值 或者 不生效
|
37
|
+
WebSandboxConsole.setup do |config|
|
38
|
+
# 配置 引擎挂载位置
|
39
|
+
# config.mount_engine_route_path = '/web_sandbox_console'
|
40
|
+
|
41
|
+
# 配置 ip 白名单
|
42
|
+
# config.ip_whitelist = %w(192.168.23.12 192.145.2.0/24)
|
43
|
+
|
44
|
+
# # 配置 基本认证
|
45
|
+
# config.http_basic_auth = {name: 'dmy', password: '123456'}
|
46
|
+
|
47
|
+
# # 配置 黑名单 类方法
|
48
|
+
# config.class_method_blacklist = {File: %i(delete read write),Dir: %i(new delete mkdir)}
|
49
|
+
|
50
|
+
# # 配置 黑名单 实例方法
|
51
|
+
# config.instance_method_blacklist = {Kernel: %i(system exec `),File: %i(chmod chown)}
|
52
|
+
|
53
|
+
# # 配置 日志路径 默认路径位于项目下
|
54
|
+
# config.console_log_path = "log/web_sandbox_console.log"
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
Contribution directions go here.
|
60
|
+
|
61
|
+
## License
|
62
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'WebSandboxConsole'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
require 'bundler/gem_tasks'
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'test'
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
32
|
+
t.verbose = false
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
task default: :test
|
@@ -0,0 +1,16 @@
|
|
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 any plugin's vendor/assets/javascripts directory 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. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require turbolinks
|
16
|
+
//= require_tree .
|
@@ -0,0 +1,69 @@
|
|
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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
16
|
+
|
17
|
+
p{
|
18
|
+
line-height: 18px;
|
19
|
+
}
|
20
|
+
|
21
|
+
.container{
|
22
|
+
margin: 20px 15px;
|
23
|
+
}
|
24
|
+
|
25
|
+
.output-content{
|
26
|
+
height: 600px;
|
27
|
+
font-size: 14px;
|
28
|
+
background-color: #272822;
|
29
|
+
color: #F8F8F2;
|
30
|
+
overflow: auto;
|
31
|
+
line-height: 12px;
|
32
|
+
padding-left: 10px;
|
33
|
+
margin-top: 20px;
|
34
|
+
}
|
35
|
+
|
36
|
+
.text_area_box{
|
37
|
+
font-size: 15px;
|
38
|
+
height: 150px;
|
39
|
+
width: 500px;
|
40
|
+
border-width: 2px;
|
41
|
+
}
|
42
|
+
|
43
|
+
.clear-button{
|
44
|
+
background: red;
|
45
|
+
height: 30px;
|
46
|
+
width: 100px;
|
47
|
+
font-size: 15px;
|
48
|
+
color: white;
|
49
|
+
cursor: pointer;
|
50
|
+
border-radius: 5px;
|
51
|
+
}
|
52
|
+
|
53
|
+
.send-button{
|
54
|
+
background: #272822;
|
55
|
+
height: 30px;
|
56
|
+
width: 150px;
|
57
|
+
font-size: 15px;
|
58
|
+
color: white;
|
59
|
+
cursor: pointer;
|
60
|
+
}
|
61
|
+
|
62
|
+
.reset-button{
|
63
|
+
background: red;
|
64
|
+
color: white;
|
65
|
+
height: 30px;
|
66
|
+
font-size: 15px;
|
67
|
+
color: 15px;
|
68
|
+
cursor: pointer;
|
69
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WebSandboxConsole
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
protect_from_forgery with: :exception
|
4
|
+
|
5
|
+
# 限制ip
|
6
|
+
def restrict_ip
|
7
|
+
return unless ip_whitelist = WebSandboxConsole.ip_whitelist
|
8
|
+
|
9
|
+
request_ip = IPAddr.new(request.remote_ip)
|
10
|
+
unless ip_whitelist.any? {|legal_ip| IPAddr.new(legal_ip).include?(request_ip)}
|
11
|
+
render text: "非法请求"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_dependency "web_sandbox_console/application_controller"
|
2
|
+
|
3
|
+
module WebSandboxConsole
|
4
|
+
class HomeController < ApplicationController
|
5
|
+
before_action :restrict_ip
|
6
|
+
http_basic_authenticate_with name: WebSandboxConsole.http_basic_auth[:name], password: WebSandboxConsole.http_basic_auth[:password] if WebSandboxConsole.http_basic_auth.present?
|
7
|
+
|
8
|
+
def index
|
9
|
+
end
|
10
|
+
|
11
|
+
def eval_code
|
12
|
+
@results = Sandbox.new(params[:code]).evalotor
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Web sandbox console</title>
|
5
|
+
<%= stylesheet_link_tag "web_sandbox_console/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "web_sandbox_console/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<div class="container">
|
11
|
+
<%= yield %>
|
12
|
+
</div>
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
控制台 index
|
2
|
+
|
3
|
+
<div class="console">
|
4
|
+
<%= form_tag(web_sandbox_console.eval_code_path, remote: true, class: 'form') do %>
|
5
|
+
<%= text_area_tag :code, '', class: 'text_area_box'%>
|
6
|
+
<input type="reset" value="重置" class='reset-button'>
|
7
|
+
<%= submit_tag '提交', data: { disable_with: "已发送,处理中..." }, class: 'send-button' %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<%= button_tag '清除输出', type: 'button', onclick: "$('.output-content').empty();", class: 'clear-button' %>
|
13
|
+
|
14
|
+
<div class="output-content">
|
15
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# web_sandbox_console 配置文件
|
2
|
+
# 以下配置 都是可选的 缺少的情况下用默认值 或者 不生效
|
3
|
+
WebSandboxConsole.setup do |config|
|
4
|
+
# 配置 引擎挂载位置
|
5
|
+
# config.mount_engine_route_path = '/web_sandbox_console'
|
6
|
+
|
7
|
+
# 配置 ip 白名单
|
8
|
+
# config.ip_whitelist = %w(192.168.23.12 192.145.2.0/24)
|
9
|
+
|
10
|
+
# # 配置 基本认证
|
11
|
+
# config.http_basic_auth = {name: 'dmy', password: '123456'}
|
12
|
+
|
13
|
+
# # 配置 黑名单 类方法
|
14
|
+
# config.class_method_blacklist = {File: %i(delete read write),Dir: %i(new delete mkdir)}
|
15
|
+
|
16
|
+
# # 配置 黑名单 实例方法
|
17
|
+
# config.instance_method_blacklist = {Kernel: %i(system exec `),File: %i(chmod chown)}
|
18
|
+
|
19
|
+
# # 配置 日志路径 默认路径位于项目下
|
20
|
+
# config.console_log_path = "log/web_sandbox_console.log"
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module WebSandboxConsole
|
2
|
+
module Common
|
3
|
+
# uuid 方便取出日志
|
4
|
+
def log_p(msg_or_exce, uuid = nil)
|
5
|
+
@logger ||= Logger.new(log_path)
|
6
|
+
|
7
|
+
if msg_or_exce.respond_to?(:message)
|
8
|
+
@logger.info "#{uuid}:" + msg_or_exce.message
|
9
|
+
@logger.info "#{uuid}:" + msg_or_exce.backtrace.join("|||")
|
10
|
+
else
|
11
|
+
@logger.info "#{uuid}:" + msg_or_exce.inspect
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def log_path
|
16
|
+
"#{Rails.root}/#{self.console_log_path || "log/web_sandbox_console.log"}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module WebSandboxConsole
|
2
|
+
# ip 白名单
|
3
|
+
mattr_accessor :ip_whitelist
|
4
|
+
# 基本认证
|
5
|
+
mattr_accessor :http_basic_auth
|
6
|
+
# 常量 黑名单 数组
|
7
|
+
mattr_accessor :constant_blacklist
|
8
|
+
# 类方法 黑名单 hash
|
9
|
+
mattr_accessor :class_method_blacklist
|
10
|
+
# 实例方法 黑名单 hash
|
11
|
+
mattr_accessor :instance_method_blacklist
|
12
|
+
# 日志路径
|
13
|
+
mattr_accessor :console_log_path
|
14
|
+
# 挂载 引擎路由位置
|
15
|
+
mattr_accessor :mount_engine_route_path
|
16
|
+
|
17
|
+
# 默认 引擎路由位置
|
18
|
+
@@mount_engine_route_path = '/web_sandbox_console'
|
19
|
+
|
20
|
+
# 内置 实例方法 黑名单
|
21
|
+
INSTANT_METOD_BUILT_IN_BLACKLIST = {
|
22
|
+
Kernel: %i(system exec `),
|
23
|
+
File: %i(chmod chown)
|
24
|
+
}
|
25
|
+
|
26
|
+
# 内置 类方法 黑名单
|
27
|
+
CLASS_METHOD_BUILT_IN_BLACKLIST = {
|
28
|
+
Kernel: %i(system exec `),
|
29
|
+
File: %i(chmod chown new open delete read write),
|
30
|
+
Dir: %i(new delete mkdir)
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
def self.setup
|
35
|
+
yield self
|
36
|
+
indifferent_access_deal(%w(http_basic_auth))
|
37
|
+
end
|
38
|
+
|
39
|
+
# 无差别hash 处理
|
40
|
+
def self.indifferent_access_deal(mattr_arr)
|
41
|
+
mattr_arr.each do |mattr|
|
42
|
+
current_hash = send(mattr)
|
43
|
+
next unless current_hash.is_a?(Hash)
|
44
|
+
send("#{mattr}=", current_hash.with_indifferent_access)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module WebSandboxConsole
|
2
|
+
module SafeRuby
|
3
|
+
# 初始化安全环境
|
4
|
+
def init_safe_env
|
5
|
+
sanitize_constants
|
6
|
+
sanitize_instance_methods
|
7
|
+
sanitize_class_methods
|
8
|
+
end
|
9
|
+
|
10
|
+
# 净化 类方法
|
11
|
+
def sanitize_class_methods
|
12
|
+
blacklist = if class_method_blacklist
|
13
|
+
merge_method_hash(CLASS_METHOD_BUILT_IN_BLACKLIST, class_method_blacklist)
|
14
|
+
else
|
15
|
+
CLASS_METHOD_BUILT_IN_BLACKLIST
|
16
|
+
end
|
17
|
+
|
18
|
+
blacklist.each do |klass, methods|
|
19
|
+
klass = Object.const_get(klass)
|
20
|
+
methods.each do |method|
|
21
|
+
next if klass.singleton_methods.exclude?(method)
|
22
|
+
klass.singleton_class.send(:undef_method, method)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# 净化 实例方法
|
28
|
+
def sanitize_instance_methods
|
29
|
+
blacklist = if instance_method_blacklist
|
30
|
+
merge_method_hash(INSTANT_METOD_BUILT_IN_BLACKLIST,instance_method_blacklist)
|
31
|
+
else
|
32
|
+
INSTANT_METOD_BUILT_IN_BLACKLIST
|
33
|
+
end
|
34
|
+
|
35
|
+
blacklist.each do |klass, methods|
|
36
|
+
klass = Object.const_get(klass)
|
37
|
+
methods.each do |method|
|
38
|
+
next if (klass != Kernel) && klass.instance_methods.exclude?(method)
|
39
|
+
klass.send(:undef_method, method)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# 净化 常量
|
45
|
+
def sanitize_constants
|
46
|
+
return unless constant_blacklist
|
47
|
+
constant_blacklist.each do |const|
|
48
|
+
Object.send(:remove_const, const) if defined?(const)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# 将两个hash 内部数组也同时合并,并去重
|
53
|
+
def merge_method_hash(hash1, hash2)
|
54
|
+
# 格式统一
|
55
|
+
hash2.transform_keys!(&:to_sym).transform_values!{|val_arr| val_arr.map{|val| val.to_sym}}
|
56
|
+
# 共有的key
|
57
|
+
common_keys = hash2.keys & hash1.keys
|
58
|
+
# hash2 特有keys
|
59
|
+
hash2_special_keys = hash2.keys - hash1.keys
|
60
|
+
# 特有keys 直接合到 hash1
|
61
|
+
hash1.merge!(hash2.slice(hash2_special_keys))
|
62
|
+
# 共用keys 数组去重
|
63
|
+
common_keys.each do |key|
|
64
|
+
hash1[key] = (hash1[key] | hash2[key]).uniq
|
65
|
+
end
|
66
|
+
hash1
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module WebSandboxConsole
|
2
|
+
class Sandbox
|
3
|
+
attr_accessor :code
|
4
|
+
attr_accessor :uuid
|
5
|
+
|
6
|
+
def initialize(code = nil)
|
7
|
+
@code = escape_single_quote_mark(code)
|
8
|
+
@uuid = SecureRandom.uuid
|
9
|
+
end
|
10
|
+
|
11
|
+
def evalotor
|
12
|
+
`bundle exec rails runner '#{runner_code}'`
|
13
|
+
get_result
|
14
|
+
end
|
15
|
+
|
16
|
+
def runner_code
|
17
|
+
str =<<-CODE
|
18
|
+
WebSandboxConsole.init_safe_env
|
19
|
+
result = nil
|
20
|
+
begin
|
21
|
+
ActiveRecord::Base.transaction(requires_new: true) do
|
22
|
+
result = eval(#{self.code.inspect})
|
23
|
+
raise ActiveRecord::Rollback
|
24
|
+
end
|
25
|
+
rescue Exception => e
|
26
|
+
WebSandboxConsole.log_p(e, "#{self.uuid}")
|
27
|
+
rescue SyntaxError => e
|
28
|
+
WebSandboxConsole.log_p(e, "#{self.uuid}")
|
29
|
+
end
|
30
|
+
WebSandboxConsole.log_p(result, "#{self.uuid}")
|
31
|
+
CODE
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_result
|
35
|
+
last_10_lines = `tail -n 10 #{WebSandboxConsole.log_path} | grep #{self.uuid}`
|
36
|
+
|
37
|
+
last_10_lines.split("\n").map do |line|
|
38
|
+
line.split("#{self.uuid}:").last.split("|||")
|
39
|
+
end.flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
# 转义单引号
|
43
|
+
def escape_single_quote_mark(code)
|
44
|
+
code.gsub(/'/,'"')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "web_sandbox_console/engine"
|
2
|
+
require "web_sandbox_console/configuration"
|
3
|
+
require "web_sandbox_console/common.rb"
|
4
|
+
require "web_sandbox_console/safe_ruby"
|
5
|
+
require "web_sandbox_console/sandbox"
|
6
|
+
|
7
|
+
|
8
|
+
module WebSandboxConsole
|
9
|
+
extend Common
|
10
|
+
extend SafeRuby
|
11
|
+
|
12
|
+
# 初始化默认路由
|
13
|
+
Engine.initializer 'rails_web_sandbox_console.mount_default' do
|
14
|
+
Rails.application.routes.prepend do
|
15
|
+
mount WebSandboxConsole::Engine => WebSandboxConsole.mount_engine_route_path
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: web_sandbox_console
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- dongmingyan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-04-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: jquery-rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: 工作中许多时候,都需要我们连到服务器进入rails c下查询或一些数据。当运维人员时间比较充足的时候,情况还相对较好;如果一个运维人员,同时负责许多台服务器,让其帮忙负责查询就会浪费很大的一部分时间;为了解决这个问题,我想找到一种即安全、又方便的查询控制台,搜索了一些gem后,发现并没有符合我预期的gem,于是决定写一个相关功能的gem,旨在提供一个安全、方便的web
|
42
|
+
控制台.
|
43
|
+
email:
|
44
|
+
- dongmingyan01@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- MIT-LICENSE
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- app/assets/config/web_sandbox_console_manifest.js
|
53
|
+
- app/assets/javascripts/web_sandbox_console/application.js
|
54
|
+
- app/assets/javascripts/web_sandbox_console/home.js
|
55
|
+
- app/assets/stylesheets/web_sandbox_console/application.css
|
56
|
+
- app/assets/stylesheets/web_sandbox_console/home.css
|
57
|
+
- app/controllers/web_sandbox_console/application_controller.rb
|
58
|
+
- app/controllers/web_sandbox_console/home_controller.rb
|
59
|
+
- app/helpers/web_sandbox_console/application_helper.rb
|
60
|
+
- app/helpers/web_sandbox_console/home_helper.rb
|
61
|
+
- app/jobs/web_sandbox_console/application_job.rb
|
62
|
+
- app/mailers/web_sandbox_console/application_mailer.rb
|
63
|
+
- app/models/web_sandbox_console/application_record.rb
|
64
|
+
- app/views/layouts/web_sandbox_console/application.html.erb
|
65
|
+
- app/views/web_sandbox_console/home/eval_code.js.erb
|
66
|
+
- app/views/web_sandbox_console/home/index.html.erb
|
67
|
+
- config/routes.rb
|
68
|
+
- lib/generators/web_sandbox_console/USAGE
|
69
|
+
- lib/generators/web_sandbox_console/templates/web_sandbox_console.rb
|
70
|
+
- lib/generators/web_sandbox_console/web_sandbox_console_generator.rb
|
71
|
+
- lib/tasks/web_sandbox_console_tasks.rake
|
72
|
+
- lib/web_sandbox_console.rb
|
73
|
+
- lib/web_sandbox_console/common.rb
|
74
|
+
- lib/web_sandbox_console/configuration.rb
|
75
|
+
- lib/web_sandbox_console/engine.rb
|
76
|
+
- lib/web_sandbox_console/safe_ruby.rb
|
77
|
+
- lib/web_sandbox_console/sandbox.rb
|
78
|
+
- lib/web_sandbox_console/version.rb
|
79
|
+
homepage: https://github.com/dongmy54/web_sandbox_console
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubygems_version: 3.0.8
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: 一个安全、方便的web 控制台
|
102
|
+
test_files: []
|