def addPermission(self, name, permission): from .models import Permission from core import db key = self.name + "." + name description = "No description available" if hasattr(permission, 'description'): description = permission.description engine = db.get_engine() table_exists = engine.dialect.has_table(engine, Permission.__tablename__) if table_exists: p = Permission.query.filter_by(name=key).first() if p is None: p = Permission(name=key, description=description) db.session.add(p) db.session.commit() p = Permission.query.filter_by(name=key).first() else: p.caption = description db.session.commit() self.permissions[key] = p else: logManager.error( 'Unable to create permission "{}" for workspace {}'.format( name, self.name))
def handle(self, action, user, workspace, actionManager): logManager.info("Execute action '{}' on view '{}'", action['viewAction'], action['view']) viewname = action['view'] if viewname in workspace.dataViews: print('found view', viewname, 'in', workspace.name, workspace.dataViews[viewname]) view = workspace.dataViews[viewname] # check if login required for this view if view.requireLogin is True and user is None: raise RequireLoginError else: # build actions to get view response_actions = [] response_data = None try: view.dataSyncs = [] dictionary = action response_data = view.executeViewActionHandler( user, workspace, ObjDict(dictionary)) notification_action = webclientActions.NotificationAction.generate( "Action '" + str(action['viewAction']) + "' executed", "info") response_actions.append(notification_action) self.db.session.commit() for v in view.dataSyncs: updateView = workspace.dataViews[v['view']] meta_data = updateView.getViewMetaHandler( user, workspace) entries = updateView.getViewHandler( user, workspace, None) properties = updateView.getProperties() uri = workspace.uri + '/' + updateView.uri loadviewaction = webclientActions.LoadViewAction.generate( uri, properties, entries, meta_data) response_actions.append(loadviewaction) except Exception as e: notification_action = webclientActions.NotificationAction.generate( "Action '" + str(action['viewAction']) + "' failed with: ", "error") response_actions = [notification_action] logManager.error( str(type(e).__name__) + 'in ExecuteViewActionsActionHandler', action['view']) traceback.print_exc(file=sys.stdout) # entries = view.getViewHandler(user, workspace) # properties = view.getProperties() # uri = view.uri # loadviewaction = webclientActions.LoadViewAction.generate(uri, properties, entries) if response_data is not None: return 'success', response_actions, response_data else: return 'success', response_actions # view not found notification_action = webclientActions.NotificationAction.generate( "View >" + viewname + "< not found", "error") return 'success', [notification_action]
def run_job(self, user, jobkey, args, date, max_instances=10, log_trigger=False): print("run job ", jobkey) if jobkey in self.jobs: je = None if log_trigger is True: from core.jobs.models import JobExecute je = JobExecute() je.triggered_on = str(datetime.now()) if user is None: je.triggered_by = "" else: je.triggered_by = user.email je.name = jobkey je.workspace = self.jobs[jobkey].workspace je.state = "TRIGGERED" self.db.session.add(je) self.db.session.commit() # if self.jobs[jobkey]['cron']: # # handle a cron job # job = self.scheduler.get_job(jobkey) # job.modify(next_run_time=datetime.now()) # return None # else: # handle a single trigger job jobInstance = self.jobs[jobkey]['job_class']() self.job_counter += 1 job_ececution_id = None if je is not None: job_ececution_id = je.id kwargs = { "job_id": str(jobkey) + str(self.job_counter), "job_execution_id": job_ececution_id } kwargs = {**kwargs, **args} self.scheduler.add_job(jobInstance.start_job, id=(str(jobkey) + str(self.job_counter)), trigger='date', next_run_time=str(date), kwargs=kwargs, max_instances=max_instances) if je is not None: return je.id else: return None else: logManager.error("Unknown type of job in add_dated_job") return None
def handle(self, action, user, workspace, actionManager): logManager.info("Execute update of view entry for '{}'", action['view']) viewname = action['view'] if viewname in workspace.dataViews: view = workspace.dataViews[viewname] # check if login required for this view if view.requireLogin is True and user is None: raise RequireLoginError else: # build actions to get view responseActions = [] try: if view.entrykey not in action['entry']: notification_action = webclientActions.NotificationAction.generate( "UpdateViewEntryActionHandler miss entrykey", "error") responseActions = [notification_action] else: view.dataSyncs = [] dictionary = action['entry'] view.updateViewEntryHandler( user, workspace, action['entry'][str(view.entrykey)], ObjDict(dictionary)) self.db.session.commit() for v in view.dataSyncs: updateView = workspace.dataViews[v['view']] entries = updateView.getViewHandler( user, workspace, None) meta_data = updateView.getViewMetaHandler( user, workspace) properties = updateView.getProperties() uri = workspace.uri + '/' + updateView.uri loadviewaction = webclientActions.LoadViewAction.generate( uri, properties, entries, meta_data) responseActions.append(loadviewaction) responseActions.append( webclientActions.NotificationAction.generate( "Updated successfully", "success")) return 'success', responseActions except Exception as e: notification_action = webclientActions.NotificationAction.generate( "UpdateViewEntry '" + str(action['view']) + "' failed with: " + str(e), "error") responseActions = [notification_action] logManager.error( str(type(e).__name__) + 'in ExecuteViewActionsActionHandler ' + action['view']) traceback.print_exc(file=sys.stdout) return 'success', responseActions notification_action = webclientActions.NotificationAction.generate( "View >" + viewname + "< not found", "error") return 'success', [notification_action]
def triggerWorkspaceHooks(self, hook: WorkspaceHooks, **kwargs): for w in self.workspaces: try: if hook == WorkspaceHooks.CREATEUSER: w.createUserHook(**kwargs) if hook == WorkspaceHooks.REMOVEUSER: w.removeUserHook(**kwargs) except Exception as e: logManager.error('Failed to run hook {} on {} with {}'.format( hook, w.name, e))
def handle(self, action, user, workspace, actionManager): logManager.info("Execute actionlink") response_actions = [] try: response_actions.append(webclientActions.UpdateActionlinkStatusAction.generate( "success", "Action succeed")) response_actions = response_actions + executeActionLink(action.hash, user) except (ExpiredError, NotFoundError): response_actions = [ webclientActions.UpdateActionlinkStatusAction.generate("error", "Action not found or expired") ] except Exception as e: logManager.error("Execute actionlink failed: {}".format(str(e))) response_actions = [webclientActions.UpdateActionlinkStatusAction.generate("error", "Action failed")] return 'success', response_actions
def activate_node(self, node): logManager.info("Activate node " + node.name) nodeInstance = None for k, v in self.node_classes.items(): if v.class_id == node.class_id: nodeInstance = self.node_classes[k]() nodeInstance.identity = node.identification if nodeInstance is not None: self.nodes[node.fingerprint] = nodeInstance else: logManager.error( "NodeManager is unable to register node {} [{}] with unknown class_id '{}'" .format(node.name, node.fingerprint, node.class_id)) node.active = True node.status = "Active"
def add_dated_job(user, job, args, date=None, workspace=None, max_instances=10): if date is None: date = datetime.now() key = "" if workspace is not None: if type(workspace) == str: key += workspace + '/' elif isclass(workspace): logManager.error( "Class parameters are not allowed for add_dated_job") return else: key += workspace.name + '/' if type(job) == str: key += job elif isclass(workspace): logManager.error("Class parameters are not allowed for add_dated_job") return elif issubclass(type(job), Job): key += job.name else: logManager.error("Unknown type of job in add_dated_job") return jobManager.run_job(user, key, args, date, max_instances)
def handleActionRequest(self, identity, expire_date, request): actions = request['actions'] response_actions = [] response_data = {} user = None print('identity = ', identity) for action in actions: if action['workspace'] in self.actionsMap: print('action workspace found') if action['action'] in self.actionsMap[action['workspace']]: print('action', action['action'], 'found in workspace') user = (self.userManager.getUser(identity)) workspace = self.workspacesMap[action['workspace']] try: handle_result = self.actionsMap[action['workspace']][ action['action']].handle(ObjDict(action), user, workspace, self) except RequireLoginError: route_action = webclientActions.RouteAction.generate( 'dashboard', delay=0) notification_action = webclientActions.NotificationAction.generate( "Login required", "error", delay=2) response_actions = [route_action, notification_action] return self.buildActionReply(response_actions, response_data) handle_result_len = len(handle_result) if handle_result_len == 1: state, actions, response = handle_result, [], {} elif handle_result_len == 2: state, actions, response = handle_result[ 0], handle_result[1], {} elif handle_result_len == 3: state, actions, response = handle_result else: state, actions, response = "error", [], {} self.db.session.commit() if state == 'success': pass else: logManager.error('Action {} failed', action['action']) response_intersection = response_data.keys() & response if len(response_intersection) != 0: logManager.warning( 'Action response data for {} overrided the following properties', action['action'], response_intersection) response_data = {**response_data, **response} response_actions = response_actions + actions else: logManager.error('action ' + action['action'] + ' not found in ' + action['workspace']) else: logManager.error('action workspace: "' + action['workspace'] + ' "not found') if expire_date is not None and identity is not None: difference = expire_date - datetime.datetime.now() remaining_minutes = difference.seconds / 60 session_expiration_minutes = self.config['SYSTEM'].get( 'session_expiration_minutes', 15) if remaining_minutes < session_expiration_minutes * 0.5: access_token = self.userManager.updateAccessToken(identity) response_actions.insert( 0, webclientActions.UpdateSessionTokenAction.generate( access_token)) return self.buildActionReply(response_actions, response_data)
def executeActionLink(self, hash, user): response_actions = [] al = self.actionLink.query.filter_by(hash=hash).first() if al is None: raise NotFoundError if al.expire_on_date < arrow.utcnow(): raise ExpiredError try: if str(al.workspace) in self.actionsMap: print('action workspace found') if al.action in self.actionsMap[al.workspace]: print('action', al.action, 'found in workspace') if user is None and al.need_login is True: response_actions.append( webclientActions.NotificationAction.generate( "Login needed you will be redirected.", "success")) response_actions.append( webclientActions.RouteAction.generate( "user/login?redirect=actionlink/" + hash, 3)) return response_actions if al.redirect_to != "": response_actions.append( webclientActions.RouteAction.generate( al.redirect_to, 2)) workspace = self.workspacesMap[al.workspace] print(user, workspace) param = al.action_data_json state, actions = self.actionsMap[al.workspace][ al.action].handle(ObjDict(param), user, workspace, self) if state == 'success': logManager.info( 'Actionlink succed with {} for user: {}', actions, user) else: logManager.error( 'Actionlink failed with {} for user: {}', actions, user) raise Exception( str('Action failed with {} for user: {}', actions, user)) response_actions = response_actions + actions return response_actions else: logManager.error('action ' + al.action + ' not found in ' + al.workspace) raise Exception( str('action workspace: "' + al.workspace + '" not found')) else: logManager.error('action workspace: "' + al.workspace + '"not found') raise Exception( str('action workspace: "' + al.workspace + '"not found')) except Exception as e: raise e finally: if al.run_only_once is True: self.db.session.delete(al)
def discoverWorkspaces(self, source): """Recursively walk the supplied package to retrieve all plugins (workspaces) """ imported_source = __import__(source, fromlist=['blah']) all_current_paths = [] # all_current_paths.append(imported_source.__path__._path) if isinstance(imported_source.__path__, str): all_current_paths.append(imported_source.__path__) else: all_current_paths.extend([x for x in imported_source.__path__]) # remove duplicates all_current_paths = list(set(all_current_paths)) for pkg_path in all_current_paths: # Walk through all sub directories child_pkgs = [ p for p in os.listdir(pkg_path) if os.path.isdir(os.path.join(pkg_path, p)) ] # Every sub directory contains one workspace for child_pkg in child_pkgs: imported_package = __import__(source + '.' + child_pkg, fromlist=['blah']) for _, workspacename, ispkg in pkgutil.iter_modules( imported_package.__path__, imported_package.__name__ + '.'): workspaceCounter = 0 if not ispkg: workspace_module = __import__(workspacename, fromlist=['blah']) clsmembers = inspect.getmembers( workspace_module, inspect.isclass) for (_, c) in clsmembers: # Check for workspace classes if issubclass(c, Workspace) & (c is not Workspace): workspaceCounter += 1 if workspaceCounter > 1: logManager.error( 'Only one workspace is allowed for one folder, other workspaces will skipped' ) break uri = "" if hasattr(c, 'uri'): uri = c.uri else: logManager.error( f'No uri defined and will not be accessable for workspace: {c.__module__}' ) name = c.__name__ if hasattr(c, 'name'): name = c.name workspaceInstance = c(self.app, self.db, name, uri) workspaceInstance.path = os.path.dirname( workspace_module.__file__) logManager.info( 'Workspace discovered : {} [{}] with uri "{}"' .format(workspaceInstance.name, c.__module__, workspaceInstance.uri)) if workspaceInstance.disable is True: logManager.info( 'Workspace {} [{}] is disabled and wont show up.' .format(workspaceInstance.name, c.__module__)) else: self.workspaces.append(workspaceInstance)
def registerWorkspacePlugins(self): """Recursively walk the supplied package to retrieve components for all plugins (workspaces) """ logManager.info("") logManager.info("Register components from workspaces:") logManager.info("") for w in self.workspaces: logManager.info(f'Workspace: "{w.name}"') # try to discover commands try: w.discoverCommands(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover commands ({str(type(e).__name__)}:{e})' ) # try to register permissions try: w.discoverPermissions(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover permissions ({str(type(e).__name__)}:{e})' ) # try to register dataViews try: w.discoverDataViews(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover dataviews ({str(type(e).__name__)}:{e})' ) # try to register jobs try: w.discoverJobs(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover jobs ({str(type(e).__name__)}:{e})' ) # try to register actions try: w.discoverActions(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover actions ({str(type(e).__name__)}:{e})' ) # try to register sections try: w.discoverSections(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover sections ({str(type(e).__name__)}:{e})' ) # try to register node classes try: w.discoverNodeClasses(self.workspaceSource) except ModuleNotFoundError: logManager.info(f'No node classes discovered for "{w.name}"') except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover node classes ({str(type(e).__name__)}:{e})' ) # try to register permissions try: w.discoverPages(self.workspaceSource) except Exception as e: traceback.print_exc(file=sys.stdout) logManager.error( f'Workspace "{w.name}" unable to discover pages ({str(type(e).__name__)}:{e})' ) logManager.info("")