oneis 1.2.2-java → 2.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/oneis-plugin +1 -1
- data/lib/auth.rb +168 -0
- data/lib/manifest.rb +1 -1
- data/lib/notifications.rb +1 -1
- data/lib/packing.rb +2 -2
- data/lib/plugin.rb +56 -40
- data/lib/plugin_tool.rb +21 -17
- data/lib/server.rb +28 -38
- data/lib/usage.txt +13 -4
- data/lib/version.txt +1 -1
- data/oneis.gemspec +2 -2
- metadata +3 -2
data/bin/oneis-plugin
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'java'
|
4
4
|
|
5
|
-
require 'yaml'
|
6
5
|
require 'digest/sha1'
|
7
6
|
require 'net/http'
|
8
7
|
require 'net/https'
|
@@ -25,6 +24,7 @@ require JS_JAR
|
|
25
24
|
|
26
25
|
require "#{ONEIS_PLUGIN_ROOT_DIR}/lib/hmac.rb"
|
27
26
|
require "#{ONEIS_PLUGIN_ROOT_DIR}/lib/manifest.rb"
|
27
|
+
require "#{ONEIS_PLUGIN_ROOT_DIR}/lib/auth.rb"
|
28
28
|
require "#{ONEIS_PLUGIN_ROOT_DIR}/lib/server.rb"
|
29
29
|
require "#{ONEIS_PLUGIN_ROOT_DIR}/lib/syntax_checking.rb"
|
30
30
|
require "#{ONEIS_PLUGIN_ROOT_DIR}/lib/notifications.rb"
|
data/lib/auth.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
@@keys_pathname = "#{Dir.getwd}/.server.json"
|
5
|
+
|
6
|
+
# ---------------------------------------------------------------------------------------------------------
|
7
|
+
|
8
|
+
def self.setup_auth(options)
|
9
|
+
keys = load_keys_file()
|
10
|
+
server = keys['default']
|
11
|
+
if options.server_substring
|
12
|
+
server = select_server(keys, options.server_substring)
|
13
|
+
end_on_error "No server found for substring '#{options.server_substring}" unless server
|
14
|
+
end
|
15
|
+
key = keys['keys'][server]
|
16
|
+
if key
|
17
|
+
hostname, port, url_base = parse_hostname_with_port(server)
|
18
|
+
set_server(hostname, port, key)
|
19
|
+
puts "Application: #{url_base}"
|
20
|
+
else
|
21
|
+
end_on_error "No server authorised. Run oneis-plugin auth SERVER_NAME"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# ---------------------------------------------------------------------------------------------------------
|
26
|
+
|
27
|
+
def self.cmd_server(options)
|
28
|
+
end_on_error "No server name substring given on command line" if options.args.empty?
|
29
|
+
keys = load_keys_file()
|
30
|
+
server = select_server(keys, options.args.first)
|
31
|
+
end_on_error "No server found for substring '#{options.args.first}" unless server
|
32
|
+
keys['default'] = server
|
33
|
+
puts "Selected server #{server}"
|
34
|
+
save_keys_file(keys)
|
35
|
+
end
|
36
|
+
|
37
|
+
# ---------------------------------------------------------------------------------------------------------
|
38
|
+
|
39
|
+
def self.cmd_auth(options)
|
40
|
+
end_on_error "No hostname given on command line" if options.args.empty?
|
41
|
+
hostname, port, url_base, server_name = parse_hostname_with_port(options.args.first)
|
42
|
+
|
43
|
+
keys = load_keys_file()
|
44
|
+
if keys['keys'].has_key?(server_name) && !options.force
|
45
|
+
puts
|
46
|
+
puts "Already authorised with #{server_name}"
|
47
|
+
puts "Use the --force argument to reauthorise with the server."
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
set_server(hostname, port, nil)
|
52
|
+
check_for_certificate_file()
|
53
|
+
http = get_http()
|
54
|
+
|
55
|
+
this_hostname = java.net.InetAddress.getLocalHost().getHostName() || "unknown"
|
56
|
+
|
57
|
+
puts "Requesting token from #{url_base} ..."
|
58
|
+
start_auth_path = "/api/plugin-tool-auth/start-auth?name=#{URI.encode(this_hostname)}"
|
59
|
+
request = Net::HTTP::Get.new(start_auth_path)
|
60
|
+
setup_request(request)
|
61
|
+
token = nil
|
62
|
+
begin
|
63
|
+
response = http.request(request)
|
64
|
+
end_on_error "Server returned an error. Check hostname and port." unless response.code == "200"
|
65
|
+
parsed_json = JSON.parse(response.body)
|
66
|
+
token = parsed_json['token']
|
67
|
+
end_on_error "Server doesn't look like a ONEIS server with plugin debugging enabled" unless parsed_json['ONEIS'] == 'plugin-tool-auth' && token
|
68
|
+
rescue => e
|
69
|
+
end_on_error "Failed to start authorisation process. Check hostname and port."
|
70
|
+
end
|
71
|
+
|
72
|
+
# Check token looks OK so we don't form dodgy URLs
|
73
|
+
end_on_error "Bad token" unless token =~ /\A[a-z0-9A-Z_-]+\z/
|
74
|
+
|
75
|
+
user_url = "#{url_base}/do/plugin-tool-auth/create/#{token}"
|
76
|
+
poll_path = "/api/plugin-tool-auth/poll/#{token}"
|
77
|
+
|
78
|
+
puts
|
79
|
+
if java.lang.System.getProperty("os.name") == 'Mac OS X'
|
80
|
+
puts "Attempting to open the following URL in your browser."
|
81
|
+
puts "If the browser does not open, please visit this URL in your browser."
|
82
|
+
system "open #{user_url}"
|
83
|
+
else
|
84
|
+
puts "Please visit this URL in your browser, and authenticate if necessary."
|
85
|
+
end
|
86
|
+
puts " #{user_url}"
|
87
|
+
puts
|
88
|
+
|
89
|
+
# Poll for a few minutes, waiting for the user to authenticate
|
90
|
+
puts "Waiting for server to authorise..."
|
91
|
+
poll_count = 0
|
92
|
+
key = nil
|
93
|
+
while poll_count < 60 && !key
|
94
|
+
delay = if poll_count < 10
|
95
|
+
2
|
96
|
+
elsif poll_count < 20
|
97
|
+
4
|
98
|
+
else
|
99
|
+
8
|
100
|
+
end
|
101
|
+
sleep delay
|
102
|
+
begin
|
103
|
+
request = Net::HTTP::Get.new(poll_path)
|
104
|
+
setup_request(request)
|
105
|
+
response = http.request(request)
|
106
|
+
parsed_json = JSON.parse(response.body)
|
107
|
+
case parsed_json['status']
|
108
|
+
when 'wait'
|
109
|
+
# poll again
|
110
|
+
when 'available'
|
111
|
+
key = parsed_json['key']
|
112
|
+
else
|
113
|
+
end_on_error "Authorisation process failed."
|
114
|
+
end
|
115
|
+
rescue => e
|
116
|
+
end_on_error "Error communicating with server"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
finish_with_connection()
|
120
|
+
|
121
|
+
end_on_error "Didn't managed to authorise with server." unless key
|
122
|
+
|
123
|
+
puts "Successfully authorised with server."
|
124
|
+
|
125
|
+
keys['default'] = server_name
|
126
|
+
keys['keys'][server_name] = key
|
127
|
+
save_keys_file(keys)
|
128
|
+
|
129
|
+
puts
|
130
|
+
puts "Key stored in #{@@keys_pathname}"
|
131
|
+
puts "#{server_name} selected as default server."
|
132
|
+
end
|
133
|
+
|
134
|
+
# ---------------------------------------------------------------------------------------------------------
|
135
|
+
|
136
|
+
def self.parse_hostname_with_port(hostname_with_port)
|
137
|
+
hostname_with_port = hostname_with_port.downcase.strip
|
138
|
+
unless hostname_with_port =~ /\A([a-z0-9\.-]+)(:(\d+))?\z/
|
139
|
+
end_on_error "Bad hostname #{hostname_with_port}"
|
140
|
+
end
|
141
|
+
hostname = $1
|
142
|
+
port = $3 ? $3.to_i : 443
|
143
|
+
server_name = "#{hostname}#{$3 ? ":#{$3}" : ''}"
|
144
|
+
[hostname, port, "https://#{server_name}", server_name]
|
145
|
+
end
|
146
|
+
|
147
|
+
# ---------------------------------------------------------------------------------------------------------
|
148
|
+
|
149
|
+
def self.load_keys_file
|
150
|
+
if File.exist?(@@keys_pathname)
|
151
|
+
File.open(@@keys_pathname) { |f| JSON.parse(f.read) }
|
152
|
+
else
|
153
|
+
{"_" => "Contains server keys. DO NOT COMMIT TO SOURCE CONTROL.", "default" => nil, "keys" => {}}
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.save_keys_file(keys)
|
158
|
+
pn = "#{@@keys_pathname}.n"
|
159
|
+
File.open(pn, "w") { |f| f.write(JSON.pretty_generate(keys)) }
|
160
|
+
File.rename(pn, @@keys_pathname)
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.select_server(keys, substring)
|
164
|
+
s = substring.downcase.strip
|
165
|
+
keys['keys'].keys.sort { |a,b| (a.length == b.length) ? (a <=> b) : (a.length <=> b.length) } .find { |a| a.include? s }
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
data/lib/manifest.rb
CHANGED
@@ -22,7 +22,7 @@ module PluginTool
|
|
22
22
|
raise "Bad root directory #{$1}" unless ALLOWED_PLUGIN_DIRS.include?($1)
|
23
23
|
end
|
24
24
|
# Get hash of file
|
25
|
-
digest = File.open(pathname) { |f| Digest::
|
25
|
+
digest = File.open(pathname) { |f| Digest::SHA256.hexdigest(f.read) }
|
26
26
|
# And add to manifest
|
27
27
|
manifest[filename] = digest
|
28
28
|
end
|
data/lib/notifications.rb
CHANGED
@@ -26,7 +26,7 @@ module PluginTool
|
|
26
26
|
puts "NOTICE: Notification connection established." if @@notification_announce_reconnect
|
27
27
|
while true
|
28
28
|
sleep(0.25) # small throttle of requests
|
29
|
-
path = '/api/
|
29
|
+
path = '/api/development-plugin-loader/get-notifications'
|
30
30
|
path << "?queue=#{@@notification_queue_name}" if @@notification_queue_name
|
31
31
|
request = Net::HTTP::Get.new(path)
|
32
32
|
setup_request(request)
|
data/lib/packing.rb
CHANGED
@@ -40,7 +40,7 @@ module PluginTool
|
|
40
40
|
unless filename =~ /\Ajs\//
|
41
41
|
data = minimiser.process(data, filename)
|
42
42
|
end
|
43
|
-
hash = Digest::
|
43
|
+
hash = Digest::SHA256.hexdigest(data)
|
44
44
|
# Make sure output directory exists, write file
|
45
45
|
output_pathname = "#{output_plugin_dir}/#{filename}"
|
46
46
|
output_directory = File.dirname(output_pathname)
|
@@ -52,7 +52,7 @@ module PluginTool
|
|
52
52
|
minimiser.finish
|
53
53
|
# Write manifest and version
|
54
54
|
File.open("#{output_plugin_dir}/manifest", "w") { |f| f.write manifest }
|
55
|
-
version = Digest::
|
55
|
+
version = Digest::SHA256.hexdigest(manifest)
|
56
56
|
File.open("#{output_plugin_dir}/version", "w") { |f| f.write "#{version}\n" }
|
57
57
|
# All done
|
58
58
|
puts "Version: #{version}\nPlugin packed."
|
data/lib/plugin.rb
CHANGED
@@ -10,6 +10,11 @@ module PluginTool
|
|
10
10
|
end
|
11
11
|
attr_accessor :name
|
12
12
|
attr_accessor :plugin_dir
|
13
|
+
attr_accessor :loaded_plugin_id
|
14
|
+
|
15
|
+
# ---------------------------------------------------------------------------------------------------------
|
16
|
+
|
17
|
+
@@pending_apply = []
|
13
18
|
|
14
19
|
# ---------------------------------------------------------------------------------------------------------
|
15
20
|
|
@@ -34,13 +39,6 @@ module PluginTool
|
|
34
39
|
end
|
35
40
|
|
36
41
|
def setup_for_server
|
37
|
-
# Delete any legacy registration file for this plugin
|
38
|
-
registration_file = "registration.#{@plugin_dir}.yaml"
|
39
|
-
if File.exists? registration_file
|
40
|
-
puts "NOTICE: Deleting legacy registration file for #{@plugin_dir}"
|
41
|
-
File.delete(registration_file)
|
42
|
-
end
|
43
|
-
|
44
42
|
# Make the first empty manifest (may be replaced from server)
|
45
43
|
@current_manifest = {}
|
46
44
|
|
@@ -50,19 +48,19 @@ module PluginTool
|
|
50
48
|
end
|
51
49
|
|
52
50
|
# See if the plugin has already been registered with the server
|
53
|
-
s_found_info = PluginTool.
|
54
|
-
if s_found_info[
|
51
|
+
s_found_info = PluginTool.post_with_json_response("/api/development-plugin-loader/find-registration", {:name => @name})
|
52
|
+
if s_found_info["found"]
|
55
53
|
# Store info returned by the server
|
56
|
-
@loaded_plugin_id = s_found_info[
|
57
|
-
@current_manifest = s_found_info[
|
54
|
+
@loaded_plugin_id = s_found_info["plugin_id"]
|
55
|
+
@current_manifest = s_found_info["manifest"]
|
58
56
|
end
|
59
57
|
|
60
58
|
# If there isn't an existing plugin registered, create a new one
|
61
59
|
if @loaded_plugin_id == nil
|
62
|
-
s_create_info = PluginTool.
|
63
|
-
end_on_error "Couldn't communicate successfully with server." if s_create_info[
|
64
|
-
end_on_error "Failed to create plugin on server" unless s_create_info[
|
65
|
-
@loaded_plugin_id = s_create_info[
|
60
|
+
s_create_info = PluginTool.post_with_json_response("/api/development-plugin-loader/create")
|
61
|
+
end_on_error "Couldn't communicate successfully with server." if s_create_info["protocol_error"]
|
62
|
+
end_on_error "Failed to create plugin on server" unless s_create_info["plugin_id"] != nil
|
63
|
+
@loaded_plugin_id = s_create_info["plugin_id"]
|
66
64
|
end
|
67
65
|
end
|
68
66
|
|
@@ -82,27 +80,27 @@ module PluginTool
|
|
82
80
|
|
83
81
|
when 'reset-db'
|
84
82
|
puts "Resetting database on server for #{@name}..."
|
85
|
-
reset_result = PluginTool.
|
86
|
-
end_on_error "Couldn't remove old database tables" unless reset_result[
|
87
|
-
apply_result = PluginTool.
|
88
|
-
end_on_error "Couldn't apply changes" unless apply_result[
|
83
|
+
reset_result = PluginTool.post_with_json_response("/api/development-plugin-loader/resetdb/#{@loaded_plugin_id}")
|
84
|
+
end_on_error "Couldn't remove old database tables" unless reset_result["result"] == 'success'
|
85
|
+
apply_result = PluginTool.post_with_json_response("/api/development-plugin-loader/apply", :plugins => @loaded_plugin_id)
|
86
|
+
end_on_error "Couldn't apply changes" unless apply_result["result"] == 'success'
|
89
87
|
puts "Done."
|
90
88
|
|
91
89
|
when 'uninstall'
|
92
90
|
puts "Uninstalling plugin #{@name} from server..."
|
93
|
-
reset_result = PluginTool.
|
94
|
-
end_on_error "Couldn't uninstall plugin" unless reset_result[
|
91
|
+
reset_result = PluginTool.post_with_json_response("/api/development-plugin-loader/uninstall/#{@loaded_plugin_id}")
|
92
|
+
end_on_error "Couldn't uninstall plugin" unless reset_result["result"] == 'success'
|
95
93
|
puts "Done."
|
96
94
|
|
97
95
|
when 'test'
|
98
96
|
puts "Running tests..."
|
99
97
|
params = {}
|
100
|
-
params[
|
101
|
-
test_result = PluginTool.
|
102
|
-
end_on_error "Couldn't run tests" unless test_result[
|
98
|
+
params["test"] = @options.args.first unless @options.args.empty?
|
99
|
+
test_result = PluginTool.post_with_json_response("/api/development-plugin-loader/run-tests/#{@loaded_plugin_id}", params)
|
100
|
+
end_on_error "Couldn't run tests" unless test_result["result"] == 'success'
|
103
101
|
puts
|
104
|
-
puts test_result[
|
105
|
-
puts test_result[
|
102
|
+
puts test_result["output"] || ''
|
103
|
+
puts test_result["summary"] || "(unknown results)"
|
106
104
|
|
107
105
|
when 'develop'
|
108
106
|
# do nothing here
|
@@ -119,7 +117,16 @@ module PluginTool
|
|
119
117
|
end
|
120
118
|
|
121
119
|
def develop_scan_and_upload(first_run)
|
120
|
+
should_apply = first_run
|
122
121
|
next_manifest = PluginTool.generate_manifest(@plugin_dir)
|
122
|
+
if !(next_manifest.has_key?("plugin.json"))
|
123
|
+
# If the plugin.json file is deleted, just uninstall the plugin from the server
|
124
|
+
command('uninstall')
|
125
|
+
@is_uninstalled = true
|
126
|
+
return
|
127
|
+
elsif @is_uninstalled
|
128
|
+
should_apply = true
|
129
|
+
end
|
123
130
|
changes = PluginTool.determine_manifest_changes(@current_manifest, next_manifest)
|
124
131
|
upload_failed = false
|
125
132
|
changes.each do |filename, action|
|
@@ -128,7 +135,7 @@ module PluginTool
|
|
128
135
|
params[:directory] = $1.gsub(/\/\z/,'') if $1
|
129
136
|
if action == :delete
|
130
137
|
puts " #{@name}: Deleting #{filename}"
|
131
|
-
PluginTool.
|
138
|
+
PluginTool.post_with_json_response("/api/development-plugin-loader/delete-file/#{@loaded_plugin_id}", params)
|
132
139
|
else
|
133
140
|
puts " #{@name}: Uploading #{filename}"
|
134
141
|
data = File.open("#{@plugin_dir}/#{filename}") { |f| f.read }
|
@@ -138,13 +145,13 @@ module PluginTool
|
|
138
145
|
size_before = data.length
|
139
146
|
data = @options.minimiser.process(data, filename)
|
140
147
|
size_after = data.length
|
141
|
-
hash = Digest::
|
148
|
+
hash = Digest::SHA256.hexdigest(data)
|
142
149
|
puts " minimisation: #{size_before} -> #{size_after} (#{(size_after * 100) / size_before}%)"
|
143
150
|
end
|
144
|
-
r = PluginTool.
|
145
|
-
if r[
|
151
|
+
r = PluginTool.post_with_json_response("/api/development-plugin-loader/put-file/#{@loaded_plugin_id}", params, {:file => [filename, data]})
|
152
|
+
if r["result"] == 'success'
|
146
153
|
# If the file was uploaded successfully, but the hash didn't match, abort now
|
147
|
-
end_on_error "#{@name}: Disagreed with server about uploaded file hash: local=#{hash}, remote=#{r[
|
154
|
+
end_on_error "#{@name}: Disagreed with server about uploaded file hash: local=#{hash}, remote=#{r["hash"]}" unless hash == r["hash"]
|
148
155
|
else
|
149
156
|
# Otherwise mark as a failed upload to stop an apply operation which will fail
|
150
157
|
upload_failed = true
|
@@ -155,22 +162,31 @@ module PluginTool
|
|
155
162
|
if upload_failed
|
156
163
|
puts "\n#{@name}: Not applying changes due to failure\n\n"
|
157
164
|
else
|
158
|
-
if !(changes.empty?) ||
|
159
|
-
|
160
|
-
r = PluginTool.get_yaml("/api/development_plugin_loader/apply/#{@loaded_plugin_id}")
|
161
|
-
unless r[:result] == 'success'
|
162
|
-
puts "\n\n#{@name}: Didn't apply changes on server\n\n"
|
163
|
-
PluginTool.beep
|
164
|
-
end
|
165
|
-
PluginTool.push_delayed_apply(@name) if r[:requires_delayed_apply]
|
165
|
+
if !(changes.empty?) || should_apply
|
166
|
+
@@pending_apply.push(self) unless @@pending_apply.include?(self)
|
166
167
|
end
|
167
168
|
end
|
168
|
-
PluginTool.finish_with_connection
|
169
169
|
@current_manifest = next_manifest
|
170
170
|
end
|
171
171
|
|
172
172
|
# ---------------------------------------------------------------------------------------------------------
|
173
173
|
|
174
|
+
def self.do_apply
|
175
|
+
return if @@pending_apply.empty?
|
176
|
+
puts "Applying changes on server: #{@@pending_apply.map { |p| p.name } .join(', ')}"
|
177
|
+
r = PluginTool.post_with_json_response("/api/development-plugin-loader/apply", {
|
178
|
+
:plugins => @@pending_apply.map { |p| p.loaded_plugin_id }.join(' ')
|
179
|
+
})
|
180
|
+
if r["result"] == 'success'
|
181
|
+
@@pending_apply = []
|
182
|
+
else
|
183
|
+
puts "\n\nDidn't apply changes on server\n\n"
|
184
|
+
PluginTool.beep
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# ---------------------------------------------------------------------------------------------------------
|
189
|
+
|
174
190
|
def generate_license_key(application_id)
|
175
191
|
info = File.open("#{@plugin_dir}/plugin.json") { |f| JSON.parse(f.read) }
|
176
192
|
if info["installSecret"] == nil
|
data/lib/plugin_tool.rb
CHANGED
@@ -15,16 +15,18 @@ LOCAL_ONLY_COMMANDS = {"license-key" => true, "pack" => true, "check" => true}
|
|
15
15
|
plugin_names = []
|
16
16
|
|
17
17
|
# Options for passing to plugin objects
|
18
|
-
options = Struct.new(:output, :minimiser, :no_console, :show_system_audit, :args).new
|
18
|
+
options = Struct.new(:output, :minimiser, :no_console, :show_system_audit, :args, :force, :server_substring).new
|
19
19
|
|
20
20
|
# Parse arguments
|
21
21
|
show_help = false
|
22
22
|
opts = GetoptLong.new(
|
23
23
|
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
24
24
|
['--plugin', '-p', GetoptLong::OPTIONAL_ARGUMENT],
|
25
|
+
['--server', '-s', GetoptLong::REQUIRED_ARGUMENT],
|
26
|
+
['--force', GetoptLong::NO_ARGUMENT],
|
25
27
|
['--output', GetoptLong::REQUIRED_ARGUMENT],
|
26
28
|
['--no-console', '-n', GetoptLong::NO_ARGUMENT],
|
27
|
-
['--show-system-audit',
|
29
|
+
['--show-system-audit', GetoptLong::NO_ARGUMENT],
|
28
30
|
['--minimise', '--minimize', '-m', GetoptLong::NO_ARGUMENT]
|
29
31
|
)
|
30
32
|
option_output = nil
|
@@ -34,6 +36,8 @@ opts.each do |opt, argument|
|
|
34
36
|
show_help = true
|
35
37
|
when '--plugin'
|
36
38
|
plugin_names = argument.split(',').map {|n| n.gsub(/[\/\\]+\z/,'')} # remove trailing dir separators
|
39
|
+
when '--server'
|
40
|
+
options.server_substring = argument
|
37
41
|
when '--output'
|
38
42
|
options.output = argument
|
39
43
|
when '--no-console'
|
@@ -42,6 +46,8 @@ opts.each do |opt, argument|
|
|
42
46
|
options.show_system_audit = true
|
43
47
|
when '--minimise', '--minimize'
|
44
48
|
options.minimiser = PluginTool::Minimiser.new
|
49
|
+
when '--force'
|
50
|
+
options.force = true
|
45
51
|
end
|
46
52
|
end
|
47
53
|
# Handle rest of command line -- first arg is the command, the rest are passed on
|
@@ -69,21 +75,19 @@ if plugin_names.length == 1 && plugin_names[0] == 'ALL'
|
|
69
75
|
plugin_names = find_all_plugins()
|
70
76
|
end
|
71
77
|
|
72
|
-
#
|
73
|
-
|
78
|
+
# Some commands don't require a server or plugin to be specified
|
79
|
+
case PLUGIN_TOOL_COMMAND
|
80
|
+
when 'new'
|
74
81
|
end_on_error "Plugin name not specified, use --plugin option." if plugin_names.empty?
|
75
82
|
end_on_error "Only one plugin name should be specified for new command" if plugin_names.length > 1
|
76
83
|
PluginTool.make_new_plugin(plugin_names.first)
|
77
84
|
exit 0
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
when '
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
else
|
86
|
-
end_on_error "Command not known. Use --help option for usage information."
|
85
|
+
when 'auth'
|
86
|
+
PluginTool.cmd_auth options
|
87
|
+
exit 0
|
88
|
+
when 'server'
|
89
|
+
PluginTool.cmd_server options
|
90
|
+
exit 0
|
87
91
|
end
|
88
92
|
|
89
93
|
# Find a plugin if none was specified
|
@@ -125,9 +129,8 @@ end
|
|
125
129
|
|
126
130
|
# Set up server communications
|
127
131
|
unless LOCAL_ONLY_COMMANDS[PLUGIN_TOOL_COMMAND]
|
128
|
-
|
129
|
-
|
130
|
-
end_on_error server_info_errors unless server_info_errors == nil
|
132
|
+
PluginTool.setup_auth(options)
|
133
|
+
PluginTool.check_for_certificate_file
|
131
134
|
# Ask plugins to set themselves up
|
132
135
|
plugins.each { |p| p.setup_for_server }
|
133
136
|
end
|
@@ -157,7 +160,8 @@ first_run = true
|
|
157
160
|
while(true)
|
158
161
|
puts "Scanning plugin files..."
|
159
162
|
plugins.each { |p| p.develop_scan_and_upload(first_run) }
|
160
|
-
PluginTool.
|
163
|
+
PluginTool::Plugin.do_apply
|
164
|
+
PluginTool.finish_with_connection
|
161
165
|
puts "Waiting for changes..."
|
162
166
|
if first_run
|
163
167
|
puts " Any changes you make to your local copy of the plugin will be automatically"
|
data/lib/server.rb
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
|
2
2
|
module PluginTool
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
def self.set_server(hostname, port, key)
|
5
|
+
@@server_hostname = hostname
|
6
|
+
@@server_port = port
|
7
|
+
@@server_key = key
|
8
|
+
end
|
7
9
|
|
8
|
-
def self.
|
9
|
-
@@
|
10
|
-
|
11
|
-
|
10
|
+
def self.check_for_certificate_file
|
11
|
+
@@server_ca = nil
|
12
|
+
hostname_parts = (@@server_hostname || '').split('.')
|
13
|
+
search_list = (0..hostname_parts.length).map do |n|
|
14
|
+
filename = "server"
|
15
|
+
search_parts = hostname_parts[n..hostname_parts.length]
|
16
|
+
filename << '.' unless search_parts.empty?
|
17
|
+
filename << search_parts.join('.')
|
18
|
+
filename << ".crt"
|
12
19
|
end
|
13
|
-
|
14
|
-
|
15
|
-
@@server_ca
|
16
|
-
puts "NOTICE: Using alternative CAs for SSL from #{SERVER_CERTIFICATE}"
|
20
|
+
@@server_ca = search_list.find { |f| File.file?(f) }
|
21
|
+
if @@server_ca
|
22
|
+
puts "NOTICE: Using alternative CAs for SSL from #{@@server_ca}"
|
17
23
|
else
|
18
24
|
# Use build in certificate bundle
|
19
25
|
@@server_ca = "#{File.dirname(__FILE__)}/CertificateBundle.pem"
|
20
26
|
end
|
21
|
-
puts "Application: https://#{@@server[:hostname]}/"
|
22
|
-
nil
|
23
27
|
end
|
24
28
|
|
25
29
|
def self.make_http_connection
|
26
|
-
http = Net::HTTP.new(@@
|
30
|
+
http = Net::HTTP.new(@@server_hostname, @@server_port)
|
27
31
|
ssl_ca = OpenSSL::X509::Store.new
|
28
32
|
unless ssl_ca.respond_to? :add_file
|
29
33
|
puts
|
@@ -54,7 +58,7 @@ module PluginTool
|
|
54
58
|
|
55
59
|
def self.setup_request(req)
|
56
60
|
req['User-Agent'] = 'plugin-tool'
|
57
|
-
req['X-ONEIS-Key'] = @@
|
61
|
+
req['X-ONEIS-Key'] = @@server_key if @@server_key
|
58
62
|
end
|
59
63
|
|
60
64
|
def self.get(path)
|
@@ -64,8 +68,8 @@ module PluginTool
|
|
64
68
|
http.request(request).body
|
65
69
|
end
|
66
70
|
|
67
|
-
def self.
|
68
|
-
report_errors_from_server(
|
71
|
+
def self.get_with_json_response(path)
|
72
|
+
report_errors_from_server(JSON.parse(get(path)))
|
69
73
|
end
|
70
74
|
|
71
75
|
def self.post(path, params = nil, files = nil)
|
@@ -105,41 +109,27 @@ EOF
|
|
105
109
|
http.request(request).body
|
106
110
|
end
|
107
111
|
|
108
|
-
def self.
|
109
|
-
report_errors_from_server(
|
112
|
+
def self.post_with_json_response(path, params = nil, files = nil)
|
113
|
+
report_errors_from_server(JSON.parse(post(path, params, files)))
|
110
114
|
end
|
111
115
|
|
112
116
|
def self.report_errors_from_server(r)
|
113
117
|
unless r.kind_of? Hash
|
114
118
|
r = {
|
115
|
-
|
116
|
-
|
117
|
-
|
119
|
+
"result" => 'error',
|
120
|
+
"protocol_error" => true,
|
121
|
+
"message" => "Unknown error. Either the server is not enabled for development, or the credentials in #{SERVER_INFO} are not valid."
|
118
122
|
}
|
119
123
|
end
|
120
|
-
if r[
|
124
|
+
if r["result"] != 'success' && r.has_key?("message")
|
121
125
|
puts "\n\n**************************************************************"
|
122
126
|
puts " ERROR REPORTED BY SERVER"
|
123
127
|
puts "**************************************************************\n\n"
|
124
|
-
puts r[
|
128
|
+
puts r["message"]
|
125
129
|
puts "\n**************************************************************\n\n"
|
126
130
|
beep
|
127
131
|
end
|
128
132
|
r
|
129
133
|
end
|
130
134
|
|
131
|
-
# Delayed apply support
|
132
|
-
@@delayed_apply_queue = []
|
133
|
-
def self.push_delayed_apply(name)
|
134
|
-
@@delayed_apply_queue.push(name)
|
135
|
-
end
|
136
|
-
def self.do_delayed_apply
|
137
|
-
return if @@delayed_apply_queue.empty?
|
138
|
-
puts "Updating server..."
|
139
|
-
self.post_yaml("/api/development_plugin_loader/delayed_apply", {"plugins" => @@delayed_apply_queue.join(',')})
|
140
|
-
self.finish_with_connection
|
141
|
-
puts "Updated."
|
142
|
-
@@delayed_apply_queue = []
|
143
|
-
end
|
144
|
-
|
145
135
|
end
|
data/lib/usage.txt
CHANGED
@@ -13,6 +13,9 @@ Options:
|
|
13
13
|
in the current directory. If not specified, and there's a single plugin in the current
|
14
14
|
directory, it will be selected automatically.
|
15
15
|
|
16
|
+
--server, -s [SUBSTRING]
|
17
|
+
For this run of the plugin tool, use the server containing the given substring.
|
18
|
+
|
16
19
|
--minimise
|
17
20
|
When uploading templates and client side JavaScript to the server, minimise the files
|
18
21
|
to match the pre-deployment pre-processing. Use this for final testing before
|
@@ -27,6 +30,12 @@ Commands:
|
|
27
30
|
develop (default command)
|
28
31
|
Developer mode. Push plugin to the specified server.
|
29
32
|
|
33
|
+
auth [SERVER]
|
34
|
+
Authorise with server. SERVER can optionally include a non-default port number.
|
35
|
+
|
36
|
+
server [SUBSTRING]
|
37
|
+
Change the default server to the one containing the given substring.
|
38
|
+
|
30
39
|
test [NAME]
|
31
40
|
Run the tests on the server, then report on the results.
|
32
41
|
This command does *not* upload changes to the plugin or tests to the server.
|
@@ -61,10 +70,10 @@ To initialise a new plugin, run a command like
|
|
61
70
|
and then edit the generated files.
|
62
71
|
|
63
72
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
If the server certificate does not use a known public CA, a alternative certificate can be
|
74
|
+
provided using a server.crt file in the current working directory. This may optionally contain
|
75
|
+
elements of the hostname, eg app.example.com would select the first file from:
|
76
|
+
server.app.example.com.crt server.example.com.crt server.com.crt server.crt
|
68
77
|
|
69
78
|
|
70
79
|
For more information, see http://docs.oneis.co.uk/dev/tool/plugin
|
data/lib/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
c7c8ef009b
|
data/oneis.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
files = Dir.glob("#{root_dir}/**/*.*").map { |x| x[root_dir.length + 1, x.length]}
|
4
4
|
|
5
5
|
s.name = 'oneis'
|
6
|
-
s.version = '
|
7
|
-
s.date = '
|
6
|
+
s.version = '2.0.1'
|
7
|
+
s.date = '2015-01-05'
|
8
8
|
s.summary = "ONEIS Tools"
|
9
9
|
s.description = "ONEIS Developer Tools"
|
10
10
|
s.authors = ["ONEIS"]
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: oneis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version:
|
5
|
+
version: 2.0.1
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- ONEIS
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2015-01-05 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: jruby-openssl
|
@@ -45,6 +45,7 @@ extra_rdoc_files: []
|
|
45
45
|
files:
|
46
46
|
- oneis.gemspec
|
47
47
|
- README.txt
|
48
|
+
- lib/auth.rb
|
48
49
|
- lib/CertificateBundle.pem
|
49
50
|
- lib/check.rb
|
50
51
|
- lib/hmac.rb
|