RemoteWebConsole 0.1.3 → 0.1.4
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 +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +18 -0
- data/app/assets/config/webconsole_manifest.js +1 -0
- data/app/assets/stylesheets/webconsole/application.css +15 -0
- data/app/assets/stylesheets/webconsole/console.css +4 -0
- data/app/controllers/webconsole/application_controller.rb +4 -0
- data/app/controllers/webconsole/console_controller.rb +163 -0
- data/app/helpers/webconsole/application_helper.rb +4 -0
- data/app/helpers/webconsole/console_helper.rb +4 -0
- data/app/jobs/webconsole/application_job.rb +4 -0
- data/app/mailers/webconsole/application_mailer.rb +6 -0
- data/app/models/webconsole/application_record.rb +5 -0
- data/app/views/layouts/webconsole/application.html.erb +17 -0
- data/app/views/webconsole/console/connect.html.erb +0 -0
- data/app/views/webconsole/console/index.html.erb +144 -0
- data/config/routes.rb +8 -6
- data/lib/tasks/webconsole_tasks.rake +4 -0
- data/lib/webconsole/config.rb +6 -0
- data/lib/webconsole/engine.rb +5 -0
- data/lib/webconsole/version.rb +3 -0
- data/lib/webconsole.rb +6 -2
- metadata +40 -7
- data/app/controllers/webconsole/webconsole_controller.rb +0 -111
- data/app/helpers/console_helper.rb +0 -46
- data/config/locales/en.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 130aeeb342a0d697598d2beffa62a8e41912b5847d0212796d37ea47e062bd7e
|
4
|
+
data.tar.gz: 9fef7199fafeb3e8b4b6d306c0ed8dec8380fcfe4b61c8d904d052d86e371c0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fffa6d8986a335d44d9066613922a301fc5c6bdd3325408638abfe1eb0ea3f987cdc21629625ec11bfe1cbb390d118c93964d320e9a077cb1182655a537ee87
|
7
|
+
data.tar.gz: 795a316ef71700c8cd893ac8a4e359239d598ca31f38986b4110e2886073ccafff46bcaade7104483ec7cbdea7654836b340d02e556aad5c8bc069fc51f6d34c
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 Cynicallity
|
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,28 @@
|
|
1
|
+
# Webconsole
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'webconsole'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install webconsole
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
4
|
+
load "rails/tasks/engine.rake"
|
5
|
+
|
6
|
+
load "rails/tasks/statistics.rake"
|
7
|
+
|
8
|
+
require "bundler/gem_tasks"
|
9
|
+
|
10
|
+
require "rake/testtask"
|
11
|
+
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = false
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :test
|
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/webconsole .css
|
@@ -0,0 +1,15 @@
|
|
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
|
+
*/
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require_dependency "webconsole/application_controller"
|
2
|
+
|
3
|
+
module Webconsole
|
4
|
+
class ConsoleController < ApplicationController
|
5
|
+
skip_before_action :verify_authenticity_token, except: [:index]
|
6
|
+
before_action :check_admin_access, only: [:run_command]
|
7
|
+
|
8
|
+
require 'ipaddr'
|
9
|
+
require 'httparty'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
def index
|
13
|
+
if params[:ip]
|
14
|
+
@details = {
|
15
|
+
name: "Webconsole",
|
16
|
+
ip: params[:ip],
|
17
|
+
connect: true
|
18
|
+
}
|
19
|
+
else
|
20
|
+
@details = {
|
21
|
+
name: "Webconsole",
|
22
|
+
connect: false
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def connect
|
28
|
+
if not allowed_ips.any? { |block| block.include?(request.remote_ip) }
|
29
|
+
render json: {
|
30
|
+
connected: false,
|
31
|
+
message: "You are not allowed to connect to the console.",
|
32
|
+
ip: request.remote_ip
|
33
|
+
}
|
34
|
+
else
|
35
|
+
render json: {
|
36
|
+
connected: true,
|
37
|
+
ip: request.remote_ip
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_command
|
43
|
+
command = params[:command].strip
|
44
|
+
|
45
|
+
if command.nil? || command.empty?
|
46
|
+
send_response("No command specified", "error", "string")
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
if command[0, 6] == "shell "
|
51
|
+
begin
|
52
|
+
eval_result = system(command[6..-1])
|
53
|
+
status = "success"
|
54
|
+
rescue Exception => e
|
55
|
+
eval_result = e.message
|
56
|
+
status = "error"
|
57
|
+
end
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
eval_result = eval(command)
|
61
|
+
status = "success"
|
62
|
+
rescue Exception => e
|
63
|
+
eval_result = e.message.to_s
|
64
|
+
status = "error"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
puts "Result of command: #{eval_result}"
|
69
|
+
|
70
|
+
result = parse_command_response(eval_result)
|
71
|
+
|
72
|
+
send_response(
|
73
|
+
result[:result],
|
74
|
+
status
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def send_command
|
79
|
+
begin
|
80
|
+
response = HTTParty.put("http://" + params[:ip] + "/webconsole/console",
|
81
|
+
body: {
|
82
|
+
command: params[:command]
|
83
|
+
}
|
84
|
+
)
|
85
|
+
|
86
|
+
if response.code == 200
|
87
|
+
render json: JSON.parse(response.body)
|
88
|
+
else
|
89
|
+
render json: {
|
90
|
+
status: "error",
|
91
|
+
message: "Error while sending command"
|
92
|
+
}
|
93
|
+
end
|
94
|
+
rescue Exception => e
|
95
|
+
render json: {
|
96
|
+
status: "error",
|
97
|
+
message: "Error while sending command"
|
98
|
+
}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def remote_connect
|
103
|
+
begin
|
104
|
+
response = HTTParty.put("http://" + params[:ip] + "/webconsole/console/connect")
|
105
|
+
if response.code == 200
|
106
|
+
render json: JSON.parse(response.body)
|
107
|
+
else
|
108
|
+
render json: {
|
109
|
+
connected: false
|
110
|
+
}
|
111
|
+
end
|
112
|
+
rescue Exception => e
|
113
|
+
render json: {
|
114
|
+
connected: false
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def send_response(result, status)
|
122
|
+
render json: {
|
123
|
+
result: result,
|
124
|
+
status: status
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
def parse_command_response(response)
|
129
|
+
if response.is_a?(String)
|
130
|
+
return {
|
131
|
+
result: response
|
132
|
+
}
|
133
|
+
elsif response.is_a?(Array)
|
134
|
+
return {
|
135
|
+
result: response.join("\n")
|
136
|
+
}
|
137
|
+
else
|
138
|
+
return {
|
139
|
+
result: response.to_json
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def check_admin_access
|
145
|
+
if !allowed_ips.include?(current_ip_address)
|
146
|
+
render json: {
|
147
|
+
connected: false,
|
148
|
+
ip: request.remote_ip
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def allowed_ips
|
154
|
+
%w{
|
155
|
+
::1
|
156
|
+
}.map { |ip| IPAddr.new ip }
|
157
|
+
end
|
158
|
+
|
159
|
+
def current_ip_address
|
160
|
+
request.env['HTTP_X_REAL_IP'] || request.env['REMOTE_ADDR']
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Webconsole</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
<%= stylesheet_link_tag "webconsole/application", media: "all" %>
|
9
|
+
|
10
|
+
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
11
|
+
<script src="https://unpkg.com/jquery.terminal/js/jquery.terminal.min.js"></script>
|
12
|
+
<link rel="stylesheet" href="https://unpkg.com/jquery.terminal/css/jquery.terminal.min.css"/>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<%= yield %>
|
16
|
+
</body>
|
17
|
+
</html>
|
File without changes
|
@@ -0,0 +1,144 @@
|
|
1
|
+
<script>
|
2
|
+
<% if not @details[:connect] %>
|
3
|
+
let connected = false;
|
4
|
+
let connected_to = "";
|
5
|
+
let greeting = "Type: connect [[b;#fff;]connect :ip] to connect to remote server";
|
6
|
+
<% else %>
|
7
|
+
let connected = true;
|
8
|
+
let connected_to = "<%= @details[:ip] %>";
|
9
|
+
let greeting = "You are connected to <%= @details[:ip] %>";
|
10
|
+
|
11
|
+
if (connected_to == "::1")
|
12
|
+
connected_to = "localhost:3000";
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
function send_command(command, shell) {
|
16
|
+
return new Promise(function(resolve) {
|
17
|
+
if (shell)
|
18
|
+
command = "shell " + command;
|
19
|
+
$.ajax({
|
20
|
+
url: '/webconsole/console/send_command',
|
21
|
+
type: 'POST',
|
22
|
+
data: {
|
23
|
+
command: command,
|
24
|
+
ip: connected_to
|
25
|
+
},
|
26
|
+
success: function(data) {
|
27
|
+
resolve(data);
|
28
|
+
}.bind(this),
|
29
|
+
error: function(xhr, status, error) {
|
30
|
+
resolve({
|
31
|
+
status: "error",
|
32
|
+
message: error
|
33
|
+
});
|
34
|
+
}.bind(this)
|
35
|
+
});
|
36
|
+
})
|
37
|
+
}
|
38
|
+
|
39
|
+
function echo(console, response) {
|
40
|
+
if (response.result == "null")
|
41
|
+
response.result = "success";
|
42
|
+
|
43
|
+
if (response.status == "success") {
|
44
|
+
console.echo(response.result);
|
45
|
+
} else {
|
46
|
+
if (connected) {
|
47
|
+
console.echo('[[b;red;]' + response.result + ']');
|
48
|
+
|
49
|
+
console.echo('Spinners, type [[b;#fff;]help] to display '+
|
50
|
+
'available spinners or [[b;#fff;]spinner <n'+
|
51
|
+
'ame>] for animation', {
|
52
|
+
keepWords: true
|
53
|
+
});
|
54
|
+
} else {
|
55
|
+
console.echo('[[b;red;]Not connected to any server]');
|
56
|
+
|
57
|
+
console.echo('Connect, type [[b;#fff;]connect :ip] to connect '+
|
58
|
+
'to a server.', {
|
59
|
+
keepWords: true
|
60
|
+
});
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
$('body').terminal({
|
66
|
+
connect: function(ip) {
|
67
|
+
if (connected) {
|
68
|
+
this.echo('Already connected to ' + connected_to);
|
69
|
+
this.echo('Use "disconnect" to disconnect');
|
70
|
+
return;
|
71
|
+
}
|
72
|
+
|
73
|
+
this.pause();
|
74
|
+
$.ajax({
|
75
|
+
url: '/webconsole/console/remote_connect',
|
76
|
+
type: 'POST',
|
77
|
+
data: {
|
78
|
+
ip: ip
|
79
|
+
},
|
80
|
+
success: function(data) {
|
81
|
+
if (data.connected) {
|
82
|
+
this.echo('Connected to ' + ip);
|
83
|
+
connected = true;
|
84
|
+
connected_to = ip;
|
85
|
+
} else {
|
86
|
+
this.echo('Could not connect to ' + ip);
|
87
|
+
}
|
88
|
+
}.bind(this),
|
89
|
+
error: function(xhr, status, error) {
|
90
|
+
this.echo('Could not connect to ' + ip);
|
91
|
+
}.bind(this)
|
92
|
+
});
|
93
|
+
this.resume();
|
94
|
+
},
|
95
|
+
disconnect: function() {
|
96
|
+
if (!connected) {
|
97
|
+
this.echo('Not connected to any server');
|
98
|
+
return;
|
99
|
+
}
|
100
|
+
|
101
|
+
this.pause();
|
102
|
+
this.echo('Disconnected from ' + connected_to);
|
103
|
+
connected = false;
|
104
|
+
connected_to = "";
|
105
|
+
this.resume();
|
106
|
+
},
|
107
|
+
shell: async function(...args) {
|
108
|
+
this.pause();
|
109
|
+
command = args.join(' ');
|
110
|
+
let response = await send_command(command, true);
|
111
|
+
echo(this, response);
|
112
|
+
this.resume();
|
113
|
+
},
|
114
|
+
rails: async function(...args) {
|
115
|
+
this.pause();
|
116
|
+
command = args.join(' ');
|
117
|
+
let response = await send_command(command, false);
|
118
|
+
echo(this, response);
|
119
|
+
this.resume();
|
120
|
+
},
|
121
|
+
server: function() {
|
122
|
+
this.pause();
|
123
|
+
echo(this, {
|
124
|
+
status: "success",
|
125
|
+
result: "Connected to " + connected_to
|
126
|
+
})
|
127
|
+
this.resume();
|
128
|
+
},
|
129
|
+
help: function() {
|
130
|
+
this.pause();
|
131
|
+
this.echo('Available commands:');
|
132
|
+
this.echo('[[b;#fff;]connect :ip] to connect to remote server');
|
133
|
+
this.echo('[[b;#fff;]disconnect] to disconnect from remote server');
|
134
|
+
this.echo('[[b;#fff;]shell <command>] to run shell command');
|
135
|
+
this.echo('[[b;#fff;]rails <command>] to run rails command');
|
136
|
+
this.echo('[[b;#fff;]server] to display server info');
|
137
|
+
this.echo('[[b;#fff;]help] to display this help');
|
138
|
+
this.resume();
|
139
|
+
}
|
140
|
+
}, {
|
141
|
+
checkArity: false,
|
142
|
+
greetings: greeting,
|
143
|
+
});
|
144
|
+
</script>
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
put '/console
|
5
|
-
put '/console/
|
6
|
-
|
1
|
+
Webconsole::Engine.routes.draw do
|
2
|
+
root to: 'console#index'
|
3
|
+
get '/:ip', to: 'console#index'
|
4
|
+
put '/console', to: 'console#run_command', as: :console_run_command
|
5
|
+
put '/console/connect', to: 'console#connect'
|
6
|
+
post '/console/remote_connect', to: 'console#remote_connect', as: :console_remote_connect
|
7
|
+
post '/console/send_command', to: 'console#send_command', as: :console_send_command
|
8
|
+
end
|
data/lib/webconsole.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: RemoteWebConsole
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Eriksson
|
@@ -9,22 +9,55 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2022-05-21 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
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: 6.1.6
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.1.6
|
13
27
|
description: A webconsole that can be used accross multiple applications.
|
14
|
-
email:
|
28
|
+
email:
|
29
|
+
- sebastian98@live.se
|
15
30
|
executables: []
|
16
31
|
extensions: []
|
17
32
|
extra_rdoc_files: []
|
18
33
|
files:
|
19
|
-
-
|
20
|
-
-
|
21
|
-
-
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- app/assets/config/webconsole_manifest.js
|
38
|
+
- app/assets/stylesheets/webconsole/application.css
|
39
|
+
- app/assets/stylesheets/webconsole/console.css
|
40
|
+
- app/controllers/webconsole/application_controller.rb
|
41
|
+
- app/controllers/webconsole/console_controller.rb
|
42
|
+
- app/helpers/webconsole/application_helper.rb
|
43
|
+
- app/helpers/webconsole/console_helper.rb
|
44
|
+
- app/jobs/webconsole/application_job.rb
|
45
|
+
- app/mailers/webconsole/application_mailer.rb
|
46
|
+
- app/models/webconsole/application_record.rb
|
47
|
+
- app/views/layouts/webconsole/application.html.erb
|
48
|
+
- app/views/webconsole/console/connect.html.erb
|
49
|
+
- app/views/webconsole/console/index.html.erb
|
22
50
|
- config/routes.rb
|
51
|
+
- lib/tasks/webconsole_tasks.rake
|
23
52
|
- lib/webconsole.rb
|
53
|
+
- lib/webconsole/config.rb
|
54
|
+
- lib/webconsole/engine.rb
|
55
|
+
- lib/webconsole/version.rb
|
24
56
|
homepage: https://rubygems.org/gems/RemoteWebConsole
|
25
57
|
licenses:
|
26
58
|
- MIT
|
27
|
-
metadata:
|
59
|
+
metadata:
|
60
|
+
homepage_uri: https://rubygems.org/gems/RemoteWebConsole
|
28
61
|
post_install_message:
|
29
62
|
rdoc_options: []
|
30
63
|
require_paths:
|
@@ -1,111 +0,0 @@
|
|
1
|
-
module WebConsole
|
2
|
-
class WebConsoleController < ApplicationController
|
3
|
-
include WebConsoleHelper
|
4
|
-
|
5
|
-
skip_before_action :verify_authenticity_token
|
6
|
-
before_action :check_admin_access, only: [:run_command]
|
7
|
-
|
8
|
-
def connect
|
9
|
-
# Recieve a connection request from the client
|
10
|
-
# and send back the connection ip and port
|
11
|
-
# if the request is from a valid ip address
|
12
|
-
|
13
|
-
if !allowed_ips.include?(current_ip_address)
|
14
|
-
render json: {
|
15
|
-
connected: true,
|
16
|
-
ip: request.remote_ip
|
17
|
-
}
|
18
|
-
else
|
19
|
-
render json: {
|
20
|
-
connected: false,
|
21
|
-
ip: request.remote_ip
|
22
|
-
}
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def run_command
|
27
|
-
command = params[:command].strip
|
28
|
-
if command.nil? || command.empty?
|
29
|
-
send_response("No command specified", "error", "string")
|
30
|
-
return
|
31
|
-
end
|
32
|
-
|
33
|
-
begin
|
34
|
-
eval_result = eval(command)
|
35
|
-
status = "success"
|
36
|
-
rescue Exception => e
|
37
|
-
eval_result = e.message
|
38
|
-
status = "error"
|
39
|
-
end
|
40
|
-
|
41
|
-
result = parse_command_response(response)
|
42
|
-
|
43
|
-
send_response(
|
44
|
-
result[:result],
|
45
|
-
status,
|
46
|
-
result[:type]
|
47
|
-
)
|
48
|
-
end
|
49
|
-
|
50
|
-
def send_command
|
51
|
-
# Find the server with the specified id
|
52
|
-
# and send the command to it
|
53
|
-
server = Server.find(params[:id])
|
54
|
-
render json: send_command(params[:command], server.ip)
|
55
|
-
end
|
56
|
-
|
57
|
-
def connect_remote
|
58
|
-
server = Server.find(params[:id])
|
59
|
-
render json: connect(server.ip)
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def send_response(result, status, type)
|
65
|
-
render json: {
|
66
|
-
result: result,
|
67
|
-
status: status,
|
68
|
-
type: type
|
69
|
-
}
|
70
|
-
end
|
71
|
-
|
72
|
-
def parse_command_response(response)
|
73
|
-
if response.is_a?(String)
|
74
|
-
return {
|
75
|
-
result: response,
|
76
|
-
type: "string"
|
77
|
-
}
|
78
|
-
elsif response.is_a?(Array)
|
79
|
-
return {
|
80
|
-
result: response.join("\n"),
|
81
|
-
type: "array"
|
82
|
-
}
|
83
|
-
else
|
84
|
-
return {
|
85
|
-
result: response.to_json,
|
86
|
-
type: "json"
|
87
|
-
}
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def check_admin_access
|
92
|
-
if !allowed_ips.include?(current_ip_address)
|
93
|
-
render json: {
|
94
|
-
connected: false,
|
95
|
-
ip: request.remote_ip
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def allowed_ips
|
101
|
-
ips_blocks = [
|
102
|
-
"::1",
|
103
|
-
"85.24.169.213"
|
104
|
-
]
|
105
|
-
end
|
106
|
-
|
107
|
-
def current_ip_address
|
108
|
-
request.env['HTTP_X_REAL_IP'] || request.env['REMOTE_ADDR']
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module WebConsole
|
2
|
-
class WebConsoleHelper < ApplicationHelper
|
3
|
-
require 'httparty'
|
4
|
-
|
5
|
-
def send_command(command, ip)
|
6
|
-
begin
|
7
|
-
response = HTTParty.put("http://" + ip + "/console",
|
8
|
-
body: {
|
9
|
-
command: command
|
10
|
-
}
|
11
|
-
)
|
12
|
-
|
13
|
-
if response.code == 200
|
14
|
-
return JSON.parse(response.body)
|
15
|
-
else
|
16
|
-
return {
|
17
|
-
status: "error",
|
18
|
-
message: "Error while sending command"
|
19
|
-
}
|
20
|
-
end
|
21
|
-
rescue Exception => e
|
22
|
-
return {
|
23
|
-
status: "error",
|
24
|
-
message: "Error while sending command"
|
25
|
-
}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def connect(ip)
|
30
|
-
begin
|
31
|
-
response = HTTParty.put("http://" + ip + "/console/connect")
|
32
|
-
if response.code == 200
|
33
|
-
return JSON.parse(response.body)
|
34
|
-
else
|
35
|
-
return {
|
36
|
-
connected: false
|
37
|
-
}
|
38
|
-
end
|
39
|
-
rescue Exception => e
|
40
|
-
return {
|
41
|
-
connected: false
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/config/locales/en.yml
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
en:
|
2
|
-
webconsole:
|
3
|
-
connect:
|
4
|
-
refused: "The server has refused your connection attempt"
|
5
|
-
success: "The server has accepted your connection and you are now connected"
|
6
|
-
error: "Something went wrong when connection to server"
|
7
|
-
error_paranoid: "Something went wrong when connection to server. Server might be down"
|
8
|
-
commands:
|
9
|
-
invalid: "Invalid command. Write 'help' for instructions"
|