webssh

Web based ssh client https://github.com/huashengdun/webssh webssh.huashengdun.org/
git clone http://git.hanabi.in/repos/webssh.git
Log | Files | Refs | README | LICENSE

commit 4710d8c0e6daebdcdbb3c430459d35cec2266474
parent ee7fd101c635204dcef46a84ebf1c5aa4408c936
Author: Sheng <webmaster0115@gmail.com>
Date:   Fri, 24 Aug 2018 11:11:43 +0800

Added connect_with_options function

Diffstat:
Mtests/test_app.py | 3++-
Mwebssh/handler.py | 28+++++++++++++++-------------
Mwebssh/static/js/main.js | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 85 insertions(+), 21 deletions(-)

diff --git a/tests/test_app.py b/tests/test_app.py @@ -213,12 +213,13 @@ class TestApp(AsyncHTTPTestCase): headers = { 'Content-Type': content_type, 'content-length': str(len(body)) } + response = yield client.fetch(url, method='POST', headers=headers, body=body) data = json.loads(to_str(response.body)) self.assertIsNone(data['id']) self.assertIsNone(data['encoding']) - self.assertTrue(data['status'].startswith('Invalid private key')) + self.assertIn('Bad Request (Invalid unicode', data['status']) @tornado.testing.gen_test def test_app_post_form_with_large_body_size(self): diff --git a/webssh/handler.py b/webssh/handler.py @@ -66,21 +66,23 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): self.loop = loop self.policy = policy self.host_keys_settings = host_keys_settings + self.filename = None def get_privatekey(self): - lst = self.request.files.get('privatekey') - if not lst: # no privatekey provided - return - - self.filename = lst[0]['filename'] - data = lst[0]['body'] - if len(data) < KEY_MAX_SIZE: + lst = self.request.files.get('privatekey') # multipart form + if not lst: try: - return to_str(data) - except (UnicodeDecodeError, ValueError, SyntaxError): + return self.get_argument('privatekey') # urlencoded form + except tornado.web.MissingArgumentError: pass - - raise ValueError('Invalid private key: {}'.format(self.filename)) + else: + self.filename = lst[0]['filename'] + data = lst[0]['body'] + if len(data) > KEY_MAX_SIZE: + raise ValueError( + 'Invalid private key: {}'.format(self.filename) + ) + return self.decode_argument(data, name=self.filename) @classmethod def get_specific_pkey(cls, pkeycls, privatekey, password): @@ -119,7 +121,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): value = self.get_value('hostname') if not (is_valid_hostname(value) | is_valid_ipv4_address(value) | is_valid_ipv6_address(value)): - raise ValueError('Invalid hostname: {}.'.format(value)) + raise ValueError('Invalid hostname: {}'.format(value)) return value def get_port(self): @@ -132,7 +134,7 @@ class IndexHandler(MixinHandler, tornado.web.RequestHandler): if is_valid_port(port): return port - raise ValueError('Invalid port: {}.'.format(value)) + raise ValueError('Invalid port: {}'.format(value)) def get_value(self, name): value = self.get_argument(name) diff --git a/webssh/static/js/main.js b/webssh/static/js/main.js @@ -105,7 +105,7 @@ jQuery(function($){ } - function callback(resp) { + function ajax_complete_callback(resp) { btn.prop('disabled', false); if (resp.status !== 200) { @@ -116,6 +116,7 @@ jQuery(function($){ var msg = resp.responseJSON; if (msg.status) { + console.log(msg); status.text(msg.status); return; } @@ -275,7 +276,7 @@ jQuery(function($){ } - function connect() { + function connect_without_options() { if (connected) { console.log('This client was already connected.'); return; @@ -298,7 +299,7 @@ jQuery(function($){ url: url, type: 'post', data: data, - complete: callback, + complete: ajax_complete_callback, cache: false, contentType: false, processData: false @@ -323,11 +324,11 @@ jQuery(function($){ var pk = data.get('privatekey'); if (pk) { if (pk.size > key_max_size) { - status.text('Invalid private key: ' + pk.name); + console.log('Invalid private key: ' + pk.name); } else { read_file_as_text(pk, function(text) { if (text === undefined) { - status.text('Invalid private key: ' + pk.name); + console.log('Invalid private key: ' + pk.name); } else { ajax_post(); } @@ -338,11 +339,71 @@ jQuery(function($){ } } - wssh.connect = connect; + + function connect_with_options(opts) { + if (connected) { + console.log('This client was already connected.'); + return; + } + + var form = document.querySelector(form_id), + xsrf = form.querySelector('input[name="_xsrf"]').value, + url = opts.url || form.action, + hostname = opts.hostname || '', + port = opts.port || '', + username = opts.username || '', + password = opts.password || '', + privatekey = opts.privatekey || '', + data = { + '_xsrf': xsrf, + 'username': username, + 'hostname': hostname, + 'port': port, + 'password': password, + 'privatekey': privatekey + }; + + + if (!hostname || !port || !username) { + console.log('Fields hostname, port and username are all required.'); + return; + } + + if (!hostname_tester.test(hostname)) { + console.log('Invalid hostname: ' + hostname); + return; + } + + if (port <= 0 || port > 63335) { + console.log('Invalid port: ' + port); + return; + } + + if (privatekey && privatekey.length > key_max_size) { + console.log('Invalid private key: ' + privatekey); + return; + } + + $.ajax({ + url: url, + type: 'post', + data: data, + complete: ajax_complete_callback + }); + } + + wssh.connect = function(opts) { + if (opts === undefined) { + connect_without_options(); + } else { + connect_with_options(opts); + } + }; + $(form_id).submit(function(event){ event.preventDefault(); - connect(); + connect_without_options(); }); });