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")
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()
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
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
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"
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)
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()
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()
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)
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", "")
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", "")
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()
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
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, "")
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)
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()
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, "")
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
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")
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)
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
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
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
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)
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
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"
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()
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
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, "")
def get_default_groups(my): groups = Config.get_value("active_directory", "default_groups") if not groups: groups = [] else: groups = groups.split("|") return groups
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
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
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()
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)
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__()))
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
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)
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
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))
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)
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)
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)
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)
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, "")
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)
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
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
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)
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", '')
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()
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
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
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()
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
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
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
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