haplo 2.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ })();