def verify(my, login_name, password):
        # replace cn=attribute with cn={login} in the config ldap_path
        # e.g. cn={login},o=organization,ou=server,dc=domain
        path = Config.get_value("security", "ldap_path")
        server = Config.get_value("security", "ldap_server")
        assert path, server

        my.login_name = login_name
        my.internal = True
        path = path.replace("{login}", login_name)
        #import ldap

        try:
            l = ldap.open(server)
            l.simple_bind_s(path, password)
            l.unbind()
            return True
        except: 
            login = Login.get_by_login(login_name)
            # check if it's an external account and verify with standard approach
            if login and login.get_value('location', no_exception=True) == 'external':
                auth_class = "pyasm.security.TacticAuthenticate"
                authenticate = Common.create_from_class_path(auth_class)
                is_authenticated = authenticate.verify(login_name, password)
                if is_authenticated == True:
                    my.internal = False
                    return True
            elif login:
                auth_class = "pyasm.security.TacticAuthenticate"
                authenticate = Common.create_from_class_path(auth_class)
                is_authenticated = authenticate.verify(login_name, password)
                if is_authenticated == True:
                    my.internal = False
                    return True
            raise SecurityException("Login/Password combination incorrect")
Example #2
0
    def draw(self):
        self.add_shortcuts()
        data_dir = tacticenv.get_data_dir()

        if os.path.exists(data_dir):
            geometry = Config.get_value("window", "geometry")
            title = Config.get_value("window", "title")
        else:
            geometry = None
            title = None

        if not title:
            title = "TACTIC - %s" % self.url
            geometry = Config.get_value("window", "geometry")
        
        if geometry == "fullscreen":
            self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
            self.showFullScreen()
        elif geometry:
            parts = geometry.split(",")
            parts = [int(x) for x in parts]
            self.setGeometry(parts[0], parts[1], parts[2], parts[3])

        self.splash.finish(self)
        self.setWindowTitle(title)
        self.setCentralWidget(self.webView)  
        self.show()  
Example #3
0
    def __init__(my, port=''):

        # It is possible on startup that the database is not running.
        from pyasm.search import DbContainer, DatabaseException, Sql

        try:
            sql = DbContainer.get("sthpw")
            if sql.get_database_type() != "MongoDb":
                # before batch, clean up the ticket with a NULL code
                if os.getenv('TACTIC_MODE') != 'production':
                    sql.do_update('DELETE from "ticket" where "code" is NULL;')
                else:
                    start_port = Config.get_value("services", "start_port")
                    if start_port:
                        start_port = int(start_port)
                    else:
                        start_port = 8081
                    if port and int(port) == start_port:
                         sql.do_update('DELETE from "ticket" where "code" is NULL;')
        except DatabaseException, e:
            # TODO: need to work on this
            print "ERROR: could not connect to [sthpw] database"
            #os.environ["TACTIC_CONFIG_PATH"] = Config.get_default_config_path()
            #Sql.set_default_vendor("Sqlite")

            Config.set_tmp_config()
            Config.reload_config()

            # try connecting again
            try:
                sql = DbContainer.get("sthpw")
            except:
                print "Could not connect to the database."
                raise
Example #4
0
    def verify(self, login_name, password):
            
        if login_name.find("\\") != -1:
            domain, base_login_name = login_name.split("\\")
        else:
            base_login_name = login_name
            domain = None

        # confirm that there is a domain present if required
        require_domain = Config.get_value("active_directory", "require_domain")
        domain_component = Config.get_value("active_directory","domain_component")
        script_path = Config.get_value("active_directory","allow_script")
        
        if script_path:
            flag = False
            try:
                from tactic.command import PythonCmd
                from pyasm.command import Command
                kwargs = {'login' : login_name}
                cmd = PythonCmd(script_path=script_path, **kwargs)
                #flag = Command.execute_cmd(cmd)
                flag = cmd.execute()
            except Exception, e:
                print e
                raise
            if flag != True:
                return False  
Example #5
0
    def execute(my):

        # make sure tmp config is unset.
        Config.unset_tmp_config()
        Config.reload_config()

        web = WebContainer.get_web()

        vendor = web.get_form_value("database/vendor")


        if vendor == 'Sqlite':
            db_dir = web.get_form_value("database/sqlite_db_dir")
            database = "sthpw"
            db_path = "%s/%s.db" % (db_dir, database)
            if os.path.exists(db_path):
                return

        elif vendor == 'PostgreSQL':
            my.test_postgres(vendor)
            return

        elif vendor in ['MySQL','SQLServer','Oracle']:
            my.test_postgres(vendor)
            return

        my.info['error'] = "Cannot connect to database"
Example #6
0
    def _do_login(self):

        security = Environment.get_security()

        require_password = Config.get_value("security", "api_require_password")
        api_password = Config.get_value("security", "api_password")

        site = Site.get()
        allow_guest =  site.allow_guest()

        # the xmlrpc login can be overridden to not require a password
        if require_password == "false" or (allow_guest and self.login_name == "guest"):
            security.login_user_without_password(self.login_name, expiry="NULL")
        elif api_password:
            if api_password == self.password:
                security.login_user_without_password(self.login_name, expiry="NULL")
            else:
                # if api password is incorrect, still try and authenticate with
                # user's password
                security.login_user(self.login_name, self.password, expiry="NULL")
        elif self.login_name == "guest":
                security.login_user_without_password(self.login_name)
        else:        
            security.login_user(self.login_name, self.password, expiry="NULL")

        if not security.is_logged_in():
            raise SecurityException("Cannot login as user: %s." % self.login_name)
Example #7
0
    def execute(self):

        # save prefix
        local_prefix = self.get_value("local_prefix")
        self.server_prefix = Config.get_value("install", "server")

        if not local_prefix and not self.server_prefix:
            raise TacticException("Cannot have empty local server prefix")

        if local_prefix and local_prefix != self.server_prefix:
            Config.set_value("install", "server", local_prefix)

            Config.save_config()

        self.project_code = self.get_value("project")
        if not self.project_code:
            self.project_code = Project.get_project_code()


        # create a share
        share = SearchType.create("sthpw/sync_server")
        self.handle_info(share)
        self.handle_sync_mode(share)

        share.commit()
Example #8
0
    def _test_strict_checkin(my):

        server = Config.get_value("install", "server")
        process = "process"
        person_code = my.person.get_code()

        filename = "filename.jpg"

        process = "strict"

        subcontexts = [
            '', '', # do 2 checkins
            'hi', 'hi',
            'medium',
            'low',
        ]

        for i, subcontext in enumerate(subcontexts):

            if subcontext:
                context = "%s/%s" % (process, subcontext)
            else:
                context = process

            # create a new test.txt file
            file_path = "./%s" % filename
            file = open(file_path, 'w')
            file.write("test")
            file.close()


            #import time
            #start = time.time()

            checkin = FileCheckin(my.person, file_path, context=context, checkin_type='strict')
            checkin.execute()
            snapshot = checkin.get_snapshot()

            #print "time: ", time.time() - start
            #print "---"

            # make sure there is no versionless
            versionless = Snapshot.get_versionless(my.person.get_search_type(), my.person.get_id(), context, mode='latest', create=False)
            my.assertEquals(None, versionless)

            
            path = snapshot.get_path_by_type("main")

            asset_dir = Config.get_value("checkin", "asset_base_dir")

            file_objects = snapshot.get_all_file_objects()
            my.assertEquals(1, len(file_objects))

            file_object = file_objects[0]
            relative_dir = file_object.get_value("relative_dir")
            file_name = file_object.get_value("file_name")

            test_path = "%s/%s/%s" % (asset_dir, relative_dir, file_name)
            my.assertEquals(test_path, path)
def do_startup(port, server=""):

    #from tactic.startup import FirstRunInit
    #cmd = FirstRunInit()
    #cmd.execute()

    if os.name != 'nt' and os.getuid() == 0:
        print 
        print "You should not run this as root. Run it as the Web server process's user. e.g. apache"
        print
	return

    thread_count = Config.get_value("services", "thread_count") 
    

    if not thread_count:
        thread_count = 10
    else: 
        thread_count = int(thread_count)


    from pyasm.web.cherrypy30_startup import CherryPyStartup
    startup = CherryPyStartup()

    startup.set_config('global', 'server.socket_port', port)

    startup.set_config('global', 'server.socket_queue_size', 100)
    startup.set_config('global', 'server.thread_pool', thread_count)
    #startup.set_config('global', 'server.socket_host', server)

    #startup.set_config('global', 'log.screen', True)

    startup.set_config('global', 'request.show_tracebacks', True)
    startup.set_config('global', 'server.log_unhandled_tracebacks', True)

    startup.set_config('global', 'engine.autoreload_on', True)




    hostname = None
    server_default = '127.0.0.1'

    if not server:
        hostname = Config.get_value("install", "hostname") 
        if hostname == 'localhost':
            # swap it to IP to suppress CherryPy Warning
            hostname = server_default
        if hostname:
            # special host name for IIS which can't load balance across many
            # ports with the same service
            hostname = hostname.replace("{port}", str(port))
            server = hostname
        else:
            server = server_default
       
    startup.set_config('global', 'server.socket_host', server)

    startup.execute()
Example #10
0
    def _test_base_dir_alias(my):

        Config.set_value("checkin", "asset_base_dir", {
            'default': '/tmp/tactic/default',
            'alias': '/tmp/tactic/alias',
            'alias2': '/tmp/tactic/alias2',
        });
        asset_dict = Environment.get_asset_dirs()
        default_dir = asset_dict.get("default")
        my.assertEquals( "/tmp/tactic/default", default_dir)

        aliases = asset_dict.keys()
        # "plugins" is assumed in some branch 
        if 'plugins' in aliases:
            my.assertEquals( 4, len(aliases))
        else:
            my.assertEquals( 3, len(aliases))
        my.assertNotEquals( None, "alias" in aliases )

        # create a naming
        naming = SearchType.create("config/naming")
        naming.set_value("search_type", "unittest/person")
        naming.set_value("context", "alias")
        naming.set_value("dir_naming", "alias")
        naming.set_value("file_naming", "text.txt")
        naming.set_value("base_dir_alias", "alias")
        naming.commit()

        # create 2nd naming where 
        naming = SearchType.create("config/naming")
        naming.set_value("search_type", "unittest/person")
        naming.set_value("context", "alias2")
        naming.set_value("dir_naming", "alias2")
        naming.set_value("base_dir_alias", "alias2")
        naming.set_value("file_naming", "text.txt")
        naming.set_value("checkin_type", "auto")
        naming.commit()

        my.clear_naming()

        # create a new test.txt file
        for context in ['alias', 'alias2']:
            file_path = "./test.txt"
            file = open(file_path, 'w')
            file.write("whatever")
            file.close()

            checkin = FileCheckin(my.person, file_path, context=context)
            checkin.execute()
            snapshot = checkin.get_snapshot()

            lib_dir = snapshot.get_lib_dir()
            expected = "/tmp/tactic/%s/%s" % (context, context)
            my.assertEquals(expected, lib_dir)

            path = "%s/text.txt" % (lib_dir)
            exists = os.path.exists(path)
            my.assertEquals(True, exists)
Example #11
0
    def configure_palette(my):

        web = WebContainer.get_web()
        palette = web.get_form_value("look/palette")

        if palette:
            Config.set_value("look", "palette", palette)
        else:
            Config.set_value("look", "palette", "")
Example #12
0
    def configure_palette(my):
        my.section = 'Look and Feel'
        web = WebContainer.get_web()
        palette = web.get_form_value("look/palette")

        if palette:
            Config.set_value("look", "palette", palette)
        else:
            Config.set_value("look", "palette", "")
Example #13
0
    def execute(self):
        self.section = None

        # make sure tmp config is unset.
        Config.unset_tmp_config()
        Config.reload_config()

        web = WebContainer.get_web()

        # read the current config file.


        # copy config to the path
        config_path = Config.get_config_path()
        if not os.path.exists(config_path):
            print "Installing default config file"

            dirname = os.path.dirname(config_path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)

            if os.name == 'nt':
                osname = 'win32'
            else:
                osname = 'linux'

            install_dir = Environment.get_install_dir()
            install_config_path = "%s/src/install/start/config/tactic_%s-conf.xml" % ( install_dir, osname)

            shutil.copy(install_config_path, dirname)

        try:
            self.configure_db()
            self.configure_install()
            self.configure_mail_services()
            self.configure_gen_services()
            self.configure_asset_dir()
            self.configure_palette()
            self.configure_security()
        except Exception as e:
            raise TacticException('Error in [%s]: %s'%(self.section, e.__str__()))
        # FIXME: if this all fails, then revert back
        
        self.save_config()

        # after saving the config, test the database
        self.load_bootstrap()

        # remove the first run file
        data_dir = Environment.get_data_dir()
        path = "%s/first_run" % data_dir
        if os.path.exists(path):
            os.unlink(path)


        self.restart_program()
Example #14
0
    def get_local_dir(self):
        '''get the local asset directory on the client machine'''
        user_agent = self.get_env("HTTP_USER_AGENT")
        if user_agent.startswith("Houdini"):
            dir = Config.get_value("checkin", "win32_local_base_dir")

        elif user_agent.find("Windows") != -1:
            dir = Config.get_value("checkin", "win32_local_base_dir")
        else:
            dir = Config.get_value("checkin", "linux_local_base_dir")

        return dir
Example #15
0
    def configure_gen_services(my):
        my.section = 'Services'
        web = WebContainer.get_web()

        options = ['process_count', 'process_time_alive', 'thread_count', 'python_path','rsync']
        for option in options:
            value = web.get_form_value("services/%s" %option)

            if value:
                Config.set_value("services", option, value)
            else:
                
                Config.set_value("services", option,  "")
Example #16
0
    def configure_services(my):

        web = WebContainer.get_web()

        options = ['server', '_user', '_password', '_port', '_tls_enabled','_sender_disabled']
        for option in options:
            server = web.get_form_value("services/mail%s" %option)

            if server:
                Config.set_value("services", "mail%s" %option, server)
            else:
                #Config.remove("services", "mail%s"%option)
                Config.set_value("services", "mail%s"%option,  "")
    def execute(my):
        hostname = my.kwargs.get("hostname")
        if not hostname:
            hostname = Config.get_value("install", "hostname")

        port = my.kwargs.get("port")
        if not port:
            port = Config.get_value("install", "port")
        if not port:
            port = 9123
        else:
            port = int(port)

        do_startup(port, server=hostname)
Example #18
0
    def execute(my):


        # make sure tmp config is unset.
        Config.unset_tmp_config()
        Config.reload_config()

        web = WebContainer.get_web()

        # read the current config file.


        # copy config to the path
        config_path = Config.get_config_path()
        if not os.path.exists(config_path):
            print "Installing default config file"

            dirname = os.path.dirname(config_path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)

            if os.name == 'nt':
                osname = 'win32'
            else:
                osname = 'linux'

            install_dir = Environment.get_install_dir()
            install_config_path = "%s/src/install/start/config/tactic_%s-conf.xml" % ( install_dir, osname)

            shutil.copy(install_config_path, dirname)

        my.configure_db()
        my.configure_install()
        my.configure_services()
        my.configure_asset_dir()
        my.configure_palette()
        # FIXME: if this all fails, then revert back
        my.save_config()

        # after saving the config, test the database
        my.load_bootstrap()

        # remove the first run file
        data_dir = Environment.get_data_dir()
        path = "%s/first_run" % data_dir
        if os.path.exists(path):
            os.unlink(path)


        my.restart_program()
Example #19
0
    def configure_security(my):
        my.section = 'Security'
        web = WebContainer.get_web()

        options = ['allow_guest','ticket_expiry','authenticate_mode',
            'authenticate_class','authenticate_version','auto_create_user',
            'api_require_password','api_password','max_login_attempt','account_logout_duration']
        for option in options:
            security_value = web.get_form_value("security/%s" %option)

            if security_value:
                Config.set_value("security", option, security_value)
            else:
                Config.set_value("security", option,  "")
Example #20
0
    def get_otherdb_wdg(my):

        div = DivWdg()
        div.add_class("spt_db_options")
        div.add_attr("spt_vendor", "Other")
        div.add_style("margin: 20px")

        table = Table()
        div.add(table)
        table.add_color("color", "color")


        table.add_row()
        table.add_cell("Server: ")
        text = TextInputWdg(name="server")
        text.set_value("localhost")
        table.add_cell(text)
        server = Config.get_value("database", "server")
        if server:
            text.set_value(server)

        table.add_row()
        table.add_cell("Port: ")
        text = TextInputWdg(name="port")
        table.add_cell(text)
        port = Config.get_value("database", "port")
        if port:
            text.set_value(port)

        table.add_row()
        table.add_cell("Login: "******"user")
        table.add_cell(text)
        user = Config.get_value("database", "user")
        if user:
            text.set_value(user)

        table.add_row()
        text = PasswordInputWdg(name="password")
        table.add_cell("Password: "******"database", "password")
        if password:
            text.set_value(password)

        #from pyasm.search import Sql
        #sql.connect()

        return div
Example #21
0
    def verify(my, login_name, password):
        path = Config.get_value("checkin", "ldap_path")
        server = Config.get_value("checkin", "ldap_server")
        assert path, server

        path = path.replace("{login}", login_name)

        import ldap

        try:
            l = ldap.open(server)
            l.simple_bind_s(path, password)
            return True
        except:
            raise SecurityException("Login/Password combination incorrect")
Example #22
0
    def get_base_url(self):
        host = self.get_http_host()

        # see if there is a protocol defined
        protocol = Config.get_value("security", "protocol")
        if not protocol:
            protocol = "http"

        # FIXME: not sure about this.
        if host == "127.0.0.1":
            base_url = Config.get_value("install", "base_url")
        else:
            base_url = "%s://%s" % (protocol, host)

        return Url(base_url)
Example #23
0
    def _test_file_owner(my):
        if os.name == 'nt':
            return
        # create a new test.txt file
        file_path = "./test2.txt"
        file = open(file_path, 'w')
        file.write("whatever")
        file.close()
        # owned by root
        os.system('echo south123paw | sudo -S chown root.root \"%s\"'%file_path)

        stat = os.stat(file_path)
        my.assertEquals(stat.st_uid, 0)

        checkin = FileCheckin(my.person, file_path, "test")
        checkin.execute()

        # check that the file exists
        snapshot = checkin.get_snapshot()
        xml = snapshot.get_xml_value("snapshot")
        file_code = xml.get_value("snapshot/file/@file_code")
        file_name = xml.get_value("snapshot/file/@name")

        my.assertNotEqual(None, file)

        lib_path = "%s/%s" % (snapshot.get_lib_dir(),file_name)
        my.assertEquals(True, os.path.exists(lib_path) )
        stat = os.stat(lib_path)
        if Config.get_value("checkin", "sudo_no_password") == 'true': 
            my.assertEquals(stat.st_uid, 48)
        else:
            # if not set, it will remain owned by root
            my.assertEquals(stat.st_uid, 0)
    def get_display(my):

        top = my.top

        sobject = my.get_current_sobject()

        version = sobject.get_value(my.get_name())
        if version == '':
            top.add("No version")

        elif version == -1:
            top.add("Latest")

        elif version == 0:
            top.add("Current")

        else:

            padding = Config.get_value("checkin", "version_padding")
            if not padding:
                padding = 3

            expr = "%s%%0.%sd" % (my.get_name()[0], padding)
            value = expr % version
            top.add(value)


        return top
Example #25
0
    def run(code, kwargs):
        code = jsondumps(code)
        kwargs = jsondumps(kwargs)

        install_dir = tacticenv.get_install_dir()
        cmd = '%s/src/tactic/command/js_cmd.py' % install_dir

        python_exec = Config.get_value("services", "python")
        cmd_list = [python_exec, cmd, code, kwargs]



        import subprocess
        program = subprocess.Popen(cmd_list, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        ret_val, error = program.communicate()

        lines = []
        start = False
        for line in ret_val.split("\n") :
            if line.startswith("~"*20):
                start = True
                continue

            if not start:
                continue

            lines.append(line)

        value = jsonloads("\n".join(lines))


        return value
Example #26
0
 def get_default_project(cls):
     from pyasm.security import Site
     project = Site.get().get_default_project()
     if project:
         return project
     project = Config.get_value("install", "default_project")
     return project
Example #27
0
    def _check(self):

        # This will kill the TACTIC process 
        # This is very harsh and should be used sparingly if at all
        use_restart = Config.get_value("services", "use_periodic_restart")
        if use_restart in [True, 'true']:
            if self.num_checks and self.num_checks % self.kill_interval == 0:
                # read pid file
                log_dir = "%s/log" % Environment.get_tmp_dir()
                file = open("%s/pid.%s" % (log_dir,self.port), "r")
                pid = file.read()
                file.close()
                Common.kill(pid)

                #self.run()
                self.num_checks += 1
                return


        self.num_checks += 1

        start = time.clock()
        try:
            response = self.check()
        except IOError, e:

            pid = self._get_pid() 
            if pid:
                Common.kill(pid)
Example #28
0
    def verify(my, login_name, password):
            
        if login_name.find("\\") != -1:
            domain, login_name = login_name.split("\\")
        else:
            domain = None

        # confirm that there is a domain present if required
        require_domain = Config.get_value("active_directory", "require_domain")
        if require_domain == "true" and not domain:
            raise SecurityException("Domain Selection Required")



        # skip authentication if ad does not exist
        if not my.ad_exists:
            print "WARNING: Active directory does not exist ... skipping verify"
            return True

        ad_connect = ADConnect()
        if domain:
            ad_connect.set_domain(domain)
        ad_connect.set_user(login_name)
        ad_connect.set_password(password)
        is_logged_in = ad_connect.logon()

        # preload data for further use later
        if is_logged_in:
            my.load_user_data(login_name)

        return is_logged_in
Example #29
0
    def get_skin(my):
        # DEPRECATED: replaced by palettes

        # TODO: prod setting shouldn't be in prod!!!
        from pyasm.prod.biz import ProdSetting
        web = WebContainer.get_web()
        skin = web.get_form_value("skin")

        # look at users preferences
        if not skin:
            skin = PrefSetting.get_value_by_key("skin")

        # if skin isn't found in user preference settings then look for it
        # in the projects/config XML file ...
        if not skin:
            skin = Config.get_value("look", "skin")

        if not skin:
            skin = "dark"

        # MMS-TACTIC ... allow for 'MMS' skin to be returned for use in overriding some colors (MMS is a copy of
        # 'dark' skin)
        if skin == 'MMS':
            return 'MMS'

        return "dark"
Example #30
0
    def __init__(self, login_name, password=None):
        super(XmlRpcLogin,self).__init__()

        self.set_app_server("xmlrpc")

        # If the tag <force_lowercase_login> is set to "true"
        # in the TACTIC config file,
        # then force the login string argument to be lowercase.
        # This tag is false by default.        
        self.login_name = login_name
        if Config.get_value("security","force_lowercase_login") == "true":
            self.login_name = self.login_name.lower()
        
        self.password = password

        # clear the main container
        #Container.clear()

        Environment.set_env_object( self )

        # set up the security object
        security = Security()
        Environment.set_security(security)

        self._do_login()
Example #31
0
 def get_top_class_name(cls):
     project = Project.get()
     class_name = project.get_value("top_class_name", no_exception=True)
     if not class_name:
         class_name = Config.get_value("install", "top_class_name")
     if not class_name:
         class_name = 'tactic.ui.app.PageNavContainerWdg'
     return class_name
Example #32
0
    def configure_security(my):
        my.section = 'Security'
        web = WebContainer.get_web()

        options = [
            'allow_guest', 'ticket_expiry', 'authenticate_mode',
            'authenticate_class', 'authenticate_version', 'auto_create_user',
            'api_require_password', 'api_password', 'max_login_attempt',
            'account_logout_duration'
        ]
        for option in options:
            security_value = web.get_form_value("security/%s" % option)

            if security_value:
                Config.set_value("security", option, security_value)
            else:
                Config.set_value("security", option, "")
Example #33
0
    def get_default_groups(my):
        groups = Config.get_value("active_directory", "default_groups")
        if not groups:
            groups = []
        else:
            groups = groups.split("|")

        return groups
Example #34
0
    def get_info_from_ad(my, login_name, attrs_map, domain=None):

        data = {}
        if login_name == 'admin':
            return data
        """
        if login_name.find("\\") != -1:
            domain, login_name = login_name.split("\\")
        else:
            domain = None
        """
        python = Config.get_value('services', 'python')
        if not python:
            python = 'python'

        try:
            # get the info from a separate process
            from subprocess import Popen, PIPE
            if domain:
                cmd = [
                    python,
                    "%s/ad_get_user_info.py" % BASE_DIR, '-d', domain, "-u",
                    login_name
                ]
            else:
                cmd = [
                    python,
                    "%s/ad_get_user_info.py" % BASE_DIR,
                    "-u",
                    login_name,
                ]

            output = Popen(cmd, stdout=PIPE).communicate()[0]
            import StringIO
            output = StringIO.StringIO(output)
            data = my.get_info_from_file(attrs_map, output)

            # get the license type from active directory
            license_type = data.get('tacticLicenseType')
            if not license_type:

                # TEST!!!! for MMS
                # FIXME: this logic is questionable.
                # if the user has no defined groups in Active Directory, then
                # it should use the default license type.
                if not my.groups:
                    license_type = my.get_default_license_type()
                    data['license_type'] = license_type
                else:
                    data['license_type'] = "user"

        except ADException:
            raise SecurityException(
                "Could not get info from Active Directory for login [%s]" %
                login_name)
        return data
Example #35
0
    def configure_category(my, title, category, options, options_type={}):
        div = DivWdg()

        title_wdg = DivWdg()
        div.add(title_wdg)

        #from tactic.ui.widget.swap_display_wdg import SwapDisplayWdg
        #swap = SwapDisplayWdg()
        #div.add(swap)

        title_wdg.add("<b>%s</b>" % title)

        table = Table()
        div.add(table)
        #table.add_color("color", "color")
        table.add_style("color: #000")
        table.add_style("margin: 20px")

        for option in options:
            table.add_row()
            display_title = Common.get_display_title(option)
            td = table.add_cell("%s: " % display_title)
            td.add_style("width: 150px")

            option_type = options_type.get(option)
            validation_scheme = ""

            #add selectWdg for those options whose type is bool
            if option_type == 'bool':
                text = SelectWdg(name="%s/%s" % (category, option))
                text.set_option('values', 'true|false')
                text.set_option('empty', 'true')
                text.add_style("margin-left: 0px")

            elif option.endswith('password'):
                text = PasswordInputWdg(name="%s/%s" % (category, option))

            # dealing with options whose type is number
            else:
                if option_type == 'number':
                    validation_scheme = 'INTEGER'

                else:
                    validation_scheme = ""

                text = TextInputWdg(name="%s/%s" % (category, option),
                                    validation_scheme=validation_scheme,
                                    read_only="false")

            value = Config.get_value(category, option)
            if value:
                text.set_value(value)

            table.add_cell(text)

        return div
Example #36
0
    def execute(my):

        input_data = my.get_input_data()
        data = my.data

        # input data for the handler
        if my.mode == 'separate process,blocking':
            input_data_str = jsondumps(input_data)
            data_str = jsondumps(data)

            file = __file__
            py_exec = Config.get_value("services", "python")
            if not py_exec:
                py_exec = "python"

            retcode = subprocess.call(
                [py_exec, file, data_str, input_data_str])

        elif my.mode == 'separate process,non-blocking':
            input_data_str = jsondumps(input_data)
            data_str = jsondumps(data)

            file = __file__
            py_exec = Config.get_value("services", "python")
            if not py_exec:
                py_exec = "python"

            retcode = subprocess.Popen(
                [py_exec, file, data_str, input_data_str])
        elif my.mode == 'same process,new transaction':
            # run it inline
            trigger = ScriptTrigger()
            trigger.set_data(data)
            trigger.set_input(input_data)
            trigger.execute()

        # DEPRECATED MMS mode
        elif my.mode == 'MMS':
            # run it inline
            trigger = MMSScriptTrigger()
            trigger.set_data(data)
            trigger.set_input(input_data)
            trigger.execute()
Example #37
0
    def add_user_info(my, login, password):
        ''' sets all the information about the user'''

        login_name = login.get_value("login")
        data = my.data


        # split up display name into first and last name
        display_name = data.get('display_name')
        if data.get('first_name') and data.get('last_name'):
            first_name = data.get('first_name')
            last_name = data.get('last_name')
        else:
            try:
                first_name, last_name = display_name.split(' ', 1)
                first_name = first_name.replace(",","")
                last_name = last_name.replace(",", "")
            except:
                first_name = display_name
                last_name = ''

        # alter so that it works for now
        data = {
            'first_name': first_name,
            'last_name': last_name,
            'email': data.get('email'),
            'phone_number': data.get('phone_number'),
            'license_type': data.get('license_type'),
            'display_name': data.get('display_name'),
            'department':   data.get('department')
        }

        from pyasm.search import Search
        columns = Search("sthpw/login").get_columns()

        for name, value in data.items():
            if value == None:
                continue
	    if value == 'None':
	        value = ''

            # only add values that are actually in the login object
            if name not in columns:
                print "WARNING: skipping [%s].  Does not exist in login" % name
                continue

            login.set_value(name, value)


        handle_groups = Config.get_value("active_directory", "handle_groups")
        if handle_groups == "false":
            my.add_default_group(login)
        else:
            # add all of the groups
            my.add_group_info(login)
Example #38
0
    def execute(my):
        my.section = None

        # make sure tmp config is unset.
        Config.unset_tmp_config()
        Config.reload_config()

        web = WebContainer.get_web()

        # read the current config file.

        # copy config to the path
        config_path = Config.get_config_path()
        if not os.path.exists(config_path):
            print "Installing default config file"

            dirname = os.path.dirname(config_path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)

            if os.name == 'nt':
                osname = 'win32'
            else:
                osname = 'linux'

            install_dir = Environment.get_install_dir()
            install_config_path = "%s/src/install/start/config/tactic_%s-conf.xml" % (
                install_dir, osname)

            shutil.copy(install_config_path, dirname)

        try:
            my.configure_db()
            my.configure_install()
            my.configure_mail_services()
            my.configure_gen_services()
            my.configure_asset_dir()
            my.configure_palette()
            my.configure_security()
        except Exception, e:
            raise TacticException('Error in [%s]: %s' %
                                  (my.section, e.__str__()))
Example #39
0
    def get_css_wdg(self):

        widget = Widget()

        web = WebContainer.get_web()
        context_url = web.get_context_url().to_string()

        skin = web.get_skin()

        version = Environment.get_release_version()

        # Bootstrap
        use_bootstrap = True
        if use_bootstrap:
            Container.append_seq(
                "Page:css",
                "%s/spt_js/bootstrap/css/bootstrap.min.css?ver=%s" %
                (context_url, version))

        # add the color wheel css
        Container.append_seq(
            "Page:css",
            "%s/spt_js/mooRainbow/Assets/mooRainbow.css" % context_url)
        Container.append_seq(
            "Page:css", "%s/spt_js/mooDialog/css/MooDialog.css" % context_url)
        Container.append_seq(
            "Page:css", "%s/spt_js/mooScrollable/Scrollable.css" % context_url)

        # first load context css
        Container.append_seq("Page:css", "%s/style/layout.css" % context_url)

        # TEST
        Container.append_seq("Page:css",
                             "%s/spt_js/video/video-js.css" % context_url)

        # get all of the registered css file
        css_files = Container.get_seq("Page:css")
        for css_file in css_files:
            widget.add(
                '<link rel="stylesheet" href="%s" type="text/css" />\n' %
                css_file)

        # custom js files to include
        includes = Config.get_value("install", "include_css")
        includes = includes.split(",")
        for include in includes:
            include = include.strip()
            if include:
                print("include: ", include)
                widget.add(
                    '<link rel="stylesheet" href="%s" type="text/css" />\n' %
                    include)

        return widget
Example #40
0
    def start_basic_tasks(my, scheduler):

        # close all extraneous database connections 15 minutes
        class DatabaseCloseTask(SchedulerTask):
            def execute(my):
                #print "Closing all connections"
                DbContainer.close_all_global_connections()

        task = DatabaseCloseTask()
        interval = 15 * 60
        scheduler.add_interval_task(task,
                                    interval=interval,
                                    mode='threaded',
                                    delay=60)

        # Kill cherrypy every interval.  This overcomes some of the memory
        # problems with long running Python processes.  In order to
        # use this properly, it is essential that a load balancer with
        # proper failover is used
        #
        class KillTacticTask(SchedulerTask):
            def execute(my):
                import cherrypy
                print
                print "Stopping TACTIC ..."
                print
                print " ... stopping Schduler"
                scheduler = Scheduler.get()
                scheduler.stop()
                print " ... stopping Cherrypy"
                cherrypy.engine.stop()
                cherrypy.engine.exit()
                print " ... closing DB connections"
                DbContainer.close_all_global_connections()
                print " ... kill current process"
                Common.kill()
                print "Done."

        from web_container import WebContainer

        if not WebContainer.is_dev_mode():
            task = KillTacticTask()
            config_delay = Config.get_value("services", "process_time_alive")
            if config_delay:
                import random
                # put in a randomizer so that not all processes die at once
                delay = int(config_delay)
                offset = random.random() * delay - delay / 2
                delay += offset
                seconds = int(delay * 60)
                print "Process will exit in [%s] seconds" % seconds
                scheduler.add_single_task(task,
                                          mode='sequential',
                                          delay=seconds)
Example #41
0
    def get_render_log_command(my):
        '''generate render log, mainly to signal a layer render is finished'''
        render_dir = my.render_context.get_render_dir()
        render_log = my.render_context.get_render_log()
        function = 'write_render_log'

        server = Config.get_value("install", "install_dir")
        jsfl_path = 'file:///%s/src/context/JSFL/load.jsfl' % server
        cmd = "fl.runScript( '%s', '%s', '%s', '%s')\n" \
                % (jsfl_path, function, render_dir, render_log)
        return cmd
Example #42
0
    def get_display(my):

        alias = my.kwargs.get("alias")

        my.rel_path = my.kwargs.get("rel_path")
        if not my.rel_path:
            from tactic_client_lib import TacticServerStub
            server = TacticServerStub.get(protocol='local')
            my.rel_path = server.get_doc_link(alias)

        if not my.rel_path or my.rel_path == 'none_found':
            #raise TacticException("Help alias [%s] does not exist" % alias)
            layout = DivWdg()
            layout.add(HelpCreateWdg(alias=alias))
            layout.add(HelpDocFilterWdg(alias='main'))
            return layout

        # special condition for plugins path
        if my.rel_path.startswith("/plugins/"):
            plugin_dir = Environment.get_plugin_dir()
            rel_path = my.rel_path.replace("/plugins/", "")
            path = "%s/%s" % (plugin_dir, rel_path)
        elif my.rel_path.startswith("/builtin_plugins/"):
            plugin_dir = Environment.get_builtin_plugin_dir()
            rel_path = my.rel_path.replace("/builtin_plugins/", "")
            path = "%s/%s" % (plugin_dir, rel_path)
        elif my.rel_path.startswith("/assets/"):
            asset_dir = Environment.get_asset_dir()
            rel_path = my.rel_path.replace("/assets/", "")
            path = "%s/%s" % (asset_dir, rel_path)
        else:

            # see if there is an override
            doc_dir = os.environ.get("TACTIC_DOC_DIR")
            if not doc_dir:
                doc_dir = Config.get_value("install", "doc_dir")
            if not doc_dir:
                install_dir = Environment.get_install_dir()
                doc_dir = "%s/doc" % install_dir

            path = "%s/%s" % (doc_dir, my.rel_path)

        html = []
        try:
            f = open(path, 'r')
            count = 0
            for line in f:
                line = my.filter_line(line, count)
                html.append(line)
                count += 1
            f.close()
        except Exception, e:
            print "Error processing: ", e
            html.append("Error processing document: %s<br/><br/>" % str(e))
Example #43
0
    def _test_autocreate(my):
        from pyasm.common import Config

        Config.set_value("security", "mode", "autocreate", no_exception=True)
        Config.set_value(
            "security",
            "authenticate_class",
            "pyasm.security.authenticate_test.AutocreateAuthenticate",
            no_exception=True)

        mode = Config.get_value("security", "mode", use_cache=False)
        my.assertEquals(mode, "autocreate")

        # verify that the user exists in the database
        search = Search("sthpw/login")
        search.add_filter("login", "foofoo")
        login = search.get_sobject()
        my.assertEquals(None, login)

        from pyasm.search import Transaction
        transaction = Transaction.get(create=True)
        transaction.start()

        my.security.login_user("foofoo", "wow")

        # verify that the user exists in the database
        search = Search("sthpw/login")
        search.add_filter("login", "foofoo")
        login = search.get_sobject()
        my.assertNotEquals(None, login)

        email = login.get_value("email")
        my.assertEquals("*****@*****.**", email)

        transaction.rollback()

        # after rollback, this user should not exist
        search = Search("sthpw/login")
        search.add_filter("login", "foofoo")
        login = search.get_sobject()
        my.assertEquals(None, login)
Example #44
0
def upgrade():
    print "Running upgrade on 'sthpw' database"

    install_dir = Environment.get_install_dir()
    python = Config.get_value("services", "python")
    if not python:
        python = "python"

    cmd = "%s %s/src/bin/upgrade_db.py -f -y -p sthpw" % (python, install_dir)
    print cmd

    os.system(cmd)
Example #45
0
    def install_win32_service(self):
        if os.name == 'nt':
            print("Installing win32 service.")
            # install the windows service
            current_dir = self.get_current_dir()
            service_path = '"%s/src/install/service/win32_service.py" install'%current_dir

            from pyasm.common import Config
            python_exe = Config.get_value("services", "python")
            if not python_exe:
                python_exe = "python3"
            os.system(python_exe + ' %s' %service_path)
Example #46
0
    def _test_cache(my):
        from pyasm.common import Config

        Config.set_value("security", "mode", "cache", no_exception=True)
        #Config.set_value("security", "authenticate_class", "pyasm.security.authenticate_test.AutocreateAuthenticate", no_exception=True)
        Config.set_value("security",
                         "authenticate_class",
                         "pyasm.security.mms_authenticate.MMSAuthenticate",
                         no_exception=True)
        mode = Config.get_value("security",
                                "authenticate_class",
                                use_cache=False)

        mode = Config.get_value("security", "mode", use_cache=False)
        my.assertEquals(mode, "cache")

        # verify that the user exists in the database
        search = Search("sthpw/login")
        search.add_filter("login", "foofoo")
        login = search.get_sobject()
        my.assertEquals(None, login)

        from pyasm.search import Transaction
        transaction = Transaction.get(create=True)
        transaction.start()

        my.security.login_user("foofoo", "wow")

        # verify that the user exists in the database
        search = Search("sthpw/login")
        search.add_filter("login", "foofoo")
        login = search.get_sobject()
        my.assertNotEquals(None, login)
Example #47
0
    def configure_asset_dir(my):
        my.section = 'Asset Management Setup'

        web = WebContainer.get_web()
        keys = web.get_form_keys()
        option_list = []
        for key in keys:
            if key.startswith('checkin/'):
                key = key.replace('checkin/', '')
                option_list.append(key)

        asset_dir = web.get_form_value("checkin/asset_base_dir")
        if asset_dir != None:
            if asset_dir and not os.path.exists(asset_dir):
                os.makedirs(asset_dir)
            Config.set_value("checkin", "asset_base_dir", asset_dir)

        if 'asset_base_dir' in option_list:
            option_list.remove('asset_base_dir')

        for item_dir in option_list:
            item_in_list = web.get_form_value('checkin/%s' % item_dir)
            if item_in_list:
                Config.set_value("checkin", '%s' % item_dir, item_in_list)
            else:
                Config.set_value("checkin", '%s' % item_dir, "")
Example #48
0
    def _do_login(self):

        allow_guest = Config.get_value("security", "allow_guest")
        if allow_guest == 'true':
            allow_guest = True
        else:
            allow_guest = False

        security = Environment.get_security()
        login = security.login_with_ticket(self.ticket, allow_guest=allow_guest)

        if not login:
            raise SecurityException("Cannot login with key: %s. Session may have expired." % self.ticket)
Example #49
0
    def get_display(my):

        web = WebContainer.get_web()
        context_url = web.get_context_url().to_string()
        js_url = "%s/javascript" % context_url
        spt_js_url = "%s/spt_js" % context_url  # adding new core "spt" javascript library folder

        version = Environment.get_release_version()

        # add some third party libraries
        third_party = js_includes.third_party
        security = Environment.get_security()

        for include in js_includes.third_party:
            Container.append_seq("Page:js", "%s/%s" % (spt_js_url, include))

        all_js_path = js_includes.get_compact_js_filepath()

        if os.path.exists(all_js_path):
            Container.append_seq(
                "Page:js",
                "%s/%s" % (context_url,
                           js_includes.get_compact_js_context_path_suffix()))
        else:
            for include in js_includes.legacy_core:
                Container.append_seq("Page:js", "%s/%s" % (js_url, include))

            for include in js_includes.spt_js:
                Container.append_seq("Page:js",
                                     "%s/%s" % (spt_js_url, include))

            for include in js_includes.legacy_app:
                Container.append_seq("Page:js", "%s/%s" % (js_url, include))

        # custom js files to include
        includes = Config.get_value("install", "include_js")
        includes = includes.split(",")
        for include in includes:
            include = include.strip()
            if include:
                print "include: ", include
                Container.append_seq("Page:js", include)

        widget = Widget()

        js_files = Container.get("Page:js")
        for js_file in js_files:
            widget.add('<script src="%s?ver=%s" ></script>\n' %
                       (js_file, version))

        return widget
Example #50
0
    def __init__(my, port=''):

        # It is possible on startup that the database is not running.
        from pyasm.common import Environment
        from pyasm.search import DbContainer, DatabaseException, Sql
        plugin_dir = Environment.get_plugin_dir()
        sys.path.insert(0, plugin_dir)

        try:
            sql = DbContainer.get("sthpw")
            if sql.get_database_type() != "MongoDb":
                # before batch, clean up the ticket with a NULL code
                if os.getenv('TACTIC_MODE') != 'production':
                    sql.do_update('DELETE from "ticket" where "code" is NULL;')
                else:
                    start_port = Config.get_value("services", "start_port")
                    if start_port:
                        start_port = int(start_port)
                    else:
                        start_port = 8081
                    if port and int(port) == start_port:
                        sql.do_update(
                            'DELETE from "ticket" where "code" is NULL;')
        except DatabaseException, e:
            # TODO: need to work on this
            print "ERROR: could not connect to [sthpw] database"
            #os.environ["TACTIC_CONFIG_PATH"] = Config.get_default_config_path()
            #Sql.set_default_vendor("Sqlite")

            Config.set_tmp_config()
            Config.reload_config()

            # try connecting again
            try:
                sql = DbContainer.get("sthpw")
            except:
                print "Could not connect to the database."
                raise
Example #51
0
    def _do_login(my):

        security = Environment.get_security()

        require_password = Config.get_value("security", "api_require_password")
        api_password = Config.get_value("security", "api_password")

        # the xmlrpc login can be overridden to not require a password
        if require_password == "false":
            security.login_user_without_password(my.login_name, expiry="NULL")
        elif api_password:
            if api_password == my.password:
                security.login_user_without_password(my.login_name, expiry="NULL")
            else:
                # if api password is incorrect, still try and authenticate with
                # user's password
                security.login_user(my.login_name, my.password, expiry="NULL")

        else:        
            security.login_user(my.login_name, my.password, expiry="NULL")

        if not security.is_logged_in():
            raise SecurityException("Cannot login as user: %s." % my.login_name)
Example #52
0
    def configure_install(my):
        my.section = 'Installation'
        web = WebContainer.get_web()

        default_project = web.get_form_value("install/default_project")
        tmp_dir = web.get_form_value("install/tmp_dir")

        if default_project:
            Config.set_value("install", "default_project", default_project)
        else:
            Config.remove("install", "default_project")

        if tmp_dir:
            Config.set_value("install", "tmp_dir", tmp_dir)
        else:
            Config.set_value("install", "tmp_dir", '')
Example #53
0
    def execute(my):

        # save prefix
        local_prefix = my.get_value("local_prefix")
        my.server_prefix = Config.get_value("install", "server")

        if not local_prefix and not my.server_prefix:
            raise TacticException("Cannot have empty local server prefix")

        if local_prefix and local_prefix != my.server_prefix:
            Config.set_value("install", "server", local_prefix)

            Config.save_config()

        my.project_code = my.get_value("project")
        if not my.project_code:
            my.project_code = Project.get_project_code()

        # create a share
        share = SearchType.create("sthpw/sync_server")
        my.handle_info(share)
        my.handle_sync_mode(share)

        share.commit()
Example #54
0
    def get_new_dirs(self, base):

        dirs = os.listdir(base)
        dir_set = set(dirs)

        # go through all the dirs and remove any that are from this server
        server_code = Config.get_value("install", "server")
        for dirname in dirs:
            if dirname.startswith("%sTRANSACTION" % server_code):
                dir_set.remove(dirname)
        dirs = list(dir_set)


        if self.last_dir_set != None:
            diff = dir_set.difference(self.last_dir_set)


            for dirname in diff.copy():

                # verify the all the files have arrived
                if not self.verify_dir("%s/%s" % (base, dirname)):
                    diff.remove(dirname)
                    dir_set.remove(dirname)

            if diff:
                print "... found new files: ", diff

            removed_diff = self.last_dir_set.difference(dir_set)


        else:
            diff = set()
            removed_diff = set()

        # use the original list to make sure that dirs aren't handled more
        # once
        self.last_dir_set = set(dirs)

        #print "time: ", time.time() - start
        if removed_diff:
            print "removed files: ", removed_diff

        diff = list(diff)
        diff.sort()

        return diff
Example #55
0
    def get_sqlite_wdg(my):
        div = DivWdg()
        div.add_class("spt_db_options")
        div.add_attr("spt_vendor", "Sqlite")
        div.add_style("padding: 20px")

        div.add("Database Folder: ")
        text = TextInputWdg(name="database/sqlite_db_dir")
        div.add(text)

        db_dir = Config.get_value("database", "sqlite_db_dir")
        if not db_dir:
            data_dir = Environment.get_data_dir()
            db_dir = "%s/db" % data_dir

        text.set_value(db_dir)

        return div
Example #56
0
    def upgrade(my):
        project_code = my.kwargs.get('project_code')
        # run the upgrade script (this has to be done in a separate
        # process due to possible sql errors in a transaction
        install_dir = Environment.get_install_dir()
        python = Config.get_value("services", "python")
        if not python:
            python = "python"

        impl = Project.get_database_impl()

        from pyasm.search.upgrade import Upgrade
        version = Environment.get_release_version()
        version.replace('.', '_')
        upgrade = Upgrade(version,
                          is_forced=True,
                          project_code=project_code,
                          quiet=True)
        upgrade.execute()
Example #57
0
    def get_md5(path):
        '''get md5 checksum'''
        py_exec = Config.get_value("services", "python")
        if not py_exec:
            py_exec = "python"

        if isinstance(path, unicode):
            path = path.encode('utf-8')
        popen =  subprocess.Popen([py_exec, '%s/src/bin/get_md5.py'%Environment.get_install_dir(), path], shell=False, stdout=subprocess.PIPE)
        popen.wait()
        output = ''
        value = popen.communicate()
        if value:
            output = value[0].strip()
            if not output:
                err = value[1]
                print err
            
        return output
Example #58
0
                def execute(my):
                    # check to see the status of this job
                    """
                    job = my.kwargs.get('job')
                    job_code = job.get_code()
                    search = Search("sthpw/queue")
                    search.add_filter("code", job_code)
                    my.kwargs['job'] = search.get_sobject()

                    if not job:
                        print "Cancelling ..."
                        return

                    state = job.get_value("state")
                    if state == "cancel":
                        print "Cancelling 2 ...."
                        return
                    """

                    subprocess_kwargs = {
                        'login': login,
                        'project_code': project_code,
                        'command': command,
                        'kwargs': kwargs
                    }
                    subprocess_kwargs_str = jsondumps(subprocess_kwargs)
                    install_dir = Environment.get_install_dir()
                    python = Config.get_value("services", "python")
                    if not python:
                        python = 'python'
                    args = [
                        '%s' % python,
                        '%s/src/tactic/command/queue.py' % install_dir
                    ]
                    args.append(subprocess_kwargs_str)

                    import subprocess
                    p = subprocess.Popen(args)

                    DbContainer.close_thread_sql()

                    return
Example #59
0
 def use_applet(self):
     # determines whether the applet should be used for local file
     # operations
     use_applet = Config.get_value("checkin", "use_applet")
     if use_applet in ['false', False]:
         use_applet = False
     elif use_applet in ['true', True]:
         use_applet = True
     else:
         browser = self.get_browser()
         # TEAM can always use the applet
         if browser == "Qt":
             use_applet = True
         else:
             # Otherwise we need a way to detect the java applet reliably
             if Container.get_dict("JSLibraries", "spt_applet"):
                 use_applet = True
             else:
                 use_applet = False
     return use_applet
Example #60
0
    def get_default(my, dirs):
        # add <project_code>/<table>/<context>
        dirs = my.get_sobject_base(dirs)

        if not Config.get_value("checkin", "default_naming_version") == "1":
            if my.sobject.has_value("code"):
                code = my.sobject.get_value("code")
                if code:
                    dirs.append(code)
            else:
                sobj_id = my.sobject.get_id()
                if sobj_id:
                    dirs.append(str(sobj_id))

            # add in the context
            process = my.snapshot.get_value("process")
            if process:
                dirs.append(process)

        return dirs