From 99ab9570cec307933c17b22ee39d36bc493a8737 Mon Sep 17 00:00:00 2001 From: Gittinger Date: Thu, 13 May 2021 16:00:36 -0600 Subject: [PATCH 01/28] Initial commit, adding in react page --- ...at-docker-compose-authenticated-config.ini | 2 +- web-server/js/slycat-plugins.js | 6 +++++ web-server/plugins/slycat-smb/slycat-smb.py | 24 +++++++++++++++++++ web-server/plugins/slycat-smb/ui.html | 3 +++ web-server/plugins/slycat-smb/ui.js | 13 ++++++++++ webpack.common.js | 6 +++++ 6 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 web-server/plugins/slycat-smb/slycat-smb.py create mode 100644 web-server/plugins/slycat-smb/ui.html create mode 100644 web-server/plugins/slycat-smb/ui.js diff --git a/docker/compose/slycat-compose/slycat-docker-compose-authenticated-config.ini b/docker/compose/slycat-compose/slycat-docker-compose-authenticated-config.ini index a47fcf198..73803fc9e 100644 --- a/docker/compose/slycat-compose/slycat-docker-compose-authenticated-config.ini +++ b/docker/compose/slycat-compose/slycat-docker-compose-authenticated-config.ini @@ -19,7 +19,7 @@ error-log-count: 100 error-log-size: 10000000 module-name: " " password-check: {"plugin": "slycat-identity-password-check"} -plugins: [ "plugins", "plugins/slycat-cca", "plugins/slycat-run-command", "plugins/slycat-column-wizard", "plugins/slycat-model-wizards", "plugins/slycat-parameter-image", "plugins/slycat-project-wizards", "plugins/slycat-remap-wizard", "plugins/slycat-timeseries-model", "plugins/slycat-video-swarm", "plugins/slycat-dac"] +plugins: [ "plugins", "plugins/slycat-smb", "plugins/slycat-cca", "plugins/slycat-run-command", "plugins/slycat-column-wizard", "plugins/slycat-model-wizards", "plugins/slycat-parameter-image", "plugins/slycat-project-wizards", "plugins/slycat-remap-wizard", "plugins/slycat-timeseries-model", "plugins/slycat-video-swarm", "plugins/slycat-dac"] projects-redirect: "/projects" remote-hosts: [{ "hostnames": ["localhost"], "agent.old": {"command":"/home/slycat/install/conda/bin/python /home/slycat/src/slycat/agent/slycat-docker-agent.py --json /home/slycat/src/slycat/agent/json"}}] remote-authentication: {"method":"password", "port":22, "localhost":"sshd"} diff --git a/web-server/js/slycat-plugins.js b/web-server/js/slycat-plugins.js index 3b80e4acc..9bd804322 100644 --- a/web-server/js/slycat-plugins.js +++ b/web-server/js/slycat-plugins.js @@ -43,6 +43,9 @@ export async function loadTemplate(name, format) { case "run-command": html = await import(/* webpackChunkName: "run_command_template" */ 'plugins/slycat-run-command/ui.html'); break; + case "smb": + html = await import(/* webpackChunkName: "smb_template" */ 'plugins/slycat-smb/ui.html'); + break; case "VS": html = await import(/* webpackChunkName: "ui_video_swarm_template" */ 'plugins/slycat-video-swarm/html/vs-ui.html'); break; @@ -89,6 +92,9 @@ export async function loadModule(name) { case "run-command": module = await import(/* webpackChunkName: "run_command_module" */ 'plugins/slycat-run-command/ui.js'); break; + case "smb": + module = await import(/* webpackChunkName: "run_command_module" */ 'plugins/slycat-smb/ui.js'); + break; case "VS": module = await import(/* webpackChunkName: "ui_video_swarm_module" */ 'plugins/slycat-video-swarm/js/vs-ui.js'); break; diff --git a/web-server/plugins/slycat-smb/slycat-smb.py b/web-server/plugins/slycat-smb/slycat-smb.py new file mode 100644 index 000000000..f1933a801 --- /dev/null +++ b/web-server/plugins/slycat-smb/slycat-smb.py @@ -0,0 +1,24 @@ +# Copyright (c) 2013, 2018 National Technology and Engineering Solutions of Sandia, LLC . Under the terms of Contract +# DE-NA0003525 with National Technology and Engineering Solutions of Sandia, LLC, the U.S. Government +# retains certain rights in this software. + +# coding=utf-8 +def register_slycat_plugin(context): + import os + + def page_html(database, model): + import pystache + context = dict() + return pystache.render(open(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../dist/ui_smb.html")), "r").read(), context) + + ''' + + Register a custom page + + Running this code: + + - Configure your web server to load the slycat-run-command plugin by adding it to the /etc/slycat/web-server-config.ini for the developer image + - Point a browser to https://your-slycat-server/pages/run-command + + ''' + context.register_page("smb", page_html) \ No newline at end of file diff --git a/web-server/plugins/slycat-smb/ui.html b/web-server/plugins/slycat-smb/ui.html new file mode 100644 index 000000000..a7b69b6ee --- /dev/null +++ b/web-server/plugins/slycat-smb/ui.html @@ -0,0 +1,3 @@ + +
+
\ No newline at end of file diff --git a/web-server/plugins/slycat-smb/ui.js b/web-server/plugins/slycat-smb/ui.js new file mode 100644 index 000000000..616606d9e --- /dev/null +++ b/web-server/plugins/slycat-smb/ui.js @@ -0,0 +1,13 @@ +import React from "react"; +import ReactDOM from "react-dom"; +const SMBWizard= () => { + return ( +
+ SMB Wizard +
+ ) +} +ReactDOM.render( + , + document.querySelector(".smb-wizard") + ); diff --git a/webpack.common.js b/webpack.common.js index c1575f29a..c0802b1d8 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -31,6 +31,7 @@ module.exports = { // ui_parameter_plus: './web-server/plugins/slycat-parameter-image-plus-model/js/ui.js', ui_run_command: './web-server/plugins/slycat-run-command/ui.js', slycat_projects: './web-server/js/slycat-projects-main.js', + ui_smb: './web-server/plugins/slycat-smb/ui.js', slycat_project: './web-server/js/slycat-project-main.js', slycat_page: './web-server/js/slycat-page-main.js', slycat_model: './web-server/js/slycat-model-main.js', @@ -81,6 +82,11 @@ module.exports = { filename: 'ui_run_command.html', chunks: ['ui_run_command'], }), + new HtmlWebpackPlugin({ + template: 'web-server/plugins/slycat-smb/ui.html', + filename: 'ui_smb.html', + chunks: ['ui_smb'], + }), new HtmlWebpackPlugin({ template: 'web-server/templates/slycat-projects.html', filename: 'slycat_projects.html', From bbbdb343b9078af806d2dd1f48a0ee4be6ca7328 Mon Sep 17 00:00:00 2001 From: Gittinger Date: Thu, 13 May 2021 16:18:01 -0600 Subject: [PATCH 02/28] Adding remote file browser to smb page --- web-server/plugins/slycat-smb/ui.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/web-server/plugins/slycat-smb/ui.js b/web-server/plugins/slycat-smb/ui.js index 616606d9e..d78c47eaf 100644 --- a/web-server/plugins/slycat-smb/ui.js +++ b/web-server/plugins/slycat-smb/ui.js @@ -1,9 +1,24 @@ import React from "react"; import ReactDOM from "react-dom"; +import RemoteFileBrowser from 'components/RemoteFileBrowser.tsx' + +const onSelectTableFile = () => { + console.log("onSelecTableFile"); +} + +const onReauth = () => { + console.log("onReauth"); +} + const SMBWizard= () => { return (
SMB Wizard +
) } From a17aed7befe7a3d563cca7e270a556b206a5ad07 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Thu, 13 May 2021 17:01:46 -0600 Subject: [PATCH 03/28] Create smb.py --- packages/slycat/web/server/smb.py | 106 ++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 packages/slycat/web/server/smb.py diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py new file mode 100644 index 000000000..48020995c --- /dev/null +++ b/packages/slycat/web/server/smb.py @@ -0,0 +1,106 @@ +import tempfile +from smb.SMBConnection import SMBConnection +import socket +import logging +import datetime +import cherrypy +import slycat.mime_type + +class Smb(object): + """ + usage: + smb = Smb('user', 'password', 'server', 'share_name') + """ + def __init__(self, username, password, server, share, domain='', port=445): + # setup data + self.domain = str(domain) + self.username = str(username) + self.password = str(password) + self.client = socket.gethostname() + self.server = str(server) + self.server_ip = socket.gethostbyname(server) + self.share = str(share) + self.port = port + self.conn = None + self.connected = False + # SMB.SMBConnection logs too much + smb_logger = logging.getLogger('SMB.SMBConnection') + smb_logger.setLevel(logging.INFO) + + def connect(self): + try: + self.conn = SMBConnection(self.username, self.password, + self.client, self.server, + is_direct_tcp=True) + self.connected = self.conn.connect(self.server_ip, self.port) + cherrypy.log.error('Connected to %s smb server' % self.server) + return self.connected + except Exception as e: + cherrypy.log.error('Connect failed. Reason: %s', e) + return False + + def list_shares(self): + try: + shares_list = self.conn.listShares() # obtain a list of shares + for share in shares_list: # iterate through the list of shares + cherrypy.log.error(" Share=", share.name) + except Exception as e: + cherrypy.log.error(str(e)) + cherrypy.log.error('### can not list shares') + + def list_path(self, share=None, path='/'): + if share is None: + share=self.share + try: + for sub_share in sorted(self.conn.listPath(share,path), key=lambda item: item.filename): + cherrypy.log.error(" File=", sub_share.filename) + cherrypy.log.error(" Fileinfo= %s" % hex(sub_share.file_attributes)) + cherrypy.log.error(" File isdir= %s" % sub_share.isDirectory) + except Exception as e: + cherrypy.log.error(str(e)) + cherrypy.log.error('### can not list shares') + + def list_Attributes(self, share=None, path='/'): + if share is None: + cherrypy.log.error('getting %s'%path) + share=self.share + try: + return self.conn.getAttributes(share,path) + except Exception as e: + cherrypy.log.error(str(e)) + cherrypy.log.error('### can not list shares') + return None + + # Handle the 'browse' command. + def browse(self, share=None, path='/'): + if share is None: + share=self.share + if path is None: + raise Exception("Missing path.") + + listing = { + "path": path, + "names": [], + "sizes": [], + "types": [], + "mtimes": [], + "mime-types": [], + } + + for sub_share in sorted(self.conn.listPath(share,path), key=lambda item: item.filename): + cherrypy.log.error(" File=", sub_share.filename) + cherrypy.log.error(" Fileinfo= %s" % hex(sub_share.file_attributes)) + cherrypy.log.error(" File isdir= %s" % sub_share.isDirectory) + ftype = "d" if sub_share.isDirectory else "f" + if ftype == "d": + mime_type = "application/x-directory" + else: + mime_type = slycat.mime_type.guess_type(sub_share.filename)[0] + + listing["names"].append(sub_share.filename) + listing["sizes"].append(sub_share.file_size) + listing["types"].append(ftype) + listing["mtimes"].append(datetime.datetime.fromtimestamp(sub_share.last_write_time).isoformat()) + listing["mime-types"].append(mime_type) + + return listing \ No newline at end of file From a8aac2ddac489834288e0865f9541789ddb82861 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 14 May 2021 16:23:05 -0600 Subject: [PATCH 04/28] adding authentication for smb drives --- packages/slycat/web/server/engine.py | 2 +- packages/slycat/web/server/handlers.py | 60 +++++++++++++- packages/slycat/web/server/smb.py | 78 ++++++++++++++++++- .../plugins/slycat-no-authentication.py | 2 +- 4 files changed, 135 insertions(+), 7 deletions(-) diff --git a/packages/slycat/web/server/engine.py b/packages/slycat/web/server/engine.py index 902742dae..6e78052f4 100644 --- a/packages/slycat/web/server/engine.py +++ b/packages/slycat/web/server/engine.py @@ -140,9 +140,9 @@ def abspath(path): dispatcher.connect("post-log", "/log", slycat.web.server.handlers.post_log, conditions={"method" : ["POST"]}) dispatcher.connect("post-projects", "/projects", slycat.web.server.handlers.post_projects, conditions={"method" : ["POST"]}) - #TODO: scrub sid dispatcher.connect("post-remote-browse", "/remotes/:hostname/browse{path:.*}", slycat.web.server.handlers.post_remote_browse, conditions={"method" : ["POST"]}) dispatcher.connect("post-remotes", "/remotes", slycat.web.server.handlers.post_remotes, conditions={"method" : ["POST"]}) + dispatcher.connect("post-remotes-smb", "/remotes/smb", slycat.web.server.handlers.post_remotes_smb, conditions={"method" : ["POST"]}) dispatcher.connect("put-model-arrayset-array", "/models/:mid/arraysets/:aid/arrays/:array", slycat.web.server.handlers.put_model_arrayset_array, conditions={"method" : ["PUT"]}) diff --git a/packages/slycat/web/server/handlers.py b/packages/slycat/web/server/handlers.py index 5d0ca304e..db0efeb1a 100644 --- a/packages/slycat/web/server/handlers.py +++ b/packages/slycat/web/server/handlers.py @@ -1886,18 +1886,16 @@ def validate_table_columns(columns): columns = [(int(spec[0]), int(spec[1]) if len(spec) == 2 else int(spec[0]) + 1) for spec in columns] columns = numpy.concatenate([numpy.arange(begin, end) for begin, end in columns]) columns = columns[columns >= 0] - return columns - except: + except Exception as e: + cherrypy.log.error(str(e)) cherrypy.log.error("slycat.web.server.handlers.py validate_table_columns", "cherrypy.HTTPError 400 malformed columns argument must be a comma separated collection of column indices or half-open index ranges.") raise cherrypy.HTTPError( "400 Malformed columns argument must be a comma separated collection of column indices or half-open index ranges.") - if numpy.any(columns < 0): cherrypy.log.error("slycat.web.server.handlers.py validate_table_columns", "cherrypy.HTTPError 400 column values must be non-negative.") raise cherrypy.HTTPError("400 Column values must be non-negative.") - return columns @@ -2468,6 +2466,60 @@ def post_remotes(): return {"sid": sid, "status": True, "msg": msg} +@cherrypy.tools.json_in(on=True) +@cherrypy.tools.json_out(on=True) +def post_remotes_smb(): + """ + Given username, hostname, password as a json payload + establishes a session with the remote host and attaches + it to the users session + :return: {"sid":sid, "status":boolean, msg:""} + user_name password + + encode with in js + + b64EncodeUnicode(str) { + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { + return String.fromCharCode('0x' + p1); + })); + } + """ + + # try and decode the username and password + username = str(cherrypy.request.json["user_name"]) + password = str(cherrypy.request.json["password"]) + # username, password = slycat.web.server.decode_username_and_password() + server = cherrypy.request.json["server"] + cherrypy.log.error("username:%s password:%s server:%s"%(username, password, server)) + # username/password are not guaranteed to exist within the incoming json + # (they don't exist for rsa-cert auth) + if username == None: + username = cherrypy.request.login + + msg = "" + return {"smb_id":"smb_id"} + smb_id = slycat.web.server.smb.create_session(username,password,server,'share') + ''' + save sid to user session + the session will be stored as follows in the users session + {sessions:[{{"sid": sid,"hostname": hostname, "username": username}},...]} + ''' + try: + database = slycat.web.server.database.couchdb.connect() + session = database.get("session", cherrypy.request.cookie["slycatauth"].value) + for i in range(len(session["sessions"])): + if session["sessions"][i]["hostname"] == hostname: + if("sid" in session["sessions"][i] and session["sessions"][i]["sid"] is not None): + slycat.web.server.remote.delete_session(session["sessions"][i]["sid"]) + del session["sessions"][i] + session["sessions"].append({"sid": sid, "hostname": hostname, "username": username}) + database.save(session) + except Exception as e: + cherrypy.log.error("login could not save session for remotes %s" % e) + msg = "login could not save session for remote host" + return {"sid": sid, "status": True, "msg": msg} + + @cherrypy.tools.json_out(on=True) def get_remotes(hostname): """ diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py index 48020995c..66cb013a9 100644 --- a/packages/slycat/web/server/smb.py +++ b/packages/slycat/web/server/smb.py @@ -1,10 +1,15 @@ import tempfile +import threading +import time +import uuid from smb.SMBConnection import SMBConnection import socket import logging import datetime import cherrypy import slycat.mime_type +session_cache = {} +session_cache_lock = threading.Lock() class Smb(object): """ @@ -103,4 +108,75 @@ def browse(self, share=None, path='/'): listing["mtimes"].append(datetime.datetime.fromtimestamp(sub_share.last_write_time).isoformat()) listing["mime-types"].append(mime_type) - return listing \ No newline at end of file + return listing + +def create_session(username, password, server, share): + """ + Create a cached smb remote session for the given host. + + Parameters + ---------- + username : string + Username for ssh authentication. + password : string + Password for ssh authentication. + server : string + server that the share is connected to + share : string + share name that is being connected to + + Returns + ------- + smb_id : string + A unique session identifier. + """ + _start_session_cleanup_worker() + smb_id = uuid.uuid4().hex + try: + with session_cache_lock: + cherrypy.log.error("create the seesion and add it to the session_cache") + session_cache[smb_id] = Smb(username, password, server, share) + return smb_id + except Exception as e: + cherrypy.log.error("Unknown exception for %s@%s: %s %s" % (username, server, type(e), str(e))) + cherrypy.log.error("slycat.web.server.remote.py create_session", + "cherrypy.HTTPError 500 unknown exception for %s@%s: %s %s." % ( + username, server, type(e), str(e))) + raise cherrypy.HTTPError("401 Remote connection failed: %s" % str(e)) + +def _expire_session(sid): + """ + Test an existing session to see if it is expired. + + Assumes that the caller already holds session_cache_lock. + """ + if sid in session_cache: + now = datetime.datetime.utcnow() + session = session_cache[sid] + if now - session.accessed > slycat.web.server.config["slycat-web-server"]["remote-session-timeout"]: + cherrypy.log.error( + "Timing-out remote session for %s@%s from %s" % (session.username, session.hostname, session.client)) + try: + session_cache[sid].close() + except Exception as e: + pass + del session_cache[sid] + +def _session_monitor(): + while True: + cherrypy.log.error("Remote session cleanup worker running.") + with session_cache_lock: + for sid in list(session_cache.keys()): # We make an explicit copy of the keys because we may be modifying the dict contents + _expire_session(sid) + cherrypy.log.error("Remote SMB session cleanup worker finished.") + time.sleep(datetime.timedelta(minutes=15).total_seconds()) + +def _start_session_cleanup_worker(): + if _start_session_cleanup_worker.thread is None: + cherrypy.log.error("Starting remote SMB session cleanup worker.") + _start_session_cleanup_worker.thread = threading.Thread(name="SMB Monitor", target=_session_monitor) + _start_session_cleanup_worker.thread.daemon = True + _start_session_cleanup_worker.thread.start() + + +_start_session_cleanup_worker.thread = None diff --git a/web-server/plugins/slycat-no-authentication.py b/web-server/plugins/slycat-no-authentication.py index ae0dfa023..19e1def2d 100644 --- a/web-server/plugins/slycat-no-authentication.py +++ b/web-server/plugins/slycat-no-authentication.py @@ -28,7 +28,7 @@ def authenticate(realm, rules=None): # See if the client already has a valid session. if "slycatauth" in cherrypy.request.cookie: - cherrypy.log.error('ding') + cherrypy.log.error('running cherrypy no authentication') sid = cherrypy.request.cookie["slycatauth"].value couchdb = slycat.web.server.database.couchdb.connect() session = None From 2c2a47ac22540de62aa189c4536680bb625e6190 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 14 May 2021 17:43:00 -0600 Subject: [PATCH 05/28] correcting imports and adding it to docker --- docker/compose/slycat-compose/requirements.txt | 1 + packages/slycat/web/server/handlers.py | 3 ++- packages/slycat/web/server/smb.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/compose/slycat-compose/requirements.txt b/docker/compose/slycat-compose/requirements.txt index 5106368e0..f3cd2efd6 100644 --- a/docker/compose/slycat-compose/requirements.txt +++ b/docker/compose/slycat-compose/requirements.txt @@ -11,3 +11,4 @@ routes scipy npTDMS pandas +pysmb diff --git a/packages/slycat/web/server/handlers.py b/packages/slycat/web/server/handlers.py index db0efeb1a..698aad7a7 100644 --- a/packages/slycat/web/server/handlers.py +++ b/packages/slycat/web/server/handlers.py @@ -25,6 +25,7 @@ import slycat.web.server.hdf5 import slycat.web.server.plugin import slycat.web.server.remote +import slycat.web.server.smb import slycat.web.server.streaming import slycat.web.server.upload import stat @@ -2497,8 +2498,8 @@ def post_remotes_smb(): username = cherrypy.request.login msg = "" - return {"smb_id":"smb_id"} smb_id = slycat.web.server.smb.create_session(username,password,server,'share') + return {"smb_id":smb_id} ''' save sid to user session the session will be stored as follows in the users session diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py index 66cb013a9..8a4e394bf 100644 --- a/packages/slycat/web/server/smb.py +++ b/packages/slycat/web/server/smb.py @@ -139,7 +139,7 @@ def create_session(username, password, server, share): return smb_id except Exception as e: cherrypy.log.error("Unknown exception for %s@%s: %s %s" % (username, server, type(e), str(e))) - cherrypy.log.error("slycat.web.server.remote.py create_session", + cherrypy.log.error("slycat.web.server.smb.py create_session", "cherrypy.HTTPError 500 unknown exception for %s@%s: %s %s." % ( username, server, type(e), str(e))) raise cherrypy.HTTPError("401 Remote connection failed: %s" % str(e)) From 3f35222c3989ed1749ab3142063bdbb2487206ed Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Thu, 20 May 2021 11:10:15 -0600 Subject: [PATCH 06/28] Update DockerFile --- docker/compose/slycat-compose/haproxy/DockerFile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/compose/slycat-compose/haproxy/DockerFile b/docker/compose/slycat-compose/haproxy/DockerFile index 50dad078f..5cb7cf2b9 100644 --- a/docker/compose/slycat-compose/haproxy/DockerFile +++ b/docker/compose/slycat-compose/haproxy/DockerFile @@ -1,5 +1,5 @@ FROM haproxy:alpine - +USER root WORKDIR /etc/slycat RUN sed -i -e 's/https/http/' /etc/apk/repositories RUN apk upgrade --update-cache --available && \ From 138b9abc3c77ca0dc593be460edb33299d184382 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 21 May 2021 15:48:27 -0600 Subject: [PATCH 07/28] finishing auth and browse for smb --- packages/slycat/web/server/engine.py | 2 + packages/slycat/web/server/handlers.py | 42 +++++++----- packages/slycat/web/server/remote.py | 8 --- packages/slycat/web/server/smb.py | 93 ++++++++++++++++++++++++-- 4 files changed, 116 insertions(+), 29 deletions(-) diff --git a/packages/slycat/web/server/engine.py b/packages/slycat/web/server/engine.py index 6e78052f4..e9ebaaf1e 100644 --- a/packages/slycat/web/server/engine.py +++ b/packages/slycat/web/server/engine.py @@ -143,6 +143,8 @@ def abspath(path): dispatcher.connect("post-remote-browse", "/remotes/:hostname/browse{path:.*}", slycat.web.server.handlers.post_remote_browse, conditions={"method" : ["POST"]}) dispatcher.connect("post-remotes", "/remotes", slycat.web.server.handlers.post_remotes, conditions={"method" : ["POST"]}) dispatcher.connect("post-remotes-smb", "/remotes/smb", slycat.web.server.handlers.post_remotes_smb, conditions={"method" : ["POST"]}) + dispatcher.connect("post-smb-browse", "/smb/remotes/:hostname/browse{path:.*}", slycat.web.server.handlers.post_smb_browse, conditions={"method" : ["POST"]}) + dispatcher.connect("put-model-arrayset-array", "/models/:mid/arraysets/:aid/arrays/:array", slycat.web.server.handlers.put_model_arrayset_array, conditions={"method" : ["PUT"]}) diff --git a/packages/slycat/web/server/handlers.py b/packages/slycat/web/server/handlers.py index 698aad7a7..1056377f7 100644 --- a/packages/slycat/web/server/handlers.py +++ b/packages/slycat/web/server/handlers.py @@ -69,12 +69,18 @@ def get_sid(hostname): for index, host_session in enumerate(session["sessions"]): if host_session["hostname"] == hostname: sid = host_session["sid"] - if(not slycat.web.server.remote.check_session(sid)): + if(host_session["session_type"] == "ssh" and not slycat.web.server.remote.check_session(sid)): cherrypy.log.error("error %s SID:%s Keys %s" % (slycat.web.server.remote.check_session(sid), sid, list(slycat.web.server.remote.session_cache.keys()))) slycat.web.server.remote.delete_session(sid) del session["sessions"][index] database.save(session) raise cherrypy.HTTPError("404") + elif(host_session["session_type"] == "smb" and not slycat.web.server.smb.check_session(sid)): + cherrypy.log.error("error %s SID:%s Keys %s" % (slycat.web.server.smb.check_session(sid), sid, list(slycat.web.server.smb.session_cache.keys()))) + slycat.web.server.smb.delete_session(sid) + del session["sessions"][index] + database.save(session) + raise cherrypy.HTTPError("404") break except Exception as e: cherrypy.log.error("could not retrieve host session for remotes %s" % e) @@ -1196,7 +1202,7 @@ def clear_ssh_sessions(): sid = cherrypy.request.cookie["slycatauth"].value couchdb = slycat.web.server.database.couchdb.connect() session = couchdb.get("session", sid) - cherrypy.log.error("ssh sessions cleared for user session: %s" % session) + cherrypy.log.error("ssh and smb sessions cleared for user session: %s" % session) cherrypy.response.status = "200" if session is not None: for ssh_session in session["sessions"]: @@ -2459,7 +2465,7 @@ def post_remotes(): if("sid" in session["sessions"][i] and session["sessions"][i]["sid"] is not None): slycat.web.server.remote.delete_session(session["sessions"][i]["sid"]) del session["sessions"][i] - session["sessions"].append({"sid": sid, "hostname": hostname, "username": username}) + session["sessions"].append({"sid": sid, "hostname": hostname, "username": username, "session_type": "ssh"}) database.save(session) except Exception as e: cherrypy.log.error("login could not save session for remotes %s" % e) @@ -2485,21 +2491,15 @@ def post_remotes_smb(): })); } """ - # try and decode the username and password - username = str(cherrypy.request.json["user_name"]) - password = str(cherrypy.request.json["password"]) - # username, password = slycat.web.server.decode_username_and_password() + username, password = slycat.web.server.decode_username_and_password() server = cherrypy.request.json["server"] - cherrypy.log.error("username:%s password:%s server:%s"%(username, password, server)) - # username/password are not guaranteed to exist within the incoming json - # (they don't exist for rsa-cert auth) + share = cherrypy.request.json["share"] + cherrypy.log.error("username:%s server:%s share:%s" % (username, server , share)) if username == None: username = cherrypy.request.login - msg = "" - smb_id = slycat.web.server.smb.create_session(username,password,server,'share') - return {"smb_id":smb_id} + sid = slycat.web.server.smb.create_session(username,password,server,share) ''' save sid to user session the session will be stored as follows in the users session @@ -2507,19 +2507,31 @@ def post_remotes_smb(): ''' try: database = slycat.web.server.database.couchdb.connect() + cherrypy.log.error("got the database") session = database.get("session", cherrypy.request.cookie["slycatauth"].value) for i in range(len(session["sessions"])): - if session["sessions"][i]["hostname"] == hostname: + if session["sessions"][i]["hostname"] == server: if("sid" in session["sessions"][i] and session["sessions"][i]["sid"] is not None): slycat.web.server.remote.delete_session(session["sessions"][i]["sid"]) del session["sessions"][i] - session["sessions"].append({"sid": sid, "hostname": hostname, "username": username}) + cherrypy.log.error("adding session") + session["sessions"].append({"sid": sid, "hostname": server, "username": username, "session_type": "smb"}) + cherrypy.log.error("saving") database.save(session) + cherrypy.log.error("saved") except Exception as e: cherrypy.log.error("login could not save session for remotes %s" % e) msg = "login could not save session for remote host" return {"sid": sid, "status": True, "msg": msg} +@cherrypy.tools.json_in(on=True) +@cherrypy.tools.json_out(on=True) +def post_smb_browse(hostname, path): + cherrypy.log.error("path:%s hostname:%s" % (path, hostname)) + sid = get_sid(hostname) + cherrypy.log.error("sid:%s path:%s hostname:%s" % (sid, path, hostname)) + with slycat.web.server.smb.get_session(sid) as session: + return session.browse(path=path) @cherrypy.tools.json_out(on=True) def get_remotes(hostname): diff --git a/packages/slycat/web/server/remote.py b/packages/slycat/web/server/remote.py index bcd822dbd..da57c74ea 100644 --- a/packages/slycat/web/server/remote.py +++ b/packages/slycat/web/server/remote.py @@ -1114,17 +1114,9 @@ def check_session(sid): ------- boolean : """ - # client = cherrypy.request.headers.get("x-forwarded-for") - with session_cache_lock: _expire_session(sid) response = True - if sid in session_cache: - session = session_cache[sid] - # Only the originating client can access a session. - # if client != session.client: - # response = False - if sid not in session_cache: response = False if response: diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py index 8a4e394bf..0746f9c9f 100644 --- a/packages/slycat/web/server/smb.py +++ b/packages/slycat/web/server/smb.py @@ -18,6 +18,7 @@ class Smb(object): """ def __init__(self, username, password, server, share, domain='', port=445): # setup data + now = datetime.datetime.utcnow() self.domain = str(domain) self.username = str(username) self.password = str(password) @@ -29,8 +30,23 @@ def __init__(self, username, password, server, share, domain='', port=445): self.conn = None self.connected = False # SMB.SMBConnection logs too much + self._created = now + self._accessed = now smb_logger = logging.getLogger('SMB.SMBConnection') smb_logger.setLevel(logging.INFO) + self._lock = threading.Lock() + + def __enter__(self): + self._lock.__enter__() + return self + + def __exit__(self, exc_type, exc_value, traceback): + return self._lock.__exit__(exc_type, exc_value, traceback) + + @property + def accessed(self): + """Return the time the session was last accessed.""" + return self._accessed def connect(self): try: @@ -136,13 +152,82 @@ def create_session(username, password, server, share): with session_cache_lock: cherrypy.log.error("create the seesion and add it to the session_cache") session_cache[smb_id] = Smb(username, password, server, share) - return smb_id + if session_cache[smb_id].connect(): + return smb_id + raise cherrypy.HTTPError("401 Remote smb connection failed: could not connect to smb drive") except Exception as e: cherrypy.log.error("Unknown exception for %s@%s: %s %s" % (username, server, type(e), str(e))) cherrypy.log.error("slycat.web.server.smb.py create_session", "cherrypy.HTTPError 500 unknown exception for %s@%s: %s %s." % ( username, server, type(e), str(e))) - raise cherrypy.HTTPError("401 Remote connection failed: %s" % str(e)) + raise cherrypy.HTTPError("401 Remote smb connection failed: %s" % str(e)) + + +def check_session(sid): + """ + Return a true if session is active + + If the session has timed-out or doesn't exist, returns false + + Parameters + ---------- + sid : string + Unique session identifier returned by :func:`slycat.web.server.remote.create_session`. + + Returns + ------- + boolean : + """ + with session_cache_lock: + _expire_session(sid) + response = True + if sid not in session_cache: + response = False + if response: + session = session_cache[sid] + session._accessed = datetime.datetime.utcnow() + return response + + +def delete_session(sid): + """ + Delete a cached remote session. + + Parameters + ---------- + sid : string, required + Unique session identifier returned by :func:`slycat.web.server.remote.create_session`. + """ + with session_cache_lock: + if sid in session_cache: + session = session_cache[sid] + cherrypy.log.error( + "Deleting remote session for %s@%s" % (session.username, session.hostname)) + del session_cache[sid] + +def get_session(sid): + """ + Return a cached smb remote session. + + If the session has timed-out or doesn't exist, raises a 404 exception. + + Parameters + ---------- + sid : string + Unique session identifier returned by :func:`slycat.web.server.smb.create_session`. + + Returns + ------- + session : :class:`slycat.web.server.smb.Session` + Session object that encapsulates the connection to a smb remote host. + """ + with session_cache_lock: + _expire_session(sid) + if sid not in session_cache: + raise cherrypy.HTTPError("404 not a session") + session = session_cache[sid] + session._accessed = datetime.datetime.utcnow() + return session def _expire_session(sid): """ @@ -156,10 +241,6 @@ def _expire_session(sid): if now - session.accessed > slycat.web.server.config["slycat-web-server"]["remote-session-timeout"]: cherrypy.log.error( "Timing-out remote session for %s@%s from %s" % (session.username, session.hostname, session.client)) - try: - session_cache[sid].close() - except Exception as e: - pass del session_cache[sid] def _session_monitor(): From bb8508cf5df48d4e5a141348267e56b1e981da57 Mon Sep 17 00:00:00 2001 From: Gittinger Date: Fri, 28 May 2021 14:12:31 -0600 Subject: [PATCH 08/28] Adding smb browse to UI --- web-server/components/ModalMedium.tsx | 2 +- web-server/components/RemoteFileBrowser.tsx | 9 ++- web-server/js/slycat-web-client.js | 52 ++++++++++++++- web-server/plugins/slycat-smb/ui.js | 73 ++++++++++++++++++++- 4 files changed, 129 insertions(+), 7 deletions(-) diff --git a/web-server/components/ModalMedium.tsx b/web-server/components/ModalMedium.tsx index 17c924e34..3a3769115 100644 --- a/web-server/components/ModalMedium.tsx +++ b/web-server/components/ModalMedium.tsx @@ -42,7 +42,7 @@ export default class ModalMedium extends React.Component +
diff --git a/web-server/components/RemoteFileBrowser.tsx b/web-server/components/RemoteFileBrowser.tsx index 8e916a47e..16dd98cce 100644 --- a/web-server/components/RemoteFileBrowser.tsx +++ b/web-server/components/RemoteFileBrowser.tsx @@ -94,11 +94,13 @@ export default class RemoteFileBrowser extends React.Component { + console.log("In browse"); // First check if we have a remote connection... client.get_remotes_fetch(this.props.hostname) .then((json) => { // If we have a session, go on. - if(json.status) { + console.log("one tier in"); + if(true) { pathInput = (pathInput === ""?"/":pathInput); this.setState({ rawFiles:[], @@ -106,8 +108,9 @@ export default class RemoteFileBrowser extends React.Component { + if (errorFunction) { + errorFunction(error) + }else{ + console.log(error); + } + }); +}; + module.post_sensitive_model_command_fetch = function(params, successFunction, errorFunction) { return fetch(`${api_root}models/${params.mid}/sensitive/${params.type}/${params.command}`, @@ -783,7 +810,6 @@ module.post_sensitive_model_command_fetch = function(params, successFunction, er }); }; - module.put_model_command = function(params) { $.ajax( @@ -1523,6 +1549,30 @@ module.post_remote_command = function(params) { }); }; +module.post_remote_browse_smb = function(params) +{ + console.log("In browse smb"); + $.ajax( + { + contentType: "application/json", + data: JSON.stringify( + { + }), + type: "POST", + url: api_root + "smb/remotes/" + params.hostname + "/browse" + params.path, + success: function(result) + { + if(params.success) + params.success(result); + }, + error: function(request, status, reason_phrase) + { + if(params.error) + params.error(request, status, reason_phrase); + } + }); +}; + module.post_remote_browse = function(params) { $.ajax( diff --git a/web-server/plugins/slycat-smb/ui.js b/web-server/plugins/slycat-smb/ui.js index d78c47eaf..44e3b750d 100644 --- a/web-server/plugins/slycat-smb/ui.js +++ b/web-server/plugins/slycat-smb/ui.js @@ -1,6 +1,30 @@ import React from "react"; import ReactDOM from "react-dom"; import RemoteFileBrowser from 'components/RemoteFileBrowser.tsx' +import ModalContent from "components/ModalContent.tsx"; +import ModalMedium from "components/ModalMedium.tsx"; +import client from "js/slycat-web-client"; + +let userName = ""; +let password = ""; + +const b64EncodeUnicode = (str) => { + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { + return String.fromCharCode('0x' + p1); + })); +}; + +let encodedUserName = b64EncodeUnicode(userName); +let encodedPassword = b64EncodeUnicode(password); + +client.post_remotes_smb_fetch({ + user_name:encodedUserName, + password:encodedPassword, + server:"", + share: "" +}).then(() => { + console.log("Woot authenticated."); +}); const onSelectTableFile = () => { console.log("onSelecTableFile"); @@ -10,19 +34,64 @@ const onReauth = () => { console.log("onReauth"); } -const SMBWizard= () => { +const cleanup = () => { + console.log("Woo, cleaned."); +} + +const getFooterJsx = () => { + let footerJSX = []; + footerJSX.push( + + ); + return footerJSX; +} + +const getBodyJsx = () => { return (
SMB Wizard
+ ); +} + +const SMBWizard= () => { + return ( + //
+ // SMB Wizard + // + //
+
+
+
+ +
+
+
) } ReactDOM.render( , document.querySelector(".smb-wizard") ); + +// For testing purposes + $(document).ready(function(){ + $("#myModal").modal('show'); +}); \ No newline at end of file From e274ed7877bd80f321dd6aa47ecce31bf705695e Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 28 May 2021 14:55:34 -0600 Subject: [PATCH 09/28] adding browse to the modal --- packages/slycat/web/server/handlers.py | 6 +- packages/slycat/web/server/smb.py | 7 +- web-server/components/RemoteFileBrowser.tsx | 7 +- .../components/SmbRemoteFileBrowser.tsx | 388 ++++++++++++++++++ web-server/plugins/slycat-smb/ui.js | 10 +- 5 files changed, 402 insertions(+), 16 deletions(-) create mode 100644 web-server/components/SmbRemoteFileBrowser.tsx diff --git a/packages/slycat/web/server/handlers.py b/packages/slycat/web/server/handlers.py index 1056377f7..3e47575e8 100644 --- a/packages/slycat/web/server/handlers.py +++ b/packages/slycat/web/server/handlers.py @@ -2548,12 +2548,16 @@ def get_remotes(hostname): session = database.get("session", cherrypy.request.cookie["slycatauth"].value) for h_session in session["sessions"]: if h_session["hostname"] == hostname: - if slycat.web.server.remote.check_session(h_session["sid"]): + if h_session["session_type"] == "ssh" and not slycat.web.server.remote.check_session(sid): + status = True + msg = "hostname session was found" + elif h_session["session_type"] == "smb" and not slycat.web.server.smb.check_session(sid): status = True msg = "hostname session was found" else: session["sessions"][:] = [tup for tup in session["sessions"] if tup["hostname"] != hostname] database.save(session) + except Exception as e: cherrypy.log.error("status could not save session for remotes %s" % e) return {"status": status, "msg": msg, "hostName": hostname} diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py index 0746f9c9f..2c49fc00f 100644 --- a/packages/slycat/web/server/smb.py +++ b/packages/slycat/web/server/smb.py @@ -62,12 +62,9 @@ def connect(self): def list_shares(self): try: - shares_list = self.conn.listShares() # obtain a list of shares - for share in shares_list: # iterate through the list of shares - cherrypy.log.error(" Share=", share.name) + return self.conn.listShares() except Exception as e: - cherrypy.log.error(str(e)) - cherrypy.log.error('### can not list shares') + raise cherrypy.HTTPError("401 Remote smb connection failed reseting: %s" % str(e)) def list_path(self, share=None, path='/'): if share is None: diff --git a/web-server/components/RemoteFileBrowser.tsx b/web-server/components/RemoteFileBrowser.tsx index 16dd98cce..92474dbe7 100644 --- a/web-server/components/RemoteFileBrowser.tsx +++ b/web-server/components/RemoteFileBrowser.tsx @@ -94,13 +94,11 @@ export default class RemoteFileBrowser extends React.Component { - console.log("In browse"); // First check if we have a remote connection... client.get_remotes_fetch(this.props.hostname) .then((json) => { // If we have a session, go on. - console.log("one tier in"); - if(true) { + if(json.status) { pathInput = (pathInput === ""?"/":pathInput); this.setState({ rawFiles:[], @@ -109,8 +107,7 @@ export default class RemoteFileBrowser extends React.Component} + */ +export default class SmbRemoteFileBrowser extends React.Component { + public constructor(props:RemoteFileBrowserProps) { + super(props) + this.state = { + path:"/", + pathInput: "/", + rawFiles: [], + pathError: false, + browseError: false, + persistenceId: props.persistenceId === undefined ? '' : props.persistenceId, + browserUpdating: false, + selected:-1 + } + } + + /** + * given a path return all the items in said path (like ls) + * + * @param pathInput path to return all ls properties from + * @private + * @memberof RemoteFileBrowser + */ + private browse = (pathInput:string) => + { + // First check if we have a remote connection... + client.get_remotes_fetch(this.props.hostname) + .then((json) => { + // If we have a session, go on. + if(json.status) { + pathInput = (pathInput === ""?"/":pathInput); + this.setState({ + rawFiles:[], + browserUpdating:true, + selected:-1, + path:pathInput, + pathInput + }); + client.post_remote_browse_smb( + { + hostname : this.props.hostname, + path : pathInput, + success : (results:any) => + { + localStorage.setItem("slycat-remote-browser-path-" + this.state.persistenceId + this.props.hostname, pathInput); + this.setState({ + browseError:false, + pathError:false, + }); + + let files: FileMetaData[] = [] + if(pathInput != "/") + files.push({type: "", name: "..", size: "", mtime: "", mimeType:"application/x-directory"}); + for(let i = 0; i != results.names.length; ++i) + files.push({name:results.names[i], size:results.sizes[i], type:results.types[i], mtime:results.mtimes[i], mimeType:results["mime-types"][i]}); + this.setState({ + rawFiles:files, + browserUpdating:false + }); + }, + error : (results:any) => + { + if(this.state.path != this.state.pathInput) + { + this.setState({pathError:true, browserUpdating:false}); + } + if(results.status == 400){ + alert("bad file path") + } + this.setState({browseError:true, browserUpdating:false}); + } + }); + } + // Otherwise...we don't have a session anymore, so + // run the reauth callback if one was passed. + else { + if(this.props.onReauthCallBack) { + this.props.onReauthCallBack(); + } + } + }); + } + + /** + * takes a path and returns the directory above it + * + * @param path string path + * @private + * @returns new string path one level up + * @memberof RemoteFileBrowser + */ + private pathDirname = (path:string):string => + { + var new_path = path.replace(/\/\.?(\w|\-|\.)*\/?$/, ""); + if(new_path == "") + new_path = "/"; + return new_path; + } + + /** + * takes left path and right path and joins them + * @param right string path + * @param left string path + * @private + * @requires joined paths + * @memberof RemoteFileBrowser + */ + private pathJoin = (left:string, right:string):string => + { + var new_path = left; + if(new_path.slice(-1) != "/") + new_path += "/"; + new_path += right; + return new_path; + } + + /** + * given a file(which includes its full path), browse to the path above it + * + * @param file meta data for the file selected to browse up + * one level from said path + * @private + * @memberof RemoteFileBrowser + */ + private browseUpByFile = (file:FileMetaData) => { + this.setState({selected:-1}); + // If the file is our parent directory, move up the hierarchy. + if(file.name === "..") + { + this.browse(this.pathDirname(this.state.path)); + } + // If the file is a directory, move down the hierarchy. + else if(file.type === "d") + { + this.browse(this.pathJoin(this.state.path, file.name)); + } + } + + keyPress = (event:any, pathInput:string) => { + if (event.key == 'Enter'){ + // How would I trigger the button that is in the render? I have this so far. + this.browse(pathInput); + } + } + + + /** + * Given a row id and file info set the selected file and + * callBack to tell caller Path, file.type, file:FileMetaData + * + * @param file an object of FileMetaData + * @param i index of selected row in the table + * @private + * @memberof RemoteFileBrowser + */ + private selectRow = (file:FileMetaData, i:number) => { + let newPath:string = this.state.path; + const path_split:string[] = this.state.path.split("/"); + + /** + * If the user types out the full path, including file name, + * we don't want to join the file name with the path + * (resulting in duplicate file names). + */ + + if(path_split[path_split.length - 1] !== file.name) { + newPath = this.pathJoin(this.state.path, file.name); + } + + this.setState({selected:i},() => { + // tell our create what we selected + this.props.onSelectFileCallBack(newPath, file.type, file); + }) + } + + /** + * takes a list of file info from the state and converts it + * to an html + * + * @private + * @memberof RemoteFileBrowser + * @returns JSX.Element[] with the styled file list + */ + private getFilesAsJsx = ():JSX.Element[] => { + const rawFilesJSX = this.state.rawFiles.map((rawFile, i) => { + return ( + this.selectRow(rawFile,i)} + onDoubleClick={()=> this.browseUpByFile(rawFile)}> + + {rawFile.mimeType === "application/x-directory"? + : + } + + {rawFile.name} + {rawFile.size} + {rawFile.mtime} + + ) + }) + return rawFilesJSX; + // if(file.mime_type() in component.icon_map) + // { + // icon = component.icon_map[file.mime_type()]; + // } + // else if(_.startsWith(file.mime_type(), "text/")) + // { + // icon = ""; + // } + // else if(_.startsWith(file.mime_type(), "image/")) + // { + // icon = ""; + // } + // else if(_.startsWith(file.mime_type(), "video/")) + // { + // icon = ""; + // } + } + + public async componentDidMount() { + const path = localStorage.getItem("slycat-remote-browser-path-" + + this.state.persistenceId + + this.props.hostname); + if(path != null){ + this.setState({path,pathInput:path}); + await this.browse(this.pathDirname(path)); + } + } + + public render() { + const options: Option[] = [{ + text:'Comma separated values (CSV)', + value:'slycat-csv-parser' + }, + { + text:'Dakota tabular', + value:'slycat-dakota-parser' + }]; + const pathStyle:any = { + width: 'calc(100% - 44px)', + float: 'left', + marginRight: '5px' + } + const styleTable:any = { + position: "relative", + height: (window.innerHeight*0.4)+"px", + overflow: "auto", + display: "block", + border: "1px solid rgb(222, 226, 230)", + } + return ( +
+ +
+
+
+ this.keyPress(event, this.state.pathInput)} + onChange={(e:React.ChangeEvent) => { + this.setState({pathInput:e.target.value}) + } + } + /> +
+ +
+
+
+ +
+
+ {/*
+ Oops, that path is not accessible. Please try again. +
*/} +
+ + {!this.state.browserUpdating? +
+ + + + + + + + + + + {this.getFilesAsJsx()} + +
NameSizeDate Modified
+
: + } + +
+ ); + } +} \ No newline at end of file diff --git a/web-server/plugins/slycat-smb/ui.js b/web-server/plugins/slycat-smb/ui.js index 44e3b750d..1ad415b59 100644 --- a/web-server/plugins/slycat-smb/ui.js +++ b/web-server/plugins/slycat-smb/ui.js @@ -1,8 +1,7 @@ import React from "react"; import ReactDOM from "react-dom"; -import RemoteFileBrowser from 'components/RemoteFileBrowser.tsx' +import SmbRemoteFileBrowser from 'components/SmbRemoteFileBrowser.tsx' import ModalContent from "components/ModalContent.tsx"; -import ModalMedium from "components/ModalMedium.tsx"; import client from "js/slycat-web-client"; let userName = ""; @@ -17,6 +16,7 @@ const b64EncodeUnicode = (str) => { let encodedUserName = b64EncodeUnicode(userName); let encodedPassword = b64EncodeUnicode(password); +alert("Authenticating"); client.post_remotes_smb_fetch({ user_name:encodedUserName, password:encodedPassword, @@ -27,11 +27,11 @@ client.post_remotes_smb_fetch({ }); const onSelectTableFile = () => { - console.log("onSelecTableFile"); + alert("onSelecTableFile"); } const onReauth = () => { - console.log("onReauth"); + alert("onReauth"); } const cleanup = () => { @@ -52,7 +52,7 @@ const getBodyJsx = () => { return (
SMB Wizard - Date: Thu, 3 Jun 2021 14:05:04 -0600 Subject: [PATCH 10/28] Update handlers.py --- packages/slycat/web/server/handlers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/slycat/web/server/handlers.py b/packages/slycat/web/server/handlers.py index 3e47575e8..400dd16a3 100644 --- a/packages/slycat/web/server/handlers.py +++ b/packages/slycat/web/server/handlers.py @@ -2548,10 +2548,10 @@ def get_remotes(hostname): session = database.get("session", cherrypy.request.cookie["slycatauth"].value) for h_session in session["sessions"]: if h_session["hostname"] == hostname: - if h_session["session_type"] == "ssh" and not slycat.web.server.remote.check_session(sid): + if h_session["session_type"] == "ssh" and slycat.web.server.remote.check_session(h_session["sid"]): status = True msg = "hostname session was found" - elif h_session["session_type"] == "smb" and not slycat.web.server.smb.check_session(sid): + elif h_session["session_type"] == "smb" and slycat.web.server.smb.check_session(h_session["sid"]): status = True msg = "hostname session was found" else: From 28beb3abb2f60339374a39d3a1aaeb3ff26cb7a1 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 4 Jun 2021 13:19:19 -0600 Subject: [PATCH 11/28] added smb stub for param space --- web-server/components/SmbRemoteFileBrowser.tsx | 5 ++++- .../slycat-parameter-image/js/wizard-ui.js | 9 +++++++++ .../slycat-parameter-image/wizard-ui.html | 17 +++++++++++++---- web-server/plugins/slycat-smb/ui.js | 4 ++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/web-server/components/SmbRemoteFileBrowser.tsx b/web-server/components/SmbRemoteFileBrowser.tsx index 7e6b44cf0..c22947a8f 100644 --- a/web-server/components/SmbRemoteFileBrowser.tsx +++ b/web-server/components/SmbRemoteFileBrowser.tsx @@ -254,8 +254,11 @@ export default class SmbRemoteFileBrowser extends React.Component { const rawFilesJSX = this.state.rawFiles.map((rawFile, i) => { + if (!rawFile.mtime){ + return null + } return ( - this.selectRow(rawFile,i)} diff --git a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js index 683bbf44e..78343d013 100644 --- a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js +++ b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js @@ -15,6 +15,9 @@ import { remoteControlsReauth } from "js/slycat-remote-controls"; import "js/slycat-remote-browser"; import "js/slycat-table-ingestion"; import parameterImageWizardUI from "../wizard-ui.html"; +import React from "react"; +import ReactDOM from "react-dom"; +import SmbRemoteFileBrowser from 'components/SmbRemoteFileBrowser.tsx' function constructor(params) { @@ -190,6 +193,12 @@ function constructor(params) component.existing_table(); } else if (type === "remote") { component.tab(2); + } else if (type === "smb") { + component.tab(2); + ReactDOM.render( +
JSX RENDER
, + document.querySelector(".smb-wizard") + ); } }; diff --git a/web-server/plugins/slycat-parameter-image/wizard-ui.html b/web-server/plugins/slycat-parameter-image/wizard-ui.html index 5f1b6014d..bdb551237 100644 --- a/web-server/plugins/slycat-parameter-image/wizard-ui.html +++ b/web-server/plugins/slycat-parameter-image/wizard-ui.html @@ -10,8 +10,8 @@ @@ -34,6 +34,13 @@
+
+ +
+
+ this.onValueChange(e.target.value, "hostname")} /> +
+
+
+ {this.getFormInputsJSX()} + + ); + } +} diff --git a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js index 78343d013..23dfb9f50 100644 --- a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js +++ b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js @@ -18,6 +18,8 @@ import parameterImageWizardUI from "../wizard-ui.html"; import React from "react"; import ReactDOM from "react-dom"; import SmbRemoteFileBrowser from 'components/SmbRemoteFileBrowser.tsx' +import SmbAuthentication from 'components/SmbAuthentication.tsx'; + function constructor(params) { @@ -184,6 +186,18 @@ function constructor(params) } }; + var onSelectTableFile = function() { + console.log("onSelectTableFile"); + }; + + var onReauth = function() { + console.log("onReauth"); + }; + + const smbAuth = function(hostname, username, password, sessionExists) { + console.log("Auth yo."); + } + component.select_type = function() { var type = component.ps_type(); @@ -196,7 +210,21 @@ function constructor(params) } else if (type === "smb") { component.tab(2); ReactDOM.render( -
JSX RENDER
, +
+ +
, + //
+ // + + //
, document.querySelector(".smb-wizard") ); } From c14d931762ccccebc8afc4d61cde737c006f35f7 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Thu, 17 Jun 2021 17:36:41 -0600 Subject: [PATCH 13/28] adding share name to input list --- web-server/components/SmbAuthentication.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/web-server/components/SmbAuthentication.tsx b/web-server/components/SmbAuthentication.tsx index 020abc518..902131953 100644 --- a/web-server/components/SmbAuthentication.tsx +++ b/web-server/components/SmbAuthentication.tsx @@ -1,11 +1,11 @@ -import React, {Component} from 'react'; +import React from 'react'; import client from "js/slycat-web-client"; import ConnectButton from 'components/ConnectButton.tsx'; /** * this class sets up and tests a remote session to an agent */ -export default class SmbAuthentication extends Component { +export default class SmbAuthentication extends React.Component { /** *Creates an instance of SlycatRemoteControls. @@ -85,8 +85,8 @@ export default class SmbAuthentication extends Component { * * @memberof SmbAuthentication */ - populateDisplay = () => { - const display = {}; + populateDisplay = ():any => { + const display:any = {}; if(localStorage.getItem("slycat-remote-controls-hostname")){ display.hostname = localStorage.getItem("slycat-remote-controls-hostname") ? localStorage.getItem("slycat-remote-controls-hostname"):null; @@ -166,6 +166,15 @@ export default class SmbAuthentication extends Component { if(!this.state.session_exists){ return (
+
+ +
+ this.onValueChange(e.target.value, "share")} /> +
+
From c3650965c35d0fa3676d92dcc346f20059f96fdf Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 18 Jun 2021 09:44:23 -0600 Subject: [PATCH 14/28] Update SmbAuthentication.tsx --- web-server/components/SmbAuthentication.tsx | 126 ++++++++++---------- 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/web-server/components/SmbAuthentication.tsx b/web-server/components/SmbAuthentication.tsx index 902131953..439a35570 100644 --- a/web-server/components/SmbAuthentication.tsx +++ b/web-server/components/SmbAuthentication.tsx @@ -1,6 +1,5 @@ import React from 'react'; import client from "js/slycat-web-client"; -import ConnectButton from 'components/ConnectButton.tsx'; /** * this class sets up and tests a remote session to an agent @@ -27,6 +26,7 @@ export default class SmbAuthentication extends React.Component { username: display.username?display.username:null, session_exists: null, password: "", + share: display.share?display.share:null, hostnames : [], loadingData: this.props.loadingData, initialLoad: false @@ -52,16 +52,6 @@ export default class SmbAuthentication extends React.Component { }); }; - connectButtonCallBack = (sessionExists, loadingData) => { - this.setState({ - session_exists:sessionExists, - loadingData:loadingData - }, () => { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.session_exists); - }); - } - /** * gets a list of all the known remote hosts that we can connect to * via ssh @@ -87,13 +77,17 @@ export default class SmbAuthentication extends React.Component { */ populateDisplay = ():any => { const display:any = {}; - if(localStorage.getItem("slycat-remote-controls-hostname")){ - display.hostname = localStorage.getItem("slycat-remote-controls-hostname") ? - localStorage.getItem("slycat-remote-controls-hostname"):null; + if(localStorage.getItem("slycat-smb-remote-controls-hostname")){ + display.hostname = localStorage.getItem("slycat-smb-remote-controls-hostname") ? + localStorage.getItem("slycat-smb-remote-controls-hostname"):null; } - if(localStorage.getItem("slycat-remote-controls-username")){ - display.username = localStorage.getItem("slycat-remote-controls-username") ? - localStorage.getItem("slycat-remote-controls-username"):null; + if(localStorage.getItem("slycat-smb-remote-controls-username")){ + display.username = localStorage.getItem("slycat-smb-remote-controls-username") ? + localStorage.getItem("slycat-smb-remote-controls-username"):null; + } + if(localStorage.getItem("slycat-smb-remote-controls-share")){ + display.share = localStorage.getItem("slycat-smb-remote-controls-share") ? + localStorage.getItem("slycat-smb-remote-controls-share"):null; } return display; }; @@ -106,19 +100,32 @@ export default class SmbAuthentication extends React.Component { */ onValueChange = (value, type) => { switch(type) { + case "share": + localStorage.setItem("slycat-smb-remote-controls-share", value); + this.setState({share: value},() => { + this.props.callBack(this.state.hostname, this.state.username, + this.state.password, this.state.share, this.state.session_exists); + }); + break; case "username": - localStorage.setItem("slycat-remote-controls-username", value); - this.setState({username: value}); + localStorage.setItem("slycat-smb-remote-controls-username", value); + this.setState({username: value},() => { + this.props.callBack(this.state.hostname, this.state.username, + this.state.password, this.state.share, this.state.session_exists); + }); break; case "hostname": - localStorage.setItem("slycat-remote-controls-hostname", value); + localStorage.setItem("slycat-smb-remote-controls-hostname", value); this.checkRemoteStatus(value); - this.setState({hostname: value}); + this.setState({hostname: value},() => { + this.props.callBack(this.state.hostname, this.state.username, + this.state.password, this.state.share, this.state.session_exists); + }); break; case "password": this.setState({password: value},() => { this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.session_exists); + this.state.password, this.state.share, this.state.session_exists); }); break; default: @@ -153,7 +160,8 @@ export default class SmbAuthentication extends React.Component { */ handleKeyDown = (e) => { if (this.state.showConnectButton && e.key === 'Enter') { - this.connect(); + this.props.callBack(this.state.hostname, this.state.username, + this.state.password, this.state.share, this.state.session_exists); } } @@ -163,51 +171,37 @@ export default class SmbAuthentication extends React.Component { * @memberof SmbAuthentication */ getFormInputsJSX = () => { - if(!this.state.session_exists){ - return ( -
-
- -
- this.onValueChange(e.target.value, "share")} /> -
+ return ( +
+
+ +
+ this.onValueChange(e.target.value, "share")} />
-
- -
- this.onValueChange(e.target.value, "username")} /> -
+
+
+ +
+ this.onValueChange(e.target.value, "username")} />
-
- -
- this.onValueChange(e.target.value, "password")} /> -
- {this.state.showConnectButton? -
- -
:null - } +
+
+ +
+ this.onValueChange(e.target.value, "password")} />
- ); - } - return null; +
+ ); } /** @@ -219,7 +213,7 @@ export default class SmbAuthentication extends React.Component { const hostnamesJSX = this.state.hostnames.map((hostnameObject, i) => { return (
  • - this.onValueChange(e.target.text, "hostname")}> + this.onValueChange(e.target.text, "hostname")}> {hostnameObject.hostname}
  • @@ -258,7 +252,7 @@ export default class SmbAuthentication extends React.Component {
    - {this.getFormInputsJSX()} + {!this.state.session_exists&&this.getFormInputsJSX()} ); } From 3256cf5d998ddfdbdde27382c0901f2d343e1874 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Fri, 18 Jun 2021 12:30:13 -0600 Subject: [PATCH 15/28] added login and browse --- packages/slycat/web/server/__init__.py | 8 +- web-server/components/SmbAuthentication.tsx | 38 +++++---- web-server/js/slycat-web-client.js | 14 +-- .../slycat-parameter-image/js/wizard-ui.js | 85 ++++++++++++++++--- .../slycat-parameter-image/wizard-ui.html | 7 +- 5 files changed, 100 insertions(+), 52 deletions(-) diff --git a/packages/slycat/web/server/__init__.py b/packages/slycat/web/server/__init__.py index 387d2fa53..1169880dd 100644 --- a/packages/slycat/web/server/__init__.py +++ b/packages/slycat/web/server/__init__.py @@ -724,14 +724,8 @@ def decode_username_and_password(): # cherrypy.log.error("decoding username and password") user_name = str(base64_decode(cherrypy.request.json["user_name"]).decode()) password = str(base64_decode(cherrypy.request.json["password"]).decode()) - - # try and get the redirect path for after successful login - try: - location = cherrypy.request.json["location"] - except Exception as e: - location = None - # cherrypy.log.error("no location provided moving on") except Exception as e: + cherrypy.log.error(str(e)) # cherrypy.log.error("username and password could not be decoded") cherrypy.log.error("slycat-standard-authentication.py authenticate", "cherrypy.HTTPError 400") raise cherrypy.HTTPError(400) diff --git a/web-server/components/SmbAuthentication.tsx b/web-server/components/SmbAuthentication.tsx index 439a35570..3dd06e68b 100644 --- a/web-server/components/SmbAuthentication.tsx +++ b/web-server/components/SmbAuthentication.tsx @@ -21,7 +21,6 @@ export default class SmbAuthentication extends React.Component { const display = this.populateDisplay(); this.state = { remote_hosts: [], - showConnectButton: this.props.showConnectButton?this.props.showConnectButton:false, hostname: display.hostname?display.hostname:null, username: display.username?display.username:null, session_exists: null, @@ -46,12 +45,21 @@ export default class SmbAuthentication extends React.Component { initialLoad:true, loadingData:false }, () => { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.session_exists); + this.props.callBack(this.state.hostname, this.b64EncodeUnicode(this.state.username), + this.b64EncodeUnicode(this.state.password), this.state.share, this.state.session_exists); }); }); }; - + /** + * takes a string value and encodes it to b64 + * @param str string to be encode + * @returns encoded result + */ + b64EncodeUnicode = (str) => { + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { + return String.fromCharCode('0x' + p1); + })); +}; /** * gets a list of all the known remote hosts that we can connect to * via ssh @@ -103,29 +111,29 @@ export default class SmbAuthentication extends React.Component { case "share": localStorage.setItem("slycat-smb-remote-controls-share", value); this.setState({share: value},() => { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.share, this.state.session_exists); + this.props.callBack(this.state.hostname, this.b64EncodeUnicode(this.state.username), + this.b64EncodeUnicode(this.state.password), this.state.share, this.state.session_exists); }); break; case "username": localStorage.setItem("slycat-smb-remote-controls-username", value); this.setState({username: value},() => { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.share, this.state.session_exists); + this.props.callBack(this.state.hostname, this.b64EncodeUnicode(this.state.username), + this.b64EncodeUnicode(this.state.password), this.state.share, this.state.session_exists); }); break; case "hostname": localStorage.setItem("slycat-smb-remote-controls-hostname", value); this.checkRemoteStatus(value); this.setState({hostname: value},() => { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.share, this.state.session_exists); + this.props.callBack(this.state.hostname, this.b64EncodeUnicode(this.state.username), + this.b64EncodeUnicode(this.state.password), this.state.share, this.state.session_exists); }); break; case "password": this.setState({password: value},() => { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.share, this.state.session_exists); + this.props.callBack(this.state.hostname, this.b64EncodeUnicode(this.state.username), + this.b64EncodeUnicode(this.state.password), this.state.share, this.state.session_exists); }); break; default: @@ -159,9 +167,9 @@ export default class SmbAuthentication extends React.Component { * @memberof SmbAuthentication */ handleKeyDown = (e) => { - if (this.state.showConnectButton && e.key === 'Enter') { - this.props.callBack(this.state.hostname, this.state.username, - this.state.password, this.state.share, this.state.session_exists); + if (e.key === 'Enter') { + this.props.callBack(this.state.hostname, this.b64EncodeUnicode(this.state.username), + this.b64EncodeUnicode(this.state.password), this.state.share, this.state.session_exists); } } diff --git a/web-server/js/slycat-web-client.js b/web-server/js/slycat-web-client.js index 58377ffd6..90e60894f 100644 --- a/web-server/js/slycat-web-client.js +++ b/web-server/js/slycat-web-client.js @@ -756,7 +756,7 @@ module.post_sensitive_model_command = function(params) { }); }; -module.post_remotes_smb_fetch = function(params, successFunction, errorFunction) +module.post_remotes_smb_fetch = function(params) { return fetch(`${api_root}remotes/smb`, { @@ -769,18 +769,6 @@ module.post_remotes_smb_fetch = function(params, successFunction, errorFunction) }, body: JSON.stringify(params || {}) }) - .then(function(response) { - if (!response.ok) { - throw `bad response with: ${response.status} :: ${response.statusText}`; - } - return response.json(); - }).catch((error) => { - if (errorFunction) { - errorFunction(error) - }else{ - console.log(error); - } - }); }; module.post_sensitive_model_command_fetch = function(params, successFunction, errorFunction) diff --git a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js index 23dfb9f50..72e77cfcb 100644 --- a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js +++ b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js @@ -37,7 +37,8 @@ function constructor(params) component.remote = mapping.fromJS({ hostname: null, username: null, - password: null, + password: null, + share: null, status: null, status_type: null, enable: true, @@ -194,8 +195,12 @@ function constructor(params) console.log("onReauth"); }; - const smbAuth = function(hostname, username, password, sessionExists) { - console.log("Auth yo."); + const setSmbAuthValues = function(hostname, username, password, share, session_exists) { + component.remote.hostname(hostname) + component.remote.username(username) + component.remote.password(password) + component.remote.share(share) + component.remote.session_exists(session_exists) } component.select_type = function() { @@ -213,19 +218,10 @@ function constructor(params)
    , - //
    - // - - //
    , - document.querySelector(".smb-wizard") + document.querySelector(".smb-wizard-login") ); } }; @@ -302,7 +298,68 @@ function constructor(params) }; fileUploader.uploadFile(fileObject); }; + component.connectSMB = function() { + component.remote.enable(false); + component.remote.status_type("info"); + component.remote.status("Connecting ..."); + if(component.remote.session_exists()) + { + ReactDOM.render( +
    + +
    , + document.querySelector(".smb-wizard-browse") + ); + component.tab(3); + component.remote.enable(true); + component.remote.status_type(null); + component.remote.status(null); + } + else + { + client.post_remotes_smb_fetch({ + user_name: component.remote.username(), + password: component.remote.password(), + server: component.remote.hostname(), + share: component.remote.share() + }).then((response) => { + console.log("authenticated.",response); + if(response.ok){ + component.remote.session_exists(true); + component.remote.enable(true); + component.remote.status_type(null); + component.remote.status(null); + component.tab(3); + ReactDOM.render( +
    + +
    , + document.querySelector(".smb-wizard-browse") + ); + + }else{ + component.remote.enable(true); + component.remote.status_type("danger"); + component.remote.focus("password"); + } + }).catch((error)=>{ + console.log("could not connect",error) + component.remote.enable(true); + component.remote.status_type("danger"); + component.remote.status(reason_phrase); + component.remote.focus("password"); + }); + } + }; component.connect = function() { component.remote.enable(false); component.remote.status_type("info"); diff --git a/web-server/plugins/slycat-parameter-image/wizard-ui.html b/web-server/plugins/slycat-parameter-image/wizard-ui.html index bdb551237..e8c46d8ad 100644 --- a/web-server/plugins/slycat-parameter-image/wizard-ui.html +++ b/web-server/plugins/slycat-parameter-image/wizard-ui.html @@ -88,12 +88,13 @@ activate:connect, session_exists:remote.session_exists "> -
    SMB
    +
    -
    +
    SMB
    +
    New Parameter Space Model - + - + +
    , document.querySelector(".smb-login") From aeed4d4035acd538c19730afea22fb7a33195ce1 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Thu, 5 Aug 2021 15:32:09 -0600 Subject: [PATCH 24/28] fixing back button --- web-server/components/SmbAuthentication.tsx | 8 ++++++-- web-server/plugins/slycat-parameter-image/js/wizard-ui.js | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/web-server/components/SmbAuthentication.tsx b/web-server/components/SmbAuthentication.tsx index b469d7fc1..6a765c475 100644 --- a/web-server/components/SmbAuthentication.tsx +++ b/web-server/components/SmbAuthentication.tsx @@ -6,7 +6,6 @@ import { displayPartsToString } from 'typescript'; * this class sets up and tests a remote session to an agent */ export default class SmbAuthentication extends React.Component { - /** *Creates an instance of SlycatRemoteControls. * @param {callBack, ConnectButton} props, @@ -33,7 +32,7 @@ export default class SmbAuthentication extends React.Component { smb_info: this.props.smb_info }; } - + private poll; /** * function used to test if we have an ssh connection to the hostname * @param {hostname} @@ -78,6 +77,10 @@ export default class SmbAuthentication extends React.Component { async componentDidMount(){ await this.checkRemoteStatus(this.state.hostname); await this.getRemoteHosts(); + this.poll = setInterval( + async () => await this.checkRemoteStatus(this.state.hostname), + 3000 + ); } /** @@ -156,6 +159,7 @@ export default class SmbAuthentication extends React.Component { */ componentWillUnmount() { const display = this.populateDisplay(); + clearInterval(this.poll); const state = { remote_hosts: [], enable: true, diff --git a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js index 295a9404a..e7b22b839 100644 --- a/web-server/plugins/slycat-parameter-image/js/wizard-ui.js +++ b/web-server/plugins/slycat-parameter-image/js/wizard-ui.js @@ -173,7 +173,7 @@ function constructor(params) // Get list of model ids project data is used in client.get_project_data_parameter_fetch({ did: did, param: "mid"}).then((models) => { // if there are no more models using that project data, delete it - if(models.length === 0) { + if(models && models.length === 0) { client.delete_project_data_fetch({ did: did }); } }); @@ -610,7 +610,7 @@ function constructor(params) // Get the list of models using that project data client.get_project_data_parameter_fetch({did: did, param: "mid"}).then((models) => { // if there are no more models using that project data, delete it - if(models.length === 0) { + if(models && models.length === 0) { client.delete_project_data_fetch({did: did}); } }); From c791b91fcde3f60e617c6d4714090eb0c53c7575 Mon Sep 17 00:00:00 2001 From: Matthew Letter Date: Thu, 19 Aug 2021 11:46:50 -0600 Subject: [PATCH 25/28] fixed not loading on first hover smb --- web-server/js/slycat-remotes.js | 5 ++--- .../js/parameter-image-scatterplot.js | 9 +++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/web-server/js/slycat-remotes.js b/web-server/js/slycat-remotes.js index 2d85581f6..890460b4f 100644 --- a/web-server/js/slycat-remotes.js +++ b/web-server/js/slycat-remotes.js @@ -58,10 +58,9 @@ export function login(params) server: params.hostname, share: component.remote.share() }).then((response) => { - console.log("authenticated.",response); if(response.ok){ component.container.children().modal("hide"); - params.success(response.data.sid); + params.success(response.status); } else { component.remote.enable(true); component.remote.status_type("danger"); @@ -161,7 +160,7 @@ export function create_pool() collab_name: params.collab_name, title: params.title, message: params.message, - success: function(sid) + success: function(status) { if(params.success) params.success(params.hostname); diff --git a/web-server/plugins/slycat-parameter-image/js/parameter-image-scatterplot.js b/web-server/plugins/slycat-parameter-image/js/parameter-image-scatterplot.js index b1b685928..f77c5b942 100644 --- a/web-server/plugins/slycat-parameter-image/js/parameter-image-scatterplot.js +++ b/web-server/plugins/slycat-parameter-image/js/parameter-image-scatterplot.js @@ -2746,8 +2746,6 @@ $.widget("parameter_image.scatterplot", } // If we don't have a session for the image hostname, create one. - var cached_uri = URI(api_root + "projects/" + self.options.model.project + "/cache/" + URI.encode(uri.host() + uri.path())) - console.log("Attempting to load image from server-side cache..."); console.log("Loading image " + image.uri + " from server..."); @@ -2758,7 +2756,7 @@ $.widget("parameter_image.scatterplot", } xhr.image = image; - xhr.open("GET", api_root + "projects/" + self.options.model.project + "/cache/" + URI.encode(uri.host() + uri.path()), true); + xhr.open("GET", api_root + "remotes/" + uri.hostname() + api + uri.pathname() + "?cache=project&project=" + self.options.model.project + "&key=" + URI.encode(URI.encode(uri.host() + uri.path())), true); xhr.responseType = "arraybuffer"; //Split path to get collab name. Assume collab name is the first thing in path. @@ -2767,10 +2765,9 @@ $.widget("parameter_image.scatterplot", xhr.onload = function(e){ //If the image isn't in cache, open an agent session: - if (this.status == 404) { + if (this.status == 404 || this.status == 400) { if(!self.login_open) { - // TODO add SMB check here self.login_open = true; self.remotes.get_remote({ smb: uri.protocol() == "smb", @@ -2834,7 +2831,7 @@ $.widget("parameter_image.scatterplot", xhr.image = image; //Double encode to avoid cherrypy's auto unencode in the controller - xhr.open("GET", api_root + "remotes/" + hostname + api + uri.pathname() + "?cache=project&project=" + self.options.model.project + "&key=" + URI.encode(URI.encode(uri.host() + uri.path())), true); + xhr.open("GET", api_root + "remotes/" + uri.hostname() + api + uri.pathname() + "?cache=project&project=" + self.options.model.project + "&key=" + URI.encode(URI.encode(uri.host() + uri.path())), true); xhr.responseType = "arraybuffer"; xhr.onload = function(e) { // If we get 404, the remote session no longer exists because it timed-out. From d7a2aa234eb4e3ec3c52e635c80a7684a8ffac40 Mon Sep 17 00:00:00 2001 From: Spurs20 <22457841+Spurs20@users.noreply.github.com> Date: Thu, 19 Aug 2021 12:25:03 -0600 Subject: [PATCH 26/28] Updating smb connection --- packages/slycat/web/server/smb.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py index a374f34e3..1d425290b 100644 --- a/packages/slycat/web/server/smb.py +++ b/packages/slycat/web/server/smb.py @@ -54,8 +54,9 @@ def connect(self): self.client, self.server, is_direct_tcp=True) self.connected = self.conn.connect(self.server_ip, self.port) + connected = True cherrypy.log.error('Connected to %s smb server' % self.server) - return self.connected + return connected, self.connected except Exception as e: cherrypy.log.error('Connect failed. Reason: %s', e) return False @@ -158,7 +159,8 @@ def create_session(username, password, server, share): with session_cache_lock: cherrypy.log.error("create the seesion and add it to the session_cache") session_cache[smb_id] = Smb(username, password, server, share) - if session_cache[smb_id].connect(): + is_connected, connected = session_cache[smb_id].connect() + if is_connected: return smb_id raise cherrypy.HTTPError("401 Remote smb connection failed: could not connect to smb drive") except Exception as e: From 7604f2048b732ba4e21d6ec0811b2b779f693817 Mon Sep 17 00:00:00 2001 From: Spurs20 <22457841+Spurs20@users.noreply.github.com> Date: Tue, 31 Aug 2021 10:27:43 -0600 Subject: [PATCH 27/28] Fixing smb bug --- packages/slycat/web/server/smb.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/slycat/web/server/smb.py b/packages/slycat/web/server/smb.py index 1d425290b..f51014e29 100644 --- a/packages/slycat/web/server/smb.py +++ b/packages/slycat/web/server/smb.py @@ -56,7 +56,7 @@ def connect(self): self.connected = self.conn.connect(self.server_ip, self.port) connected = True cherrypy.log.error('Connected to %s smb server' % self.server) - return connected, self.connected + return self.connected except Exception as e: cherrypy.log.error('Connect failed. Reason: %s', e) return False @@ -159,8 +159,7 @@ def create_session(username, password, server, share): with session_cache_lock: cherrypy.log.error("create the seesion and add it to the session_cache") session_cache[smb_id] = Smb(username, password, server, share) - is_connected, connected = session_cache[smb_id].connect() - if is_connected: + if session_cache[smb_id].connect(): return smb_id raise cherrypy.HTTPError("401 Remote smb connection failed: could not connect to smb drive") except Exception as e: From 40c183f0f770bd46f7950511af9b1dd52f72cef6 Mon Sep 17 00:00:00 2001 From: Spurs20 <22457841+Spurs20@users.noreply.github.com> Date: Thu, 2 Sep 2021 13:50:17 -0600 Subject: [PATCH 28/28] Adding error handling to smb authentication --- web-server/plugins/slycat-parameter-image/wizard-ui.html | 6 ++++-- web-server/templates/slycat-remote-login.html | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/web-server/plugins/slycat-parameter-image/wizard-ui.html b/web-server/plugins/slycat-parameter-image/wizard-ui.html index bb456c649..39cd0303a 100644 --- a/web-server/plugins/slycat-parameter-image/wizard-ui.html +++ b/web-server/plugins/slycat-parameter-image/wizard-ui.html @@ -89,6 +89,8 @@ session_exists:remote.session_exists "> +
    @@ -136,9 +138,9 @@ - + - +