(meth)
return new
initialize the XMLRPC environment and wrap the command in a transaction
initialize the XMLRPC environment and wrap the command in a transaction
initialize the XMLRPC environment and wrap the command in a transaction
def xmlrpc_decorator(meth):
    '''initialize the XMLRPC environment and wrap the command in a transaction
    '''
    def preprocess(ticket):
        '''store the state when the ticket comes from the web'''
        data_key = "%s:%s" % (XMLRPC_DATA_KEY, self.__hash__())
        init_data_key = "%s:%s" % (XMLRPC_INIT_DATA_KEY, self.__hash__())

        if isinstance(ticket, dict):
            lang = ticket.get('language')
            if lang == 'javascript':
                state  = Container.get(data_key).copy()
                Container.put(init_data_key, state)

    def postprocess(ticket):
        '''restore the state when the ticket comes from the web'''
        data_key = "%s:%s" % (XMLRPC_DATA_KEY, self.__hash__())
        init_data_key = "%s:%s" % (XMLRPC_INIT_DATA_KEY, self.__hash__())

        if isinstance(ticket, dict):
            state  = Container.get(init_data_key)
            if state:
                Container.put(data_key, state)

    def decode_api_key(key):
        key = key.lstrip("$")
        tmp_dir = Environment.get_tmp_dir(include_ticket=True)
        path = "%s/api_key_%s.txt" % (tmp_dir,key)
        if not os.path.exists(path):
            print("ERROR: API path [%s] not found" % path)
            raise ApiException("API key not valid")

        f = open(path, 'r')
        data = f.read()
        f.close()
        data = jsonloads(data)
        api_method = data.get("api_method")
        inputs = data.get("inputs")
        login = data.get("login")
        ticket = data.get("ticket")
        current_login = Environment.get_user_name()
        if current_login:
            if login == current_login:
                return api_method, inputs, ticket
            else:
                raise ApiException("Permission Denied: wrong user")
        else:
            return api_method, inputs, ticket




    def new(self, original_ticket, *args, **kwargs):

        api_key = original_ticket.get("api_key")
        results = None

        try:
            ticket = self.init(original_ticket)
            # ticket = original_ticket.get("ticket")

            # These modes disable a good chunk of the API for a more secure
            # environment.

            if self.get_protocol() != 'local':
                api_mode = Environment.get_api_mode()

                allowed = False

                security = Environment.get_security()
                user_name = security.get_user_name()

                if user_name == "admin":
                    allowed = True

                meth_name = meth.__name__
                if api_mode == "open":
                    allowed = True

                if api_mode in ["closed", "query"]:
                    if api_mode == "closed":
                        if meth_name in API_MODE.get("closed"):
                            allowed = True
                    elif api_mode == "query":
                        if meth_name in API_MODE.get("query") or meth_name in API_MODE.get("closed"):
                            allowed = True

                    if not allowed:
                        if api_key:
                            if isinstance(api_key, basestring):
                                if api_key.startswith("$"):
                                    api_method, api_inputs, api_ticket = decode_security_key(api_key)
                                    if api_method == meth.__name__:
                                        for i in range(len(api_inputs)):
                                            if api_inputs[i] == "__API_UNKNOWN__":
                                                api_inputs[i] = args[i]

                                            if isinstance(api_inputs[i], dict):
                                                for k, v in api_inputs[i].items():
                                                    if v == "__API_UNKNOWN__":
                                                        api_inputs[i][k] = args[i][k]

                                            if api_inputs[i] == args[i]:
                                                allowed = True
                                            else:
                                                allowed = False
                                                print("WARNING: Trying to pass in unexpected inputs: %s" % args[i])
                                                break
                                    else:
                                        raise ApiException("Try to access API's that are not allowed.")

                if not allowed:
                    raise ApiException("Permission Denied [%s] [%s]" % (meth.__name__, args))


            try:
                multi_site = Config.get_value("master", "enabled")

                if meth.__name__ in QUERY_METHODS:
                    cmd = get_simple_cmd(self, meth, ticket, args)
                elif meth.__name__ in TRANS_OPTIONAL_METHODS:
                    cmd = None

                    # If multi-site is enabled, redirect commands flagged as update.
                    if multi_site and meth.__name__ == "execute_cmd" and args[0]:
                        if args[0] != "tactic.ui.app.DynamicUpdateCmd":
                            cmd_class = Common.create_from_class_path(args[0], {}, {})
                            if cmd_class.is_update() == True:
                                #FIXME: Extra dict is appended to args list
                                result = self.redirect_to_server(ticket, meth.__name__, args[:-1])
                                return self.browser_res(meth, result)

                        cmd = get_simple_cmd(self, meth, ticket, args)

                    else:
                        idx =  TRANS_OPTIONAL_METHODS[meth.__name__]
                        if len(args) - 1 == idx and args[idx].get('use_transaction') == False:
                            cmd = get_simple_cmd(self, meth, ticket, args)
                        else:
                            cmd = get_full_cmd(self, meth, ticket, args)

                else:
                    if multi_site:
                        result = self.redirect_to_server(ticket, meth.__name__, args[:-1])
                        return self.browser_res(meth, result)
                    else:
                        cmd = get_full_cmd(self, meth, ticket, args)

                profile_flag = False

                if Container.get("profile") == True:
                    profile_flag = False

                if profile_flag:
                    Container.put("profile", True)

                    global profile_cmd
                    profile_cmd = cmd
                    import profile, pstats
                    if os.name == 'nt':
                        path = "C:/sthpw/profile"
                    else:
                        path = "/tmp/sthpw/profile"
                    profile.run( "from pyasm.prod.service import profile_execute; profile_execute()", path)
                    p = pstats.Stats(path)
                    p.sort_stats('cumulative').print_stats(30)
                    print("*"*30)
                    p.sort_stats('time').print_stats(30)

                else:
                    if self.get_protocol() == 'local':
                        transaction = Transaction.get()
                        if not transaction:
                            cmd.execute_cmd(cmd)
                        else:
                            cmd.execute()
                    else:
                        cmd.execute_cmd(cmd)

                if not cmd.get_description():
                    cmd.add_description(meth.__name__)

                #postprocess(original_ticket)
                results = cmd.results

            except Exception as e:

                # make sure all sqls are aborted
                if not self.get_protocol() == "local":
                    DbContainer.abort_thread_sql(force=True)


                #print("Error: ", e.message)
                import traceback
                tb = sys.exc_info()[2]
                stacktrace = traceback.format_tb(tb)
                stacktrace_str = "".join(stacktrace)
                print("-"*50)
                print(stacktrace_str)
                try:
                    message = e.message
                except:
                    message = str(e)

                if not message:
                    message = e.__str__()

                if not Common.IS_Pv3:
                    if isinstance(message, unicode):
                        error_msg = message.encode('utf-8')
                    elif isinstance(message, str):
                        error_msg = unicode(message, errors='ignore').encode('utf-8')
                    else:
                        error_msg = message
                else:
                    error_msg = message
                print("Error: ", error_msg)
                print("-"*50)
                raise

        finally:
            if not self.get_protocol() == "local":
                DbContainer.release_thread_sql()


        # reformat the data to JSON if going to the browser
        try:
            # NOTE: add in a special requirement for get_widget() because
            # of the bizarre 4096 byte limitation on responseXML in the browser
            results = self.browser_res(meth, results)

            # handle special cases for c#
            #elif self.get_language() == 'c#':
            #    results = jsondumps(results)


        except Exception as e:
            print(e.__str__())

        return results

    new.exposed = True
    return new
def xmlrpc_decorator ( meth ) : def preprocess ( ticket ) : '''store the state when the ticket comes from the web''' data_key = "%s:%s" % ( XMLRPC_DATA_KEY , self . __hash__ ( ) ) init_data_key = "%s:%s" % ( XMLRPC_INIT_DATA_KEY , self . __hash__ ( ) ) if isinstance ( ticket , dict ) : lang = ticket . get ( 'language' ) if lang == 'javascript' : state = Container . get ( data_key ) . copy ( ) Container . put ( init_data_key , state ) def postprocess ( ticket ) : '''restore the state when the ticket comes from the web''' data_key = "%s:%s" % ( XMLRPC_DATA_KEY , self . __hash__ ( ) ) init_data_key = "%s:%s" % ( XMLRPC_INIT_DATA_KEY , self . __hash__ ( ) ) if isinstance ( ticket , dict ) : state = Container . get ( init_data_key ) if state : Container . put ( data_key , state ) def decode_api_key ( key ) : key = key . lstrip ( "$" ) tmp_dir = Environment . get_tmp_dir ( include_ticket = True ) path = "%s/api_key_%s.txt" % ( tmp_dir , key ) if not os . path . exists ( path ) : print ( "ERROR: API path [%s] not found" % path ) raise ApiException ( "API key not valid" ) f = open ( path , 'r' ) data = f . read ( ) f . close ( ) data = jsonloads ( data ) api_method = data . get ( "api_method" ) inputs = data . get ( "inputs" ) login = data . get ( "login" ) ticket = data . get ( "ticket" ) current_login = Environment . get_user_name ( ) if current_login : if login == current_login : return api_method , inputs , ticket else : raise ApiException ( "Permission Denied: wrong user" ) else : return api_method , inputs , ticket def new ( self , original_ticket , * args , * * kwargs ) : api_key = original_ticket . get ( "api_key" ) results = None try : ticket = self . init ( original_ticket ) # ticket = original_ticket.get("ticket") # These modes disable a good chunk of the API for a more secure # environment. if self . get_protocol ( ) != 'local' : api_mode = Environment . get_api_mode ( ) allowed = False security = Environment . get_security ( ) user_name = security . get_user_name ( ) if user_name == "admin" : allowed = True meth_name = meth . __name__ if api_mode == "open" : allowed = True if api_mode in [ "closed" , "query" ] : if api_mode == "closed" : if meth_name in API_MODE . get ( "closed" ) : allowed = True elif api_mode == "query" : if meth_name in API_MODE . get ( "query" ) or meth_name in API_MODE . get ( "closed" ) : allowed = True if not allowed : if api_key : if isinstance ( api_key , basestring ) : if api_key . startswith ( "$" ) : api_method , api_inputs , api_ticket = decode_security_key ( api_key ) if api_method == meth . __name__ : for i in range ( len ( api_inputs ) ) : if api_inputs [ i ] == "__API_UNKNOWN__" : api_inputs [ i ] = args [ i ] if isinstance ( api_inputs [ i ] , dict ) : for k , v in api_inputs [ i ] . items ( ) : if v == "__API_UNKNOWN__" : api_inputs [ i ] [ k ] = args [ i ] [ k ] if api_inputs [ i ] == args [ i ] : allowed = True else : allowed = False print ( "WARNING: Trying to pass in unexpected inputs: %s" % args [ i ] ) break else : raise ApiException ( "Try to access API's that are not allowed." ) if not allowed : raise ApiException ( "Permission Denied [%s] [%s]" % ( meth . __name__ , args ) ) try : multi_site = Config . get_value ( "master" , "enabled" ) if meth . __name__ in QUERY_METHODS : cmd = get_simple_cmd ( self , meth , ticket , args ) elif meth . __name__ in TRANS_OPTIONAL_METHODS : cmd = None # If multi-site is enabled, redirect commands flagged as update. if multi_site and meth . __name__ == "execute_cmd" and args [ 0 ] : if args [ 0 ] != "tactic.ui.app.DynamicUpdateCmd" : cmd_class = Common . create_from_class_path ( args [ 0 ] , { } , { } ) if cmd_class . is_update ( ) == True : #FIXME: Extra dict is appended to args list result = self . redirect_to_server ( ticket , meth . __name__ , args [ : - 1 ] ) return self . browser_res ( meth , result ) cmd = get_simple_cmd ( self , meth , ticket , args ) else : idx = TRANS_OPTIONAL_METHODS [ meth . __name__ ] if len ( args ) - 1 == idx and args [ idx ] . get ( 'use_transaction' ) == False : cmd = get_simple_cmd ( self , meth , ticket , args ) else : cmd = get_full_cmd ( self , meth , ticket , args ) else : if multi_site : result = self . redirect_to_server ( ticket , meth . __name__ , args [ : - 1 ] ) return self . browser_res ( meth , result ) else : cmd = get_full_cmd ( self , meth , ticket , args ) profile_flag = False if Container . get ( "profile" ) == True : profile_flag = False if profile_flag : Container . put ( "profile" , True ) global profile_cmd profile_cmd = cmd import profile , pstats if os . name == 'nt' : path = "C:/sthpw/profile" else : path = "/tmp/sthpw/profile" profile . run ( "from pyasm.prod.service import profile_execute; profile_execute()" , path ) p = pstats . Stats ( path ) p . sort_stats ( 'cumulative' ) . print_stats ( 30 ) print ( "*" * 30 ) p . sort_stats ( 'time' ) . print_stats ( 30 ) else : if self . get_protocol ( ) == 'local' : transaction = Transaction . get ( ) if not transaction : cmd . execute_cmd ( cmd ) else : cmd . execute ( ) else : cmd . execute_cmd ( cmd ) if not cmd . get_description ( ) : cmd . add_description ( meth . __name__ ) #postprocess(original_ticket) results = cmd . results except Exception as e : # make sure all sqls are aborted if not self . get_protocol ( ) == "local" : DbContainer . abort_thread_sql ( force = True ) #print("Error: ", e.message) import traceback tb = sys . exc_info ( ) [ 2 ] stacktrace = traceback . format_tb ( tb ) stacktrace_str = "" . join ( stacktrace ) print ( "-" * 50 ) print ( stacktrace_str ) try : message = e . message except : message = str ( e ) if not message : message = e . __str__ ( ) if not Common . IS_Pv3 : if isinstance ( message , unicode ) : error_msg = message . encode ( 'utf-8' ) elif isinstance ( message , str ) : error_msg = unicode ( message , errors = 'ignore' ) . encode ( 'utf-8' ) else : error_msg = message else : error_msg = message print ( "Error: " , error_msg ) print ( "-" * 50 ) raise finally : if not self . get_protocol ( ) == "local" : DbContainer . release_thread_sql ( ) # reformat the data to JSON if going to the browser try : # NOTE: add in a special requirement for get_widget() because # of the bizarre 4096 byte limitation on responseXML in the browser results = self . browser_res ( meth , results ) # handle special cases for c# #elif self.get_language() == 'c#': #    results = jsondumps(results) except Exception as e : print ( e . __str__ ( ) ) return results new . exposed = True return new