Exemple #1
0
    def _execute_embedded_script(self, script):
        log = logging.getLogger("%s.%s" % (__name__, self.uuid))
        try:
            log.info("start executing workflow script")
            env = dict(data=self._get_data())
            dispatcher = PluginRegistry.getInstance('CommandRegistry')

            def make_dispatch(method):
                def call(*args, **kwargs):
                    return dispatcher.dispatch(self.__user, self.__session_id,
                                               method, *args, **kwargs)

                return call

            # Add public calls
            for method in dispatcher.getMethods():
                env[method] = make_dispatch(method)

            # add logger
            env['log'] = log

            exec(script, env)

            log.info("finished executing workflow script")

            if self.__user is not None:
                # tell the frontend
                e = EventMaker()
                ev = e.Event(
                    e.BackendDone(e.UUID(self.uuid), e.Type("workflow"),
                                  e.State("success")))
                event_object = objectify.fromstring(
                    etree.tostring(ev, pretty_print=True).decode('utf-8'))
                SseHandler.notify(event_object,
                                  channel="user.%s" % self.__user)

        except Exception as ex:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]

            log.error("Exception while executing the embedded script:")
            log.error("%s line %s" % (fname, exc_tb.tb_lineno))
            log.error(exc_type)
            log.error(exc_obj)

            if GosaErrorHandler.get_error_id(str(ex)) is None:
                ex = ScriptError(C.make_error('WORKFLOW_SCRIPT_ERROR',
                                              str(ex)))

            e = EventMaker()
            ev = e.Event(
                e.BackendDone(e.UUID(self.uuid), e.Type("workflow"),
                              e.State("error"), e.Message(str(ex))))
            event_object = objectify.fromstring(
                etree.tostring(ev, pretty_print=True).decode('utf-8'))
            SseHandler.notify(event_object, channel="user.%s" % self.__user)
            raise ex

        return True
Exemple #2
0
    def runcode(self, code):
        """
        Execute a code object.

        When an exception occurs, self.showtraceback() is called to
        display a traceback.  All exceptions are caught except
        SystemExit, which is reraised.

        A note about KeyboardInterrupt: this exception may occur
        elsewhere in this code, and may not always be caught.  The
        caller should be prepared to deal with it.
        """
        self.lastCode = code
        try:
            exec(code, self.locals)
        except SystemExit:  # pragma: nocover
            raise
        except HTTPError as e:
            if e.code == 401:
                raise
            self.showtraceback()
        except JSONRPCException as e:
            # Check for error member
            try:
                err = e.error["error"]
            except KeyError:
                err = str(e)
            # Resolve error details if supplied
            error_id = C.get_error_id(err)
            if error_id:
                locs = locale.getdefaultlocale()
                info = self.proxy.getError(error_id, ".".join(locs if locs != (None, None) else ("en_US", "UTF-8")))
                detail = ""
                if info['details']:
                    detail = " - %s [%s]" % (info['details'][0]['detail'], info['details'][0]['index'])
                if info['topic']:
                    print(info['text'] + detail + ": " + info['topic'])
                else:
                    print(info['text'] + detail)

            else:
                print(err)

            if softspace(sys.stdout, 0):
                print()
        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info() #@UnusedVariable
            self.showtraceback()
        else:
            if softspace(sys.stdout, 0):
                print()
Exemple #3
0
    def __set_client_offline(self, client, purge=False):
        try:
            self.systemSetStatus(client, "-O+o")
        except ValueError as e:
            id = C.get_error_id(str(e))
            error = C.getError(None, None, id, keep=True)
            if error['status_code'] == 404:
                pass
            else:
                raise e

        if client in self.__client:
            if purge:
                del self.__client[client]

                if client in self.__proxy:
                    self.__proxy[client].close()
                    del self.__proxy[client]

                if client in self.__user_session:
                    del self.__user_session[client]

            else:
                self.__client[client]['online'] = False
Exemple #4
0
    def __set_client_offline(self, client, purge=False):
        try:
            self.systemSetStatus(client, "-O+o")
        except ValueError as e:
            id = C.get_error_id(str(e))
            error = C.getError(None, None, id, keep=True)
            if error.status_code == 404:
                pass
            else:
                raise e

        if client in self.__client:
            if purge:
                del self.__client[client]

                if client in self.__proxy:
                    self.__proxy[client].close()
                    del self.__proxy[client]

                if client in self.__user_session:
                    del self.__user_session[client]

            else:
                self.__client[client]['online'] = False
Exemple #5
0
    def dispatch(self, method, params, jid):
        cached_method = method[0:2] == "**"
        hash_value = None
        if cached_method:
            method = method[2:]
            hash_value = params.pop(0)
        # Try to call method with dispatcher
        if not self.dispatcher.hasMethod(method):
            text = "No such method '%s'" % method
            error_value = dict(
                name='JSONRPCError',
                code=100,
                message=text,
                error=text)
            self.log.warning(text)

            self.set_status(500)
            return dict(result=None, error=error_value, id=jid)

        try:
            self.log.debug("calling method %s(%s)" % (method, params))
            user = self.get_secure_cookie('REMOTE_USER').decode('ascii') if self.get_secure_cookie('REMOTE_USER') else None
            sid = self.get_secure_cookie('REMOTE_SESSION').decode('ascii') if self.get_secure_cookie('REMOTE_SESSION') else None
            self.log.debug("received call [%s] for %s (SID=%s): %s(%s)" % (jid, user, sid, method, params))

            if user is None and method in no_login_commands:
                # allow execution without user
                user = self.dispatcher

            if isinstance(params, dict):
                result = self.dispatcher.dispatch(user, sid, method, **params)
            else:
                result = self.dispatcher.dispatch(user, sid, method, *params)

        except JSONRPCException as e:
            exc_value = sys.exc_info()[1]
            error_value = dict(
                name='JSONRPCError',
                code=100,
                message=str(exc_value),
                error=e.error)
            self.log.error(e.error)

            self.set_status(500)
            return dict(result=None, error=error_value, id=jid)

        except Exception as e:
            text = traceback.format_exc()
            exc_value = sys.exc_info()[1]
            status_code = 500

            #TODO: enroll information if it's an extended exception
            err = str(e)
            err_id = C.get_error_id(err)
            if err_id is not None:
                # get error
                err = C.getError(None, None, err_id, keep=True)
                if err and 'status_code' in err and err['status_code'] is not None:
                    status_code = err['status_code']

            error_value = dict(
                name='JSONRPCError',
                code=100,
                message=str(exc_value),
                error=err)

            self.log.error("returning call [%s]: %s / %s" % (jid, None, f_print(err)))
            self.log.error(text)

            self.set_status(status_code)
            return dict(result=None, error=error_value, id=jid)

        self.log.debug("returning call [%s]: %s / %s" % (jid, result, None))
        if cached_method:
            response_hash = hashlib.md5(repr(result).encode('utf-8')).hexdigest()
            if hash_value == response_hash:
                # cache hit
                result = dict(hash=response_hash)
            else:
                # cache miss
                result = dict(hash=response_hash, response=result)
        return dict(result=result, error=None, id=jid)