Esempio n. 1
0
    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))
Esempio n. 2
0
    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]
Esempio n. 3
0
    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
Esempio n. 4
0
    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))
Esempio n. 6
0
    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
Esempio n. 7
0
    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"
Esempio n. 8
0
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)
Esempio n. 9
0
    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)
Esempio n. 10
0
    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)
Esempio n. 11
0
    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)
Esempio n. 12
0
    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("")