def check_user_shortcuts(toyz_settings, user_id, shortcuts=None): """ Check that a user has all of the default shortcuts. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): Toyz Settings - user_id (*string* ): User id to check for shortcuts - shortcuts (*dict*, optional): Dictionary of shortcuts for a user. Shortcuts are always of the form ``shortcut_name:path`` . Returns - shortcuts: dictionary of shortcuts for the user """ modified = False if shortcuts == None: shortcuts = db_utils.get_param(toyz_settings.db, 'shortcuts', user_id=user_id) if 'user' not in shortcuts: shortcuts['user'] = os.path.join(toyz_settings.config.root_path, 'users', user_id) db_utils.update_param(toyz_settings.db, 'shortcuts', user_id=user_id, shortcuts={'user': shortcuts['user']}) create_paths([shortcuts['user']]) modified = True if 'temp' not in shortcuts: shortcuts['temp'] = os.path.join(shortcuts['user'], 'temp') db_utils.update_param(toyz_settings.db, 'shortcuts', user_id=user_id, shortcuts={'temp': shortcuts['temp']}) create_paths([shortcuts['temp']]) modified = True if modified: db_utils.update_param(toyz_settings.db, 'shortcuts', user_id=user_id, shortcuts=shortcuts) paths = db_utils.get_param(toyz_settings.db, 'paths', user_id=user_id) # Ensure that the user has full access to his/her home directory if shortcuts['user'] not in paths or paths[ shortcuts['user']] != 'frwx': db_utils.update_param(toyz_settings.db, 'paths', user_id=user_id, paths={shortcuts['user']: '******'}) return shortcuts
def save_workspace(toyz_settings, tid, params): """ Save a workspace for later use """ core.check4keys(params, ['workspaces', 'overwrite']) workspaces = db_utils.get_param(toyz_settings.db, 'workspaces', user_id=tid['user_id']) work_id = params['workspaces'].keys()[0] if work_id in workspaces and params['overwrite'] is False: response = { 'id': 'verify', 'func': 'save_workspace' } else: user_id = tid['user_id'] if 'user_id' in params and params['user_id']!=tid['user_id']: params['work_id'] = work_id permissions = core.get_workspace_permissions(toyz_settings, tid, params) if permissions['modify']: user_id = params['user_id'] else: raise ToyzJobError( "You do not have permission to save {0}".format(params['work_id'])) db_utils.update_param(toyz_settings.db, 'workspaces', workspaces=params['workspaces'], user_id=user_id) response = { 'id': 'notification', 'msg': 'Workspace saved successfully', 'func': 'save_workspace' } return response
def save_workspace(toyz_settings, tid, params): """ Save a workspace for later use """ core.check4keys(params, ['workspaces', 'overwrite']) workspaces = db_utils.get_param(toyz_settings.db, 'workspaces', user_id=tid['user_id']) work_id = params['workspaces'].keys()[0] if work_id in workspaces and params['overwrite'] is False: response = {'id': 'verify', 'func': 'save_workspace'} else: user_id = tid['user_id'] if 'user_id' in params and params['user_id'] != tid['user_id']: params['work_id'] = work_id permissions = core.get_workspace_permissions( toyz_settings, tid, params) if permissions['modify']: user_id = params['user_id'] else: raise ToyzJobError( "You do not have permission to save {0}".format( params['work_id'])) db_utils.update_param(toyz_settings.db, 'workspaces', workspaces=params['workspaces'], user_id=user_id) response = { 'id': 'notification', 'msg': 'Workspace saved successfully', 'func': 'save_workspace' } return response
def get_img_info(toyz_settings, tid, params): """ Map a large image into a set of tiles that make up the larger image """ import toyz.web.viewer as viewer print('************************************************') core.check4keys(params, ['img_info', 'file_info']) if tid['user_id']!='admin': permissions = file_access.get_parent_permissions( toyz_settings.db, params['file_info']['filepath'], user_id=tid['user_id']) if 'r' not in permissions: raise ToyzJobError( 'You do not have permission to view the requested file.' 'Please contact your network administrator if you believe this is an error.') shortcuts = db_utils.get_param(toyz_settings.db, 'shortcuts', user_id=tid['user_id']) save_path = os.path.join(shortcuts['temp'], tid['session_id'], 'images') params['img_info']['save_path'] = save_path img_info = viewer.get_img_info(params['file_info'], params['img_info']) result = get_tile_info(toyz_settings, tid, { 'file_info': params['file_info'], 'img_info': img_info }) img_info['tiles'] = result['new_tiles'] response = { 'id': 'img info', 'img_info': img_info, 'new_tiles': result['new_tiles'] } print('************************************************') return response
def load_workspace(toyz_settings, tid, params): """ Load a workspace """ core.check4keys(params, ['work_id']) user_id = tid['user_id'] if 'user_id' in params and params['user_id'] != tid['user_id']: permissions = core.get_workspace_permissions(toyz_settings, tid, params) print('permissions', permissions) if permissions['view']: user_id = params['user_id'] else: raise ToyzJobError("You do not have permission to load {0}".format( params['work_id'])) workspaces = db_utils.get_param(toyz_settings.db, 'workspaces', user_id=user_id) if params['work_id'] not in workspaces: raise ToyzJobError("{0} not found in your workspaces".format( params['work_id'])) response = { 'id': 'workspace', 'work_id': params['work_id'], 'settings': workspaces[params['work_id']] } return response
def load_user_info(toyz_settings, tid, params): """ Load info for a given user from the database Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (see *params* below) Params - user_id or group_id (*string* ): User or group to load parameters for - user_attr (*list* ): List of user attributes to load Response - id: 'user_info' - Each attribute requested by the client is also returned as a key in the response """ user = core.get_user_type(params) fields = params['user_attr'] response = {'id': 'user_info'} for field in fields: if field in params['user_attr']: response[field] = db_utils.get_param(toyz_settings.db, field, **user) return response
def load_user_info(toyz_settings, tid, params): """ Load info for a given user from the database Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (see *params* below) Params - user_id or group_id (*string* ): User or group to load parameters for - user_attr (*list* ): List of user attributes to load Response - id: 'user_info' - Each attribute requested by the client is also returned as a key in the response """ user = core.get_user_type(params) fields = params['user_attr'] response = { 'id': 'user_info' } for field in fields: if field in params['user_attr']: response[field] = db_utils.get_param(toyz_settings.db, field, **user) return response
def get_module_info(toyz_settings, tid, params): """ Get information about modules accessible by the current user """ from toyz.utils import io from toyz.utils import sources toyz_modules = {'toyz': dict(io.io_modules)} data_sources = {'toyz': sources.src_types} tiles = {} import_error = {} modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=tid['user_id']) for module in modules: try: logger.info("importing {0}.config".format(module)) config = importlib.import_module(module + '.config') if hasattr(config, 'workspace_tiles'): tiles.update(config.workspace_tiles) if hasattr(config, 'io_modules'): toyz_modules.update({module: config.io_modules}) if hasattr(config, 'src_types'): data_sources[module] = config.src_types except ImportError: import_error[module] = 'could not import' + module + '.config' return { 'data_sources': data_sources, 'tiles': tiles, 'import_errors': import_error, 'toyz_modules': toyz_modules }
def save_user_info(toyz_settings, tid, params): """ Save a users info. If any admin settings are being changed, ensures that the user is in the admin group. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (see *params* below) Params can be any settings the user has permission to set on the server. Response - id: 'notification' - func: 'save_user_info' - msg: 'Settings saved for <user_id>' """ groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) # check that user is in the admin group if 'paths' in params and tid['user_id']!='admin' and 'admin' not in groups: raise ToyzJobError("You must be in the admin group to modify path permissions") if (('modules' in params or 'toyz' in params or 'third_party' in params) and tid['user_id']!='admin' and 'admin' not in groups and 'modify_toyz' not in groups): raise ToyzJobError( "You must be an administrator or belong to the 'modify_toyz' " "group to modify a users toyz or module access") # Conditions is a dict that contains any conditional parameters from a gui # parameter list. We don't use any of those for this function, so we remove them if 'conditions' in params: del params['conditions'] user = core.get_user_type(params) #update_fields = dict(params) #if 'user_id' in params: # del update_fields['user_id'] #elif 'group_id' in params: # del update_fields['group_id'] for field in params: if field in db_utils.param_formats: field_dict = {field: params[field]} field_dict.update(user) db_utils.update_all_params(toyz_settings.db, field, **field_dict) if 'user_id' in user: msg = params['user_id'] else: msg = params['group_id'] response = { 'id': 'notification', 'func': 'save_user_info', 'msg': 'Settings saved for '+ msg } return response
def get_all_user_modules(toyz_settings, user_id): """ Get all modules available for the user. Parameters toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): - Settings for the application runnning the job (may be needed to load user info or check permissions) user_id ( *string* ): id of the current user Returns user_modules ( *list* of *strings* ): - list of all toyz modules that the user has access to, including permissions granted by member groups """ groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=user_id) user_modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=user_id) user_modules.extend(toyz_settings.config.approved_modules) for group_id in groups: user_modules.extend(db_utils.get_param(toyz_settings.db, 'modules', group_id=group_id)) return list(set(user_modules))
def get_all_user_toyz(toyz_settings, user_id): """ Get all available Toyz paths for the current user Parameters toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): - Settings for the application runnning the job (may be needed to load user info or check permissions) user_id ( *string* ): id of the current user Returns user_toyz ( *dict* ): - All of the local python directories that the user can use to run jobs. """ groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=user_id) user_toyz = {} for group_id in groups: user_toyz.update(db_utils.get_param(toyz_settings.db, 'toyz', group_id=group_id)) user_toyz.update(db_utils.get_param(toyz_settings.db, 'toyz', user_id=user_id)) return user_toyz
def get_all_user_toyz(toyz_settings, user_id): """ Get all available Toyz paths for the current user Parameters toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): - Settings for the application runnning the job (may be needed to load user info or check permissions) user_id ( *string* ): id of the current user Returns user_toyz ( *dict* ): - All of the local python directories that the user can use to run jobs. """ groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=user_id) user_toyz = {} for group_id in groups: user_toyz.update( db_utils.get_param(toyz_settings.db, 'toyz', group_id=group_id)) user_toyz.update( db_utils.get_param(toyz_settings.db, 'toyz', user_id=user_id)) return user_toyz
def check_user_shortcuts(toyz_settings, user_id, shortcuts=None): """ Check that a user has all of the default shortcuts. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): Toyz Settings - user_id (*string* ): User id to check for shortcuts - shortcuts (*dict*, optional): Dictionary of shortcuts for a user. Shortcuts are always of the form ``shortcut_name:path`` . Returns - shortcuts: dictionary of shortcuts for the user """ modified = False if shortcuts==None: shortcuts = db_utils.get_param(toyz_settings.db, 'shortcuts', user_id=user_id) if 'user' not in shortcuts: shortcuts['user'] = os.path.join(toyz_settings.config.root_path, 'users', user_id) db_utils.update_param(toyz_settings.db, 'shortcuts', user_id=user_id, shortcuts={'user': shortcuts['user']}) create_paths([shortcuts['user']]) modified = True if 'temp' not in shortcuts: shortcuts['temp'] = os.path.join(shortcuts['user'], 'temp') db_utils.update_param(toyz_settings.db, 'shortcuts', user_id=user_id, shortcuts={'temp': shortcuts['temp']}) create_paths([shortcuts['temp']]) modified = True if modified: db_utils.update_param(toyz_settings.db, 'shortcuts', user_id=user_id, shortcuts=shortcuts) paths = db_utils.get_param(toyz_settings.db, 'paths', user_id=user_id) # Ensure that the user has full access to his/her home directory if shortcuts['user'] not in paths or paths[shortcuts['user']] !='frwx': db_utils.update_param(toyz_settings.db, 'paths', user_id=user_id, paths={shortcuts['user']: '******'}) return shortcuts
def get_all_user_modules(toyz_settings, user_id): """ Get all modules available for the user. Parameters toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): - Settings for the application runnning the job (may be needed to load user info or check permissions) user_id ( *string* ): id of the current user Returns user_modules ( *list* of *strings* ): - list of all toyz modules that the user has access to, including permissions granted by member groups """ groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=user_id) user_modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=user_id) user_modules.extend(toyz_settings.config.approved_modules) for group_id in groups: user_modules.extend( db_utils.get_param(toyz_settings.db, 'modules', group_id=group_id)) return list(set(user_modules))
def new_session(self, user_id, websocket, session_id=None): """ Open a new websocket session for a given user Parameters user_id ( :py:class:`toyz.utils.core.ToyzUser` ): User id websocket (:py:class:`toyz.web.app.WebSocketHandler` ): new websocket opened """ import datetime if user_id not in self.user_sessions: self.user_sessions[user_id] = {} print("Users logged in:", self.user_sessions.keys()) if session_id is None: session_id = str(datetime.datetime.now()).replace( ' ', '__').replace('.', '-').replace(':', '_') self.user_sessions[user_id][session_id] = websocket shortcuts = db_utils.get_param(self.toyz_settings.db, 'shortcuts', user_id=user_id) shortcuts = core.check_user_shortcuts(self.toyz_settings, user_id, shortcuts) websocket.session = { 'user_id': user_id, 'session_id': session_id, 'path': os.path.join(shortcuts['temp'], session_id), } core.create_paths(websocket.session['path']) #initialize process for session jobs websocket.job_pipe, remote_pipe = multiprocessing.Pipe() websocket.process = multiprocessing.Process(target=job_process, args=(session_id, remote_pipe, websocket.job_pipe)) websocket.process.start() remote_pipe.close() process_events = (tornado.ioloop.IOLoop.READ | tornado.ioloop.IOLoop.ERROR) tornado.ioloop.IOLoop.current().add_handler(websocket.job_pipe, websocket.send_response, process_events) websocket.write_message({ 'id': 'initialize', 'user_id': user_id, 'session_id': session_id, })
def old_load_data_file(toyz_settings, tid, params): """ Load a data file given a set of parameters from the browser, initialized by ``get_io_info``. """ import toyz.utils.io as io import toyz.utils.sources as sources src_types = sources.src_types modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=tid['user_id']) for module in modules: try: config = importlib.import_module(module + '.config') except ImportError: import_error[module] = 'could not import' + module + '.config' if hasattr(config, 'src_types'): src_types.update(config.src_types) # If this is the first data source, define variable to keep track of data sources if not hasattr(session_vars, 'data_sources'): session_vars.data_sources = {} # Load the data into a data object src_id = params['src_id'] src_name = params['src_name'] if 'src_type' in params: src_type = params['src_type'] else: src_type = 'DataSource' if 'data_type' in params: data_type = params['data_type'] else: data_type = None print('PARAMS:', params, "\n\n") session_vars.data_sources[src_id] = src_types[src_type]( user_id=tid['user_id'], data_type=data_type, paths=params['paths']) session_vars.data_sources[src_id].src_id = src_id session_vars.data_sources[src_id].name = src_id response = { 'id': 'data_file', 'columns': session_vars.data_sources[src_id].columns, } return response
def get_file_permissions(db_settings, path, **user): """ Get all of the permissions for a given path. Returns **None** type if no permissions have been set. Parameters - db_settings (*object* ): Database settings - path (*string* ): Path to check for permissions - user (*dict* ): Key is either **user_id** or **group_id**, value is the *user_id* or *group_id* Return - permissions (*string* ): Permissions for the given user for the given path. Returns **None** if no permissions have been set. """ # If the user is an admin, automatically grant him/her full permission for user_type, user_id in user.items(): if user_id == 'admin': return 'frwx' elif 'user_id' in user: groups = db_utils.get_param(db_settings, 'groups', **user) print('groups', groups) if 'admin' in groups: return 'frwx' permissions = None path_info = db_utils.get_path_info(db_settings, path) if path_info is not None: # Find permissions for the user or group (if there are any) if 'user_id' in user: # If permissions are set explicitely for a user, user those permissions # Otherwise check for the most stringent group permissions if user['user_id'] in path_info['users']: permissions = path_info['users'][user['user_id']] print('permissions in user', permissions) else: # Combine all group permissions to take the most permissive # permissions of the combined groups group_permissions = ''.join([p for g,p in path_info['groups'].items() if g in groups]) permissions = ''.join(set(group_permissions)) else: if user['group_id'] in path_info['groups']: permissions = path_info['groups'][user['group_id']] return permissions
def get_file_permissions(db_settings, path, **user): """ Get all of the permissions for a given path. Returns **None** type if no permissions have been set. Parameters - db_settings (*object* ): Database settings - path (*string* ): Path to check for permissions - user (*dict* ): Key is either **user_id** or **group_id**, value is the *user_id* or *group_id* Return - permissions (*string* ): Permissions for the given user for the given path. Returns **None** if no permissions have been set. """ # If the user is an admin, automatically grant him/her full permission for user_type, user_id in user.items(): if user_id == 'admin': return 'frwx' elif 'user_id' in user: groups = db_utils.get_param(db_settings, 'groups', **user) print('groups', groups) if 'admin' in groups: return 'frwx' permissions = None path_info = db_utils.get_path_info(db_settings, path) if path_info is not None: # Find permissions for the user or group (if there are any) if 'user_id' in user: # If permissions are set explicitely for a user, user those permissions # Otherwise check for the most stringent group permissions if user['user_id'] in path_info['users']: permissions = path_info['users'][user['user_id']] print('permissions in user', permissions) else: # Combine all group permissions to take the most permissive # permissions of the combined groups group_permissions = ''.join( [p for g, p in path_info['groups'].items() if g in groups]) permissions = ''.join(set(group_permissions)) else: if user['group_id'] in path_info['groups']: permissions = path_info['groups'][user['group_id']] return permissions
def load_data_file(toyz_settings, tid, params): """ Load a data file given a set of parameters from the browser, initialized by ``get_io_info``. """ import toyz.utils.io as io import toyz.utils.sources as sources src_types = sources.src_types modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=tid['user_id']) for module in modules: try: config = importlib.import_module(module+'.config') except ImportError: import_error[module] = 'could not import' + module+'.config' if hasattr(config, 'src_types'): src_types.update(config.src_types) # If this is the first data source, define variable to keep track of data sources if not hasattr(session_vars, 'data_sources'): session_vars.data_sources = {} # Load the data into a data object src_id = params['src_id'] src_name = params['src_name'] if 'src_type' in params: src_type = params['src_type'] else: src_type = 'DataSource' if 'data_type' in params: data_type = params['data_type'] else: data_type = None session_vars.data_sources[src_id] = src_types[src_type]( user_id=tid['user_id'], data_type=data_type, paths=params['paths']) session_vars.data_sources[src_id].src_id = src_id session_vars.data_sources[src_id].name = src_id response = { 'id': 'data_file', 'columns': session_vars.data_sources[src_id].columns, } return response
def new_session(self, user_id, websocket, session_id=None): """ Open a new websocket session for a given user Parameters user_id ( :py:class:`toyz.utils.core.ToyzUser` ): User id websocket (:py:class:`toyz.web.app.WebSocketHandler` ): new websocket opened """ import datetime if user_id not in self.user_sessions: self.user_sessions[user_id] = {} print("Users logged in:", self.user_sessions.keys()) if session_id is None: session_id = str( datetime.datetime.now()).replace(' ','__').replace('.','-').replace(':','_') self.user_sessions[user_id][session_id] = websocket shortcuts = db_utils.get_param(self.toyz_settings.db, 'shortcuts', user_id=user_id) shortcuts = core.check_user_shortcuts(self.toyz_settings, user_id, shortcuts) websocket.session = { 'user_id': user_id, 'session_id': session_id, 'path': os.path.join(shortcuts['temp'], session_id), } core.create_paths(websocket.session['path']) #initialize process for session jobs websocket.job_pipe, remote_pipe = multiprocessing.Pipe() websocket.process = multiprocessing.Process( target = job_process, args=(session_id, remote_pipe, websocket.job_pipe)) websocket.process.start() remote_pipe.close() process_events = (tornado.ioloop.IOLoop.READ | tornado.ioloop.IOLoop.ERROR) tornado.ioloop.IOLoop.current().add_handler( websocket.job_pipe, websocket.send_response, process_events) websocket.write_message({ 'id': 'initialize', 'user_id': user_id, 'session_id': session_id, })
def close_session(self, session): """ Close a websocket session and delete any temporary files or directories created during the session. To help ensure all temp files are deleted (in case of a server or client error), if the user doesn't have any open session his/her **temp** directory is also deleted. """ shutil.rmtree(session['path']) # Close process for current session tornado.ioloop.IOLoop.current().remove_handler( self.user_sessions[session['user_id']][session['session_id']].job_pipe) self.user_sessions[session['user_id']][session['session_id']].job_pipe.close() # Delete the current session del self.user_sessions[session['user_id']][session['session_id']] # If all of the users sessions have completed, delete the users temp directory if len(self.user_sessions[session['user_id']])==0: shortcuts = db_utils.get_param(self.toyz_settings.db, 'shortcuts', user_id=session['user_id']) shutil.rmtree(shortcuts['temp']) del self.user_sessions[session['user_id']]
def check_pwd(toyz_settings, user_id, pwd): """ Check to see if a users password matches the one stored in the database. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings` ): Settings for the current application - user_id (*string* ): Id of the user logging in - pwd: (*string* ): password the user has entered Returns - valid_login (*bool* ): True if the user name and password match """ from passlib.context import CryptContext pwd_context = CryptContext(**toyz_settings.security.pwd_context) users = db_utils.get_all_ids(toyz_settings.db, user_type='user_id') if user_id not in users: # Dummy check to prevent a timing attack to guess user names pwd_context.verify('foo', 'bar') return False user_hash = db_utils.get_param(toyz_settings.db, 'pwd', user_id=user_id) return pwd_context.verify(pwd, user_hash)
def close_session(self, session): """ Close a websocket session and delete any temporary files or directories created during the session. To help ensure all temp files are deleted (in case of a server or client error), if the user doesn't have any open session his/her **temp** directory is also deleted. """ shutil.rmtree(session['path']) # Close process for current session tornado.ioloop.IOLoop.current().remove_handler(self.user_sessions[ session['user_id']][session['session_id']].job_pipe) self.user_sessions[session['user_id']][ session['session_id']].job_pipe.close() # Delete the current session del self.user_sessions[session['user_id']][session['session_id']] # If all of the users sessions have completed, delete the users temp directory if len(self.user_sessions[session['user_id']]) == 0: shortcuts = db_utils.get_param(self.toyz_settings.db, 'shortcuts', user_id=session['user_id']) shutil.rmtree(shortcuts['temp']) del self.user_sessions[session['user_id']]
def get_workspace_permissions(toyz_settings, tid, params): groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) shared_workspaces = db_utils.get_workspace_sharing( toyz_settings.db, user_id=params['user_id'], work_id=params['work_id']) permissions = {'view': False, 'modify': False, 'share': False} if tid['user_id'] == 'admin' or 'admin' in groups: for p in permissions: permissions[p] = True else: if len(shared_workspaces) > 0: for shared_user in shared_workspaces: if (shared_user['share_id_type'] == 'user_id' and shared_user['share_id'] == tid['user_id']): for p in permissions: permissions[p] = permissions[p] or shared_user[p] elif (shared_user['share_id_type'] == 'group_id' and shared_user['share_id'] in groups): for p in permissions: permissions[p] = permissions[p] or shared_user[p] return permissions
def load_workspace(toyz_settings, tid, params): """ Load a workspace """ core.check4keys(params, ['work_id']) user_id = tid['user_id'] if 'user_id' in params and params['user_id']!=tid['user_id']: permissions = core.get_workspace_permissions(toyz_settings, tid, params) print('permissions', permissions) if permissions['view']: user_id = params['user_id'] else: raise ToyzJobError("You do not have permission to load {0}".format(params['work_id'])) workspaces = db_utils.get_param(toyz_settings.db, 'workspaces', user_id=user_id) if params['work_id'] not in workspaces: raise ToyzJobError("{0} not found in your workspaces".format(params['work_id'])) response = { 'id': 'workspace', 'work_id': params['work_id'], 'settings': workspaces[params['work_id']] } return response
def get_module_info(toyz_settings, tid, params): """ Get information about modules accessible by the current user """ from toyz.utils import io from toyz.utils import sources toyz_modules = { 'toyz': dict(io.io_modules) } data_sources = { 'toyz': sources.src_types } tiles = {} import_error = {} modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=tid['user_id']) for module in modules: try: logger.info("importing {0}.config".format(module)) config = importlib.import_module(module+'.config') if hasattr(config, 'workspace_tiles'): tiles.update(config.workspace_tiles) if hasattr(config, 'io_modules'): toyz_modules.update({ module: config.io_modules }) if hasattr(config, 'src_types'): data_sources[module] = config.src_types except ImportError: import_error[module] = 'could not import' + module+'.config' return { 'data_sources': data_sources, 'tiles': tiles, 'import_errors': import_error, 'toyz_modules': toyz_modules }
def get_workspace_permissions(toyz_settings, tid, params): groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) shared_workspaces = db_utils.get_workspace_sharing( toyz_settings.db, user_id=params['user_id'], work_id=params['work_id']) permissions = { 'view': False, 'modify': False, 'share': False } if tid['user_id']=='admin' or 'admin' in groups: for p in permissions: permissions[p] = True else: if len(shared_workspaces)>0: for shared_user in shared_workspaces: if (shared_user['share_id_type']=='user_id' and shared_user['share_id']==tid['user_id']): for p in permissions: permissions[p] = permissions[p] or shared_user[p] elif (shared_user['share_id_type']=='group_id' and shared_user['share_id'] in groups): for p in permissions: permissions[p] = permissions[p] or shared_user[p] return permissions
def get_img_info(toyz_settings, tid, params): """ Map a large image into a set of tiles that make up the larger image """ import toyz.web.viewer as viewer print('************************************************') core.check4keys(params, ['img_info', 'file_info']) if tid['user_id'] != 'admin': permissions = file_access.get_parent_permissions( toyz_settings.db, params['file_info']['filepath'], user_id=tid['user_id']) if 'r' not in permissions: raise ToyzJobError( 'You do not have permission to view the requested file.' 'Please contact your network administrator if you believe this is an error.' ) shortcuts = db_utils.get_param(toyz_settings.db, 'shortcuts', user_id=tid['user_id']) save_path = os.path.join(shortcuts['temp'], tid['session_id'], 'images') params['img_info']['save_path'] = save_path img_info = viewer.get_img_info(params['file_info'], params['img_info']) result = get_tile_info(toyz_settings, tid, { 'file_info': params['file_info'], 'img_info': img_info }) img_info['tiles'] = result['new_tiles'] response = { 'id': 'img info', 'img_info': img_info, 'new_tiles': result['new_tiles'] } print('************************************************') return response
def save_user_info(toyz_settings, tid, params): """ Save a users info. If any admin settings are being changed, ensures that the user is in the admin group. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (see *params* below) Params can be any settings the user has permission to set on the server. Response - id: 'notification' - func: 'save_user_info' - msg: 'Settings saved for <user_id>' """ groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) # check that user is in the admin group if 'paths' in params and tid[ 'user_id'] != 'admin' and 'admin' not in groups: raise ToyzJobError( "You must be in the admin group to modify path permissions") if (('modules' in params or 'toyz' in params or 'third_party' in params) and tid['user_id'] != 'admin' and 'admin' not in groups and 'modify_toyz' not in groups): raise ToyzJobError( "You must be an administrator or belong to the 'modify_toyz' " "group to modify a users toyz or module access") # Conditions is a dict that contains any conditional parameters from a gui # parameter list. We don't use any of those for this function, so we remove them if 'conditions' in params: del params['conditions'] user = core.get_user_type(params) #update_fields = dict(params) #if 'user_id' in params: # del update_fields['user_id'] #elif 'group_id' in params: # del update_fields['group_id'] for field in params: if field in db_utils.param_formats: field_dict = {field: params[field]} field_dict.update(user) db_utils.update_all_params(toyz_settings.db, field, **field_dict) if 'user_id' in user: msg = params['user_id'] else: msg = params['group_id'] response = { 'id': 'notification', 'func': 'save_user_info', 'msg': 'Settings saved for ' + msg } return response
def load_user_settings(toyz_settings, tid, params): """ Load settings for a given user Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (**None** for this function) Response for all users - id: 'user_settings' - shortcuts (*dict* ): Dictionary of ``shortcut_name: shortcut_path`` 's for the user - workspaces (*dict* ): Dictionary of ``workspace_name: workspace_settings`` for the user Additional response keys for users in the **modify_toyz** group - modules (*list* ): List of toyz modules the user can run - toyz (*dict* ): Dictionary of ``toy_name: path_to_toy`` 's that the user can run Additional reponse keys for admins - config (*dict* ): Configuration settings for the application - db (*dict* ): Database settings - web (*dict*): Web settings - security (*dict* ): Security settings - users (*list* ): list of all users in the database - groups (*list* ): list of all groups in the database - user_settings (*dict* ): Settings for a specified user (initially the *admin*) - group_settings (*dict* ): Settings for a specified group (initially the *admin* group) """ from toyz.utils import third_party dbs = toyz_settings.db old_shortcuts = db_utils.get_param(dbs, 'shortcuts', user_id=tid['user_id']) shortcuts = core.check_user_shortcuts(toyz_settings, tid['user_id'], old_shortcuts) workspaces = db_utils.get_param(dbs, 'workspaces', user_id=tid['user_id']) response = { 'id':'user_settings', 'shortcuts': shortcuts, 'workspaces': workspaces } # set the default workspace sharing options if len(workspaces)>0: response['workspace'] = sorted(workspaces.keys())[0] groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) # Only allow administrators to modify user settings if tid['user_id']=='admin' or 'admin' in groups: all_users = db_utils.get_all_ids(dbs, 'user_id') all_groups = db_utils.get_all_ids(dbs, 'group_id') user_settings = load_user_info(toyz_settings, tid, { 'user_id': 'admin', 'user_attr': ['groups', 'modules', 'toyz', 'paths'], }) group_settings = load_user_info(toyz_settings, tid, { 'group_id': 'admin', 'user_attr': ['groups', 'modules', 'toyz', 'paths'], }) del user_settings['id'] del group_settings['id'] user_settings['user_id'] = 'admin' group_settings['group_id'] = 'admin' response.update({ 'config': toyz_settings.config.__dict__, 'db': toyz_settings.db.__dict__, 'web': toyz_settings.web.__dict__, 'security': toyz_settings.security.__dict__, 'users': all_users, 'groups': all_groups, 'user_settings': user_settings, 'group_settings': group_settings }) # Only allow power users to modify toyz they have access to if 'modify_toyz' in groups or 'admin' in groups or tid['user_id'] == 'admin': response.update({ 'modules': db_utils.get_param(dbs, 'modules', user_id=tid['user_id']), 'toyz': db_utils.get_param(dbs, 'toyz', user_id=tid['user_id']) }) return response
def load_user_settings(toyz_settings, tid, params): """ Load settings for a given user Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (**None** for this function) Response for all users - id: 'user_settings' - shortcuts (*dict* ): Dictionary of ``shortcut_name: shortcut_path`` 's for the user - workspaces (*dict* ): Dictionary of ``workspace_name: workspace_settings`` for the user Additional response keys for users in the **modify_toyz** group - modules (*list* ): List of toyz modules the user can run - toyz (*dict* ): Dictionary of ``toy_name: path_to_toy`` 's that the user can run Additional reponse keys for admins - config (*dict* ): Configuration settings for the application - db (*dict* ): Database settings - web (*dict*): Web settings - security (*dict* ): Security settings - users (*list* ): list of all users in the database - groups (*list* ): list of all groups in the database - user_settings (*dict* ): Settings for a specified user (initially the *admin*) - group_settings (*dict* ): Settings for a specified group (initially the *admin* group) """ from toyz.utils import third_party dbs = toyz_settings.db old_shortcuts = db_utils.get_param(dbs, 'shortcuts', user_id=tid['user_id']) shortcuts = core.check_user_shortcuts(toyz_settings, tid['user_id'], old_shortcuts) workspaces = db_utils.get_param(dbs, 'workspaces', user_id=tid['user_id']) response = { 'id': 'user_settings', 'shortcuts': shortcuts, 'workspaces': workspaces } # set the default workspace sharing options if len(workspaces) > 0: response['workspace'] = sorted(workspaces.keys())[0] groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) # Only allow administrators to modify user settings if tid['user_id'] == 'admin' or 'admin' in groups: all_users = db_utils.get_all_ids(dbs, 'user_id') all_groups = db_utils.get_all_ids(dbs, 'group_id') user_settings = load_user_info( toyz_settings, tid, { 'user_id': 'admin', 'user_attr': ['groups', 'modules', 'toyz', 'paths'], }) group_settings = load_user_info( toyz_settings, tid, { 'group_id': 'admin', 'user_attr': ['groups', 'modules', 'toyz', 'paths'], }) del user_settings['id'] del group_settings['id'] user_settings['user_id'] = 'admin' group_settings['group_id'] = 'admin' response.update({ 'config': toyz_settings.config.__dict__, 'db': toyz_settings.db.__dict__, 'web': toyz_settings.web.__dict__, 'security': toyz_settings.security.__dict__, 'users': all_users, 'groups': all_groups, 'user_settings': user_settings, 'group_settings': group_settings }) # Only allow power users to modify toyz they have access to if 'modify_toyz' in groups or 'admin' in groups or tid[ 'user_id'] == 'admin': response.update({ 'modules': db_utils.get_param(dbs, 'modules', user_id=tid['user_id']), 'toyz': db_utils.get_param(dbs, 'toyz', user_id=tid['user_id']) }) return response
def load_directory(toyz_settings, tid, params): """ Used by the file browser to load the folders and files in a given path. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (see *params* below) Params - path (*string* ): Path to search Response - id: 'directory' - path (*string* ): path passed to the function - shortcuts (*dict* ): Dictionary of ``shortcut_name: shortcut_path`` 's for the user - folders (*list* of strings): folders contained in the path - files (*list* of strings): files contained in the path - parent (*string* ): parent directory of current path """ core.check4keys(params, ['path']) show_hidden = False # If the path is contained in a set of dollar signs (for example `$images$`) then # search in the users shortcuts for the given path shortcuts = db_utils.get_param(toyz_settings.db, 'shortcuts', user_id=tid['user_id']) if params['path'][0] == '$' and params['path'][-1] == '$': shortcut = params['path'][1:-1] if shortcut not in shortcuts: raise ToyzJobError("Shortcut '{0}' not found for user {1}".format( shortcut, tid['user_id'])) params['path'] = shortcuts[shortcut] if not os.path.isdir(params['path']): parent = os.path.dirname(params['path']) if not os.path.isdir(parent): raise ToyzJobError("Path '{0}' not found".format(params['path'])) params['path'] = parent if 'show_hidden' in params and params['show_hidden']: show_hidden = True # Keep separate lists of the files and directories for the current path. # Only include the files and directories the user has permissions to view files = [] folders = [] groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) if 'admin' in groups or tid['user_id'] == 'admin': admin = True else: admin = False for f in os.listdir(params['path']): if (f[0] != '.' or show_hidden): f_path = os.path.join(params['path'], f) if admin: permission = True else: permissions = file_access.get_parent_permissions( toyz_settings.db, f_path, user_id=tid['user_id']) if permissions is None: permissions = '' permission = 'f' in permissions if permission: if os.path.isfile(f_path): files.append(str(f)) elif os.path.isdir(f_path): folders.append(str(f)) else: print("no access to", f) files.sort(key=lambda v: v.lower()) folders.sort(key=lambda v: v.lower()) response = { 'id': 'directory', 'path': os.path.join(params['path'], ''), 'shortcuts': shortcuts.keys(), 'folders': folders, 'files': files, 'parent': os.path.abspath(os.path.join(params['path'], os.pardir)) } #print('path info:', response) return response
def load_directory(toyz_settings, tid, params): """ Used by the file browser to load the folders and files in a given path. Parameters - toyz_settings ( :py:class:`toyz.utils.core.ToyzSettings`): Settings for the toyz application - tid (*string* ): Task ID of the client user running the task - params (*dict* ): Any parameters sent by the client (see *params* below) Params - path (*string* ): Path to search Response - id: 'directory' - path (*string* ): path passed to the function - shortcuts (*dict* ): Dictionary of ``shortcut_name: shortcut_path`` 's for the user - folders (*list* of strings): folders contained in the path - files (*list* of strings): files contained in the path - parent (*string* ): parent directory of current path """ core.check4keys(params,['path']) show_hidden=False # If the path is contained in a set of dollar signs (for example `$images$`) then # search in the users shortcuts for the given path shortcuts = db_utils.get_param(toyz_settings.db, 'shortcuts', user_id=tid['user_id']) if params['path'][0]=='$' and params['path'][-1]=='$': shortcut = params['path'][1:-1] if shortcut not in shortcuts: raise ToyzJobError("Shortcut '{0}' not found for user {1}".format(shortcut, tid['user_id'])) params['path'] = shortcuts[shortcut] if not os.path.isdir(params['path']): parent = os.path.dirname(params['path']) if not os.path.isdir(parent): raise ToyzJobError("Path '{0}' not found".format(params['path'])) params['path'] = parent if 'show_hidden' in params and params['show_hidden']: show_hidden=True # Keep separate lists of the files and directories for the current path. # Only include the files and directories the user has permissions to view files = [] folders = [] groups = db_utils.get_param(toyz_settings.db, 'groups', user_id=tid['user_id']) if 'admin' in groups or tid['user_id'] == 'admin': admin=True else: admin=False for f in os.listdir(params['path']): if(f[0]!='.' or show_hidden): f_path =os.path.join(params['path'],f) if admin: permission = True else: permissions = file_access.get_parent_permissions(toyz_settings.db, f_path, user_id=tid['user_id']) if permissions is None: permissions = '' permission = 'f' in permissions if permission: if os.path.isfile(f_path): files.append(str(f)) elif os.path.isdir(f_path): folders.append(str(f)) else: print("no access to", f) files.sort(key=lambda v: v.lower()) folders.sort(key=lambda v: v.lower()) response={ 'id': 'directory', 'path': os.path.join(params['path'],''), 'shortcuts': shortcuts.keys(), 'folders': folders, 'files': files, 'parent': os.path.abspath(os.path.join(params['path'],os.pardir)) } #print('path info:', response) return response
def get_workspace_info(toyz_settings, tid, params): """ Get I/O settings for different packages (pure python, numpy, pandas, etc) and other settings for the current users workspaces """ import toyz.utils.io as io import toyz.utils.sources as sources src_types = sources.src_types.keys() data_types = sources.data_types image_types = sources.image_types toyz_modules = { 'toyz': dict(io.io_modules) } # Get workspace info from other Toyz modules tiles = {} import_error = {} modules = db_utils.get_param(toyz_settings.db, 'modules', user_id=tid['user_id']) for module in modules: try: print("importing", module+'.config') config = importlib.import_module(module+'.config') except ImportError: import_error[module] = 'could not import' + module+'.config' if hasattr(config, 'workspace_tiles'): tiles.update(config.workspace_tiles) if hasattr(config, 'data_types'): data_types += config.data_types if hasattr(config, 'image_types'): image_types += config.image_types if hasattr(config, 'io_modules'): toyz_modules.update({ module: config.io_modules }) if hasattr(config, 'src_types'): src_types += config.src_types.keys() load_src = io.build_gui(toyz_modules, 'load') load_src.update({ 'optional': { 'src_type': { 'lbl': 'Data Source Type', 'type': 'select', 'options': sorted(src_types), 'default_val': 'DataSource' }, 'data_type': { 'lbl': 'data type', 'type': 'select', 'options': sorted(data_types) }, 'image_type': { 'lbl': 'image_type', 'type': 'select', 'options': sorted(image_types) } } }) save_src = io.build_gui(toyz_modules, 'save') response = { 'id': 'workspace_info', 'load_src_info': load_src, 'save_src_info': save_src, 'tiles': tiles, 'import_error': import_error } return response