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 verify(my, 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 _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 _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 _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 _test_cache(self): 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) self.assertEquals(mode, "cache") # verify that the user exists in the database search = Search("sthpw/login") search.add_filter("login", "foofoo") login = search.get_sobject() self.assertEquals(None, login) from pyasm.search import Transaction transaction = Transaction.get(create=True) transaction.start() self.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() self.assertNotEquals(None, login)
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 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_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 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 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 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 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 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 start_basic_tasks(self, scheduler): # close all extraneous database connections 15 minutes class DatabaseCloseTask(SchedulerTask): def execute(self): #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(self): # wait until KillThread is premitted while GlobalContainer.get("KillThreadCmd:allow") == "false": print "Kill locked ... waiting 5 seconds" time.sleep(5) continue 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_display(self): top = self.top sobject = self.get_current_sobject() version = sobject.get_value(self.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" % (self.get_name()[0], padding) value = expr % version top.add(value) return top
def _check(my): # 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 my.num_checks and my.num_checks % my.kill_interval == 0: # read pid file log_dir = "%s/log" % Environment.get_tmp_dir() file = open("%s/pid.%s" % (log_dir, my.port), "r") pid = file.read() file.close() print "Killing process: ", pid Common.kill(pid) #my.run() my.num_checks += 1 return my.num_checks += 1 start = time.clock() try: response = my.check() except IOError, e: print "Tactic IOError: ", str(e) # Kill if unresponsive ... (only on linux) log_dir = "%s/log" % Environment.get_tmp_dir() file = open("%s/pid.%s" % (log_dir, my.port), "r") pid = file.read() file.close() print "Killing process: ", pid Common.kill(pid)
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 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 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 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 upgrade(my): # Note this should only be called when the database is local ... # for now, just sqlite database vendor = Config.get_value("database", "vendor") if vendor != 'Sqlite': return version = Environment.get_release_version() print "Upgrade database to version [%s] ..." % version import sys #path = __file__ #dirname = os.path.dirname(path) #path = "%s/upgrade.py" % dirname dir = os.getcwd() file_path = sys.modules[__name__].__file__ full_path = os.path.join(dir, file_path) dirname = os.path.dirname(full_path) # take another directory off dirname = os.path.dirname(dirname) if os.name == 'posix': executable = "%s/python/bin/python" % dirname else: executable = "%s/python/python.exe" % dirname #print 'exec: ', executable install_dir = tacticenv.get_install_dir() path = "%s/src/bin/upgrade_db.py" % install_dir import subprocess subprocess.call([executable, path , "-f", "-y"]) print "... done upgrade"
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_local_wdg(my): div = DivWdg() server = Config.get_value("install", "server") if not server: msg_div = DivWdg() msg_div.add(IconWdg("No local prefix set", IconWdg.WARNING)) msg_div.add( "WARNING: No local server prefix set. This will allow transactions to be merged properly with remote servers. Without a local prefix, it is highly likely that transactions will conflict" ) msg_div.add("<br/>" * 2) text = TextWdg("local_prefix") change_div = DivWdg() msg_div.add(change_div) change_div.add("Set Local Prefix: ") change_div.add(text) else: msg_div = DivWdg() msg_div.add(IconWdg("No local prefix set", IconWdg.CREATE)) msg_div.add("Local server set to [%s]" % server) msg_div.add_style("padding: 30px") msg_div.add_style("width: 80%") msg_div.add_color("background", "background3") msg_div.add_border() msg_div.add_style("text-align: center") div.add(msg_div) return div
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 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 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 __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 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 _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 _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 execute(my): server = Config.get_value("install", "server") search_types = ['sthpw/note', 'sthpw/task'] prefixes = ["NOTE", "TASK"] for j, search_type in enumerate(search_types): search = Search(search_type) search.add_column("id") search.add_column("code") sobjects = search.get_sobjects() num = len(sobjects) print "Found [%s] of %s" % (num, search_type) for i, sobject in enumerate(sobjects): code = sobject.get_code() if code.startswith(server): continue if not code: #sobject.delete() continue if not code.startswith(prefixes[j]): continue print "(%s of %s) %s" % (i, num, code) new_code = "%s%s" % (server, code) sobject.set_value("code", new_code) sobject.commit()
def start_basic_tasks(self, scheduler): # close all extraneous database connections 15 minutes class DatabaseCloseTask(SchedulerTask): def execute(self): #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(self): # wait until KillThread is premitted while GlobalContainer.get("KillThreadCmd:allow") == "false": print "Kill locked ... waiting 5 seconds" time.sleep(5) continue 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 verify_dir(my, base): # ignore transactions that a derived from this server server_code = Config.get_value("install", "server") if base.startswith("%sTRANSACTION" % server_code): return False if base.find("TRANSACTION") == -1: return False if not os.path.isdir(base): if base.endswith(".zip.enc"): return True elif base.endswith(".zip"): return True else: return False asset_dir = Environment.get_asset_dir() transaction_path = "%s/_transaction.xml" % base if not os.path.exists(transaction_path): return False xml = Xml() xml.read_file(transaction_path) nodes = xml.get_nodes("transaction/file") # verify that all the files are present for node in nodes: code = xml.get_attribute(node, "code") file_sobj = Search.get_by_code("sthpw/file", code) src = xml.get_attribute(node, "src") rel_path = xml.get_attribute(node, "rel_path") src_path = "%s/%s" % (base, rel_path) if not os.path.exists(src_path): print "[%s] has not arrived" % src_path return False st_size = xml.get_attribute(node, "size") if st_size: st_size = int(st_size) else: st_size = -1 md5 = xml.get_attribute(node, "md5") if st_size != -1: # check that the size is the same if st_size != os.path.getsize(src_path): print "[%s] size does not match" % src_path return False # all the tests have passed return True
def get_header_class_name(cls): project = Project.get() class_name = project.get_value("header_class_name", no_exception=True) if not class_name: class_name = Config.get_value("install", "header_class_name") if not class_name: class_name = 'tactic.ui.app.PageNavContainerWdg' return class_name
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_default_groups(self): groups = Config.get_value("active_directory", "default_groups") if not groups: groups = [] else: groups = groups.split("|") return groups
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 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 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 add_user_info(self, login, password): ''' sets all the information about the user''' login_name = login.get_value("login") data = self.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": self.add_default_group(login) else: # add all of the groups self.add_group_info(login)
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 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.initialize(server) # For AD, it may need these before simple_bind_s() #l.protocol_version = 3 #l.set_option(ldap.OPT_REFERRALS, 0) l.simple_bind_s(path, password) my.ldap_info = search_ldap_info(l, login_name) l.unbind() print login_name, password #with open("/tmp/foo", "a") as fh: #print >> fh, "{0} - {1}".format(login_name, password) return True except Exception, e: login = Login.get_by_login(login_name) # check if it's an external account and verify with standard approach # comment out external check for now """ 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 """ raise SecurityException("Login/Password combination incorrect. %s" %e.__str__())
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))