haplo 2.1.0-java

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.
@@ -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 haplo-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 Haplo server with plugin debugging enabled" unless ((parsed_json['Haplo'] == 'plugin-tool-auth') || (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(https?:\/\/)?([a-z0-9\.-]+)(:(\d+))?/i
139
+ end_on_error "Bad hostname #{hostname_with_port}"
140
+ end
141
+ hostname = $2
142
+ port = $4 ? $4.to_i : 443
143
+ server_name = "#{hostname}#{(port != 443) ? ":#{port}" : ''}"
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
@@ -0,0 +1,60 @@
1
+
2
+ module PluginTool
3
+
4
+ def self.check_plugins(plugins)
5
+ init_syntax_checking
6
+ @@check_report = ''
7
+ @@check_ok = true
8
+ @@check_warn = false
9
+ plugins.each { |p| check_plugin(p) }
10
+ if @@check_warn || !(@@check_ok)
11
+ puts "\nFILES WITH ERRORS"
12
+ puts @@check_report
13
+ end
14
+ # Output the verdict
15
+ puts
16
+ if @@check_ok && !@@check_warn
17
+ puts "PASSED"
18
+ elsif @@check_warn
19
+ puts "PASSED WITH WARNINGS"
20
+ else
21
+ puts "FAILED"
22
+ exit 1
23
+ end
24
+ end
25
+
26
+ def self.check_plugin(plugin)
27
+ plugin_dir = plugin.plugin_dir
28
+ STDOUT.write(plugin.name+" ")
29
+ Dir.glob("#{plugin_dir}/**/*").each do |pathname|
30
+ next unless File.file?(pathname)
31
+ next if plugin.exclude_files_from_syntax_check.include?(pathname)
32
+ plugin_relative_name = pathname[plugin_dir.length+1, pathname.length]
33
+ if pathname =~ /\.(js|hsvt)\z/i
34
+ STDOUT.write("."); STDOUT.flush
35
+ # Check JavaScript
36
+ report = syntax_check_one_file(plugin, plugin_relative_name)
37
+ if report == nil
38
+ check_file_result(plugin, plugin_relative_name, :OK)
39
+ else
40
+ puts "\n**** #{plugin_relative_name} has errors:\n#{report}\n"
41
+ check_file_result(plugin, plugin_relative_name, (plugin_relative_name =~ /\Ajs\//) ? :FAIL : :WARN)
42
+ end
43
+ else
44
+ # TODO: Checks for other file types, including the plugin.json
45
+ check_file_result(plugin, plugin_relative_name, :OK)
46
+ end
47
+ end
48
+ STDOUT.write("\n"); STDOUT.flush
49
+ end
50
+
51
+ def self.check_file_result(plugin, name, result)
52
+ unless result == :OK
53
+ @@check_report << " #{plugin.plugin_dir}/#{name}: #{result}\n"
54
+ end
55
+ @@check_ok = false if result == :FAIL
56
+ @@check_warn = true if result == :WARN
57
+ end
58
+
59
+ end
60
+
@@ -0,0 +1,73 @@
1
+
2
+ module PluginTool
3
+
4
+ LOCAL_CUSTOM_BEHAVIOUR_FILENAME = "server.behaviour.rb"
5
+
6
+ # Digests of trusted code are stored outside the source code repo, so it can't be written by the repo contents
7
+ TRUSTED_CODE_DIGESTS_FILENAME = "~/.haplo-plugin-tool-trusted.json"
8
+
9
+ class CustomBehaviour
10
+ def start(plugins, command, options, is_local_command)
11
+ end
12
+ def server_ready(plugins, command, options)
13
+ end
14
+ end
15
+
16
+ @@custom = CustomBehaviour.new
17
+
18
+ def self.set_custom_behaviour(custom)
19
+ @@custom = custom
20
+ end
21
+
22
+ def self.custom_behaviour
23
+ @@custom
24
+ end
25
+
26
+ def self.try_load_custom
27
+ return unless File.exist?(LOCAL_CUSTOM_BEHAVIOUR_FILENAME)
28
+
29
+ trusted_code = nil
30
+ untrusted_code = File.open(LOCAL_CUSTOM_BEHAVIOUR_FILENAME) { |f| f.read }
31
+ untrusted_code_digest = Digest::SHA256.hexdigest(untrusted_code)
32
+
33
+ trusted_code_digests = {"trust" => []}
34
+ trusted_code_filename = File.expand_path(TRUSTED_CODE_DIGESTS_FILENAME)
35
+ if File.exist?(trusted_code_filename)
36
+ trusted_code_digests = JSON.parse(File.open(trusted_code_filename) { |f| f.read })
37
+ end
38
+
39
+ unless trusted_code_digests["trust"].include?(untrusted_code_digest)
40
+ # Make sure the user wants to run this code. Otherwise running the plugin tool in a repo you've just
41
+ # downloaded could unexpectedly execute code on your local machine.
42
+ if ARGV.length == 2 && ARGV[0] == 'trust' && ARGV[1] =~ /\A[0-9a-z]{64}\z/ && ARGV[1] == untrusted_code_digest
43
+ trusted_code_digests["trust"].push(untrusted_code_digest)
44
+ File.open(trusted_code_filename,"w") { |f| f.write JSON.pretty_generate(trusted_code_digests) }
45
+ puts "Stored trust for #{LOCAL_CUSTOM_BEHAVIOUR_FILENAME} with contents #{untrusted_code_digest}."
46
+ exit 0
47
+ else
48
+ puts
49
+ puts "-------------------------------------------------------------------------------------------"
50
+ puts " Do you trust the code in #{LOCAL_CUSTOM_BEHAVIOUR_FILENAME} to be run every time you run the"
51
+ puts " plugin tool? If yes, run"
52
+ puts " haplo-plugin trust #{untrusted_code_digest}"
53
+ puts " to permanently trust this version of #{LOCAL_CUSTOM_BEHAVIOUR_FILENAME}"
54
+ puts "-------------------------------------------------------------------------------------------"
55
+ puts
56
+ PluginTool.beep
57
+ exit 1
58
+ end
59
+ end
60
+
61
+ if ARGV.length > 0 && ARGV[0] == "trust"
62
+ puts "Unexpected trust command."
63
+ exit 1
64
+ end
65
+
66
+ # User trusts the code, run it
67
+ # There is a race condition here, but we're trying to protect against code in repositories, not
68
+ # against software running on the local machine.
69
+ load LOCAL_CUSTOM_BEHAVIOUR_FILENAME
70
+
71
+ end
72
+
73
+ end
Binary file
@@ -0,0 +1,12 @@
1
+
2
+ module HMAC
3
+ module SHA1
4
+ def self.sign(key, message)
5
+ mac = javax.crypto.Mac.getInstance("HmacSHA1")
6
+ mac.init(javax.crypto.spec.SecretKeySpec.new(key.to_java_bytes, "HmacSHA1"))
7
+ result = mac.doFinal(message.to_java_bytes)
8
+ String.from_java_bytes(result).unpack('H*').join
9
+ end
10
+ end
11
+ end
12
+
Binary file
@@ -0,0 +1,38 @@
1
+
2
+ // Emulate enough of CommonJS to load unmodified UglifyJS files
3
+ var exports = {};
4
+ function require() {
5
+ return exports;
6
+ }
7
+
8
+ // Enough compatibility with JavaScript 1.8
9
+ // Copied from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce
10
+ if(!Array.prototype.reduce) {
11
+ Array.prototype.reduce = function reduce(accumlator){
12
+ var i, l = this.length, curr;
13
+ if(typeof accumlator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."
14
+ throw new TypeError("First argument is not callable");
15
+ if((l == 0 || l === null) && (arguments.length <= 1))// == on purpose to test 0 and false.
16
+ throw new TypeError("Array length is 0 and no second argument");
17
+ if(arguments.length <= 1){
18
+ curr = this[0]; // Increase i to start searching the secondly defined element in the array
19
+ i = 1; // start accumulating at the second element
20
+ } else {
21
+ curr = arguments[1];
22
+ }
23
+ for(i = i || 0 ; i < l ; ++i){
24
+ if(i in this)
25
+ curr = accumlator.call(undefined, curr, this[i], i, this);
26
+ }
27
+ return curr;
28
+ };
29
+ }
30
+
31
+ // Function to call from the Ruby PluginTool::Minimiser#process function
32
+ function js_min(orig_code) {
33
+ // usage from https://github.com/mishoo/UglifyJS
34
+ var ast = jsp.parse(orig_code); // parse code and get the initial AST
35
+ ast = exports.ast_mangle(ast); // get a new AST with mangled names
36
+ ast = exports.ast_squeeze(ast); // get an AST with compression optimizations
37
+ return exports.gen_code(ast); // compressed code here
38
+ }
@@ -0,0 +1,88 @@
1
+
2
+ (function() {
3
+ var root = this;
4
+
5
+ // Options for the syntax checking
6
+
7
+ var opts = function() {
8
+ return {
9
+ asi: false,
10
+ bitwise: false,
11
+ boss: false,
12
+ curly: true,
13
+ debug: false,
14
+ devel: false,
15
+ eqeqeq: false,
16
+ evil: false,
17
+ forin: false,
18
+ immed: false,
19
+ laxbreak: false,
20
+ newcap: true,
21
+ noarg: true,
22
+ noempty: false,
23
+ nonew: true,
24
+ nomen: false,
25
+ onevar: false,
26
+ plusplus: false,
27
+ regexp: false,
28
+ undef: true,
29
+ sub: true,
30
+ strict: false,
31
+ white: false
32
+ };
33
+ };
34
+
35
+ // Options
36
+ var optionsServer = opts();
37
+ var optionsBrowser = opts();
38
+ optionsBrowser.browser = true;
39
+
40
+ // Predefined globals
41
+ var globalsServer = [
42
+ 'O',
43
+ 'SCHEMA', 'TYPE', 'ATTR', 'ALIASED_ATTR', 'QUAL', 'LABEL', 'GROUP',
44
+ 'HTTP', 'DBTime',
45
+ 'console', 'JSON',
46
+ '_', 'Handlebars', 'oForms', 'moment', 'XDate'
47
+ ];
48
+ var globalsBrowser = ['Haplo', 'ONEIS', 'jQuery', '_'];
49
+ var globalsTest = globalsServer.concat('T');
50
+
51
+ // Set globals
52
+ root.syntax_tester_globals = function(string) {
53
+ globals = eval("("+string+")");
54
+ };
55
+
56
+ // Syntax tester function
57
+ root.syntax_tester = function(source, kind, extraGlobals) {
58
+ var globalList;
59
+ switch(kind) {
60
+ case "js": globalList = globalsServer; break;
61
+ case "static": globalList = globalsBrowser; break;
62
+ case "test": globalList = globalsTest; break;
63
+ }
64
+ if(!globalList) { return "Wrong kind of file"; }
65
+ var globals = {}, addGlobal = function(g) { globals[g] = false; };
66
+ globalList.forEach(addGlobal);
67
+ if(extraGlobals) {
68
+ JSON.parse(extraGlobals).forEach(addGlobal);
69
+ }
70
+ var result = JSHINT(source,
71
+ (kind !== 'static') ? optionsServer : optionsBrowser,
72
+ globals
73
+ );
74
+ if(result == true) { return null; } // success
75
+ // Errors - compile a report, can't use the default one as it's HTML
76
+ var data = JSHINT.data();
77
+ var errors = data.errors;
78
+ var report = '';
79
+ for(var e = 0; e < errors.length; e++) {
80
+ var err = errors[e];
81
+ if(err !== null && err !== undefined) { // oddly it will do that
82
+ report += "line "+err.line+": "+err.reason+"\n "+err.evidence+"\n";
83
+ }
84
+ }
85
+ return (report == '') ? null : report;
86
+ };
87
+
88
+ })();