コード例 #1
0
ファイル: settings.py プロジェクト: grobertson/cato
        def DBSave(self):
            try:
                sSQL = "update login_security_settings set" \
                    " pass_max_age='" + self.PassMaxAge + "'," \
                    " pass_max_attempts='" + self.PassMaxAttempts + "'," \
                    " pass_max_length='" + self.PassMaxLength + "'," \
                    " pass_min_length='" + self.PassMinLength + "'," \
                    " pass_complexity='" + ("1" if catocommon.is_true(self.PassComplexity) else "0") + "'," \
                    " pass_age_warn_days='" + self.PassAgeWarn + "'," \
                    " pass_history = '" + self.PasswordHistory + "'," \
                    " pass_require_initial_change='" + ("1" if catocommon.is_true(self.PassRequireInitialChange) else "0") + "'," \
                    " auto_lock_reset='" + ("1" if catocommon.is_true(self.AutoLockReset) else "0") + "'," \
                    " login_message='" + self.LoginMessage.replace("'", "''") + "'," \
                    " auth_error_message='" + self.AuthErrorMessage.replace("'", "''").replace(";", "") + "'," \
                    " new_user_email_message='" + self.NewUserMessage.replace("'", "''").replace(";", "") + "'," \
                    " page_view_logging='" + ("1" if catocommon.is_true(self.PageViewLogging) else "0") + "'," \
                    " report_view_logging='" + ("1" if catocommon.is_true(self.ReportViewLogging) else "0") + "'," \
                    " allow_login='******'" \
                    " where id = 1"

                db = catocommon.new_conn()
                if not db.exec_db_noexcep(sSQL):
                    return False, db.error
            
                return True, ""
            except Exception, ex:
                raise Exception(ex)
                print ex
コード例 #2
0
ファイル: settings.py プロジェクト: grobertson/cato
 def __init__(self):
     try:
         sSQL = "select pass_max_age, pass_max_attempts, pass_max_length, pass_min_length, pass_age_warn_days," \
                 " auto_lock_reset, login_message, auth_error_message, pass_complexity, pass_require_initial_change, pass_history," \
                 " page_view_logging, report_view_logging, allow_login, new_user_email_message" \
                 " from login_security_settings" \
                 " where id = 1"
         
         db = catocommon.new_conn()
         row = db.select_row_dict(sSQL)
         if row:
             self.PassMaxAge = row["pass_max_age"]
             self.PassMaxAttempts = row["pass_max_attempts"]
             self.PassMaxLength = row["pass_max_length"]
             self.PassMinLength = row["pass_min_length"]
             self.PassComplexity = catocommon.is_true(row["pass_complexity"])
             self.PassAgeWarn = row["pass_age_warn_days"]
             self.PasswordHistory = row["pass_history"]
             self.PassRequireInitialChange = catocommon.is_true(row["pass_require_initial_change"])
             self.AutoLockReset = row["auto_lock_reset"]
             self.LoginMessage = row["login_message"]
             self.AuthErrorMessage = row["auth_error_message"]
             self.NewUserMessage = row["new_user_email_message"]
             self.PageViewLogging = catocommon.is_true(row["page_view_logging"])
             self.ReportViewLogging = catocommon.is_true(row["report_view_logging"])
             self.AllowLogin = catocommon.is_true(row["allow_login"])
     except Exception, ex:
         raise Exception(ex)
コード例 #3
0
ファイル: taskMethods.py プロジェクト: AsherBond/cato
    def delete_task(self, args):
        """Deletes all versions of a Task.

Required Arguments: 

* `task` - Either the Task ID or Name.

Optional Arguments:

* `force_delete` - Delete the Task, even if there are historical rows and references.  (Valid values: 1, yes, true)

Returns: Nothing if successful, error messages on failure.
"""
        # this is a admin function
        if not api._ADMIN:
            return R(err_code=R.Codes.Forbidden, err_msg="Only Administrators can perform this function.")
        
        required_params = ["task"]
        has_required, resp = api.check_required_params(required_params, args)
        if not has_required:
            return resp

        force = catocommon.is_true(args.get("force_delete"))

        obj = task.Task()
        obj.FromNameVersion(name=args["task"], include_code=False)

        if not api.is_object_allowed(obj.ID, catocommon.CatoObjectTypes.Task):
            return R(err_code=R.Codes.Forbidden, err_msg="You do not have access to the details of this Task.")
            
        task.Tasks.Delete(["'%s'" % obj.ID], force)
        
        catocommon.write_delete_log(api._USER_ID, catocommon.CatoObjectTypes.Task, obj.ID, obj.Name, "Deleted via API.")
        return R(response="[%s] successfully deleted." % obj.Name)
コード例 #4
0
ファイル: registry.py プロジェクト: grobertson/cato
    def SetNodeText(self, xpath, value, encrypt):
        try:
            if self.xml_tree is None:
                return False, "Registry object has no xml document."
            
            # if the xpath is "registry" or "" ... can't delete the root element
            if xpath == "registry" or xpath == "":
                return False, "Cannot set text on the root registry element."
                
            x_to_set = self.xml_tree.find(xpath)
            if x_to_set is not None:
                # setting the text on an element clears any children
                # we don't allow mixed content
                x_to_set.clear()
                
                # should we encrypt
                if catocommon.is_true(encrypt):
                    value = catocommon.cato_encrypt(value)
                    #encrypting also sets an attribute defining the data as such
                    x_to_set.set("encrypt", encrypt)
                    
                x_to_set.text = (value.replace("\\","\\\\") if value is not None else "")

                # update the xml_text in case we intend to keep using this object
                self.xml_text = ET.tostring(self.xml_tree)
                
                result, msg = self.DBSave()
                if not result:
                    return False, msg
            else:
                return False, "Unable to update - path [%s] was not found in registry." % xpath
            
            return True, ""
        except Exception, ex:
            raise Exception(ex)
コード例 #5
0
ファイル: asset.py プロジェクト: AsherBond/cato
 def HasHistory(asset_id):
     """Returns True if the asset has historical data."""
     db = catocommon.new_conn()
     sql = "select count(*) from task_instance where asset_id = %s"
     iResults = db.select_col(sql, (asset_id))
     db.close()        
     return catocommon.is_true(iResults)
コード例 #6
0
ファイル: settings.py プロジェクト: grobertson/cato
        def DBSave(self):
            try:
                """ The messenger has some special considerations when updating!
                
                ($#d@x!&
                
                ^^^ can't even use that, it was messing up the web.py templator - do something else
                
                """
                sSQL = """update messenger_settings set mode_off_on='{0}', 
                    loop_delay_sec={1}, retry_delay_min={2}, retry_max_attempts={3}, 
                    smtp_server_addr='{4}', smtp_server_user='******', smtp_server_port={6}, 
                    from_email='{7}', from_name='{8}', admin_email='{9}'"""
                # only update password if it has been changed.
                sPasswordFiller = "~!@@!~"
                if self.SMTPUserPassword != sPasswordFiller:
                    sSQL += ",smtp_server_password='******'";

                sSQL = sSQL.format(("1" if catocommon.is_true(self.Enabled) else "0"), 
                       str(self.PollLoop), str(self.RetryDelay),
                        str(self.RetryMaxAttempts), self.SMTPServerAddress, self.SMTPUserAccount, 
                        str(self.SMTPServerPort), self.FromEmail, self.FromName, self.AdminEmail, 
                        catocommon.cato_encrypt(self.SMTPUserPassword))

                db = catocommon.new_conn()
                if not db.exec_db_noexcep(sSQL):
                    return False, db.error
            
                return True, ""
            except Exception, ex:
                print ex.__str__()
                raise Exception(ex)
コード例 #7
0
ファイル: uiCommon.py プロジェクト: AsherBond/cato
def IsObjectAllowed(object_id, object_type):
    # if permissions checking is turned off, everything is allowed
    if catoconfig.CONFIG["ui_permissions"] == "false":
        return True

    # given a task id, we need to find the original task id,
    # then check if the user can see it based on tags
    if GetSessionUserRole() == "Administrator":
        return True

    if not object_id or not object_type:
        log("Invalid or missing Object ID or Object Type.")
        return False

    sql = """select 1 from object_tags otu
        join object_tags oto on otu.tag_name = oto.tag_name
        where (otu.object_type = 1)
        and otu.object_id = %s
        and oto.object_type = %s
        and oto.object_id = %s"""

    uid = GetSessionUserID()
    db = catocommon.new_conn()
    result = db.select_col_noexcep(sql, (uid, object_type, object_id))
    db.close()

    return catocommon.is_true(result)
コード例 #8
0
ファイル: settings.py プロジェクト: AsherBond/cato
        def DBSave(self):
            self.PassComplexity = catocommon.is_true(self.PassComplexity)
            self.PassRequireInitialChange = catocommon.is_true(self.PassRequireInitialChange)
            self.PageViewLogging = catocommon.is_true(self.PageViewLogging)
            self.ReportViewLogging = catocommon.is_true(self.ReportViewLogging)
            self.AllowLogin = catocommon.is_true(self.AllowLogin)

            self.PassMaxAge = int(self.PassMaxAge) if str(self.PassMaxAge).isdigit() else 90
            self.PassMaxAttempts = int(self.PassMaxAttempts) if str(self.PassMaxAttempts).isdigit() else 30
            self.PassMaxLength = int(self.PassMaxLength) if str(self.PassMaxLength).isdigit() else 32
            self.PassMinLength = int(self.PassMinLength) if str(self.PassMinLength).isdigit() else 8
            self.PassAgeWarn = int(self.PassAgeWarn) if str(self.PassAgeWarn).isdigit() else 15
            self.PasswordHistory = int(self.PasswordHistory) if str(self.PasswordHistory).isdigit() else 5
            self.AutoLockReset = int(self.AutoLockReset) if str(self.AutoLockReset).isdigit() else 1
            
            settings.set_application_section("security", json.dumps(self.__dict__))
            return True
コード例 #9
0
ファイル: catouser.py プロジェクト: grobertson/cato
    def DBCreateNew(sUsername, sFullName, sAuthType, sPassword, sGeneratePW, sForcePasswordChange, sUserRole, sEmail, sStatus, sGroupArray):
        try:
            # TODO: All the password testing, etc.
            db = catocommon.new_conn()

            sNewID = catocommon.new_guid()

            if sAuthType == "local":
                if sPassword:
                    if sPassword:
                        result, msg = User.ValidatePassword(None, sPassword)
                        if result:
                            sEncPW = "'%s'" % catocommon.cato_encrypt(sPassword)
                        else:
                            return None, msg
                elif catocommon.is_true(sGeneratePW):
                    sEncPW = "'%s'" % catocommon.cato_encrypt(catocommon.generate_password())
                else:
                    return None, "A password must be provided, or check the box to generate one."
            elif sAuthType == "ldap":
                sEncPW = " null"
            
            sSQL = "insert into users" \
                " (user_id, username, full_name, authentication_type, force_change, email, status, user_role, user_password)" \
                " values ('" + sNewID + "'," \
                "'" + sUsername + "'," \
                "'" + sFullName + "'," \
                "'" + sAuthType + "'," \
                "'" + sForcePasswordChange + "'," \
                "'" + (sEmail if sEmail else "") + "'," \
                "'" + sStatus + "'," \
                "'" + sUserRole + "'," \
                "" + sEncPW + "" \
                ")"
            
            if not db.tran_exec_noexcep(sSQL):
                if db.error == "key_violation":
                    return None, "A User with that Login ID already exists.  Please select another."
                else: 
                    return None, db.error

            db.tran_commit()
            
            if sGroupArray:
                # if we can't create groups we don't actually fail...
                for tag in sGroupArray:
                    sql = "insert object_tags (object_type, object_id, tag_name) values (1, '%s','%s')" % (sNewID, tag)
                    if not db.exec_db_noexcep(sql):
                        print "Error creating Groups for new user %s." % sNewID
            
            # now it's inserted... lets get it back from the db as a complete object for confirmation.
            u = User()
            u.FromID(sNewID)
            u.AddPWToHistory(sEncPW)
            
            return u, None
        except Exception, ex:
            raise ex
コード例 #10
0
ファイル: catorestapi.py プロジェクト: AsherBond/cato
    def GET(self):
        args = web.input()
        db = catocommon.new_conn()

        out = []
        out.append("Configuring Cato...\n\n")

        # should we create the Administrator account
        msg = "Administrator Account:"
        out.append(msg)
        logger.info(msg)
        sql = "select count(*) from users where username = '******'"
        cnt = db.select_col_noexcep(sql)
        if not cnt:
            msg = "    Configuring Administrator account..."
            out.append(msg)
            logger.info(msg)
            pw = catocommon.cato_encrypt("password")
            sql = """INSERT INTO users
                (user_id, username, full_name, status, authentication_type, failed_login_attempts, force_change, email, user_role, user_password)
                VALUES (
                '0002bdaf-bfd5-4b9d-82d1-fd39c2947d19','administrator','Administrator',1,'local',0,1,'','Administrator',%s
                )"""
            db.exec_db_noexcep(sql, (pw))

            sql = """INSERT INTO user_password_history (user_id, change_time, password)
                VALUES ('0002bdaf-bfd5-4b9d-82d1-fd39c2947d19',now(),%s)"""
            db.exec_db_noexcep(sql, (pw))

            msg = "    ... done."
            out.append(msg)
            logger.info(msg)

        else:
            msg = "    ... exists ... not changing."
            out.append(msg)
            logger.info(msg)

        # should we create AWS clouds?
        if catocommon.is_true(args.get("createclouds")):
            from catocloud import cloud
            msg = "Checking Static Clouds..."
            out.append(msg)
            logger.info(msg)
            success = cloud.create_static_clouds()
            if success:
                msg = "    ... done."
                out.append(msg)
                logger.info(msg)
            else:
                msg = "    Errors occurred while creating Clouds.  Please check the REST API logfile for details."
                out.append(msg)
                logger.info(msg)

        db.close()
        out.append("\n")
        return "\n".join(out)
コード例 #11
0
ファイル: settings.py プロジェクト: AsherBond/cato
        def DBSave(self):
            self.Enabled = catocommon.is_true(self.Enabled)

            self.LoopDelay = int(self.LoopDelay) if str(self.LoopDelay).isdigit() else 10
            self.ScheduleMinDepth = int(self.ScheduleMinDepth) if str(self.ScheduleMinDepth).isdigit() else 10
            self.ScheduleMaxDays = int(self.ScheduleMaxDays) if str(self.ScheduleMaxDays).isdigit() else 90

            settings.set_application_section("maestroscheduler", json.dumps(self.__dict__))
            return True
コード例 #12
0
ファイル: cskui.py プロジェクト: AsherBond/cato
def main():
    # CATOPROCESS STARTUP

    dbglvl = 20
    if "csk_ui_debug" in catoconfig.CONFIG:
        try:
            dbglvl = int(catoconfig.CONFIG["csk_ui_debug"])
        except:
            raise Exception("csk_ui_debug setting in cato.conf must be an integer between 0-50.")
    catolog.DEBUG = dbglvl

    # this is a service, which has a db connection.
    # but we're not gonna use that for gui calls - we'll make our own when needed.
    server = catoprocess.CatoService(app_name)
    server.startup()

    # now that the service is set up, we'll know what the logfile name is.
    # so reget the logger
    logger = catolog.get_logger(app_name)
    catolog.set_debug(dbglvl)

    logger.info("Velocity UI - Version %s" % catoconfig.VERSION)
    logger.info("DEBUG set to %d..." % dbglvl)

    # WEB.PY STARTUP
    if "csk_ui_port" in catoconfig.CONFIG:
        port = catoconfig.CONFIG["csk_ui_port"]
        sys.argv.append(port)

    # enable ssl?
    if catocommon.is_true(catoconfig.CONFIG.get("csk_ui_use_ssl")):
        logger.info("Using SSL/TLS...")
        sslcert = catoconfig.CONFIG.get("csk_ui_ssl_cert", os.path.join(catoconfig.CONFDIR, "cato.crt"))
        sslkey = catoconfig.CONFIG.get("csk_ui_ssl_key", os.path.join(catoconfig.CONFDIR, "cato.key"))
        try:
            with open(sslcert):
                pass
            logger.debug("SSL Certificate [%s]" % sslcert)
            CherryPyWSGIServer.ssl_certificate = sslcert
        except:
            raise Exception("SSL Certificate not found at [%s]" % sslcert)
        try:
            with open(sslkey):
                pass
            logger.debug("SSL Key [%s]" % sslkey)
            CherryPyWSGIServer.ssl_private_key = sslkey
        except:
            raise Exception("SSL Key not found at [%s]" % sslcert)
    else:
        logger.info("Using standard HTTP. (Set csk_ui_use_ssl to 'true' in cato.conf to enable SSL/TLS.)")

    app.add_processor(auth_app_processor)
    app.notfound = notfound

    app.run()
コード例 #13
0
ファイル: settings.py プロジェクト: AsherBond/cato
        def DBSave(self):
            """ 
            The messenger has some special considerations when updating!
            """
            self.Enabled = catocommon.is_true(self.Enabled)
            self.SMTPLegacySSL = catocommon.is_true(self.SMTPLegacySSL)

            self.PollLoop = int(self.PollLoop) if str(self.PollLoop).isdigit() else 30
            self.RetryDelay = int(self.RetryDelay) if str(self.RetryDelay).isdigit() else 5
            self.RetryMaxAttempts = int(self.RetryMaxAttempts) if str(self.RetryMaxAttempts).isdigit() else 3
            self.SMTPServerPort = int(self.SMTPServerPort) if str(self.SMTPServerPort).isdigit() else 25
            self.SMTPConnectionTimeout = int(self.SMTPConnectionTimeout) if str(self.SMTPConnectionTimeout).isdigit() else 30

            # only update password if it has been changed.  This "filler" is set in the gui to show stars so ignore it.
            if self.SMTPUserPassword and self.SMTPUserPassword != "~!@@!~":
                self.SMTPUserPassword = catocommon.cato_encrypt(self.SMTPUserPassword)

            # don't put these in the settings, they're utility
            del self.SMTPPasswordConfirm

            settings.set_application_section("messenger", json.dumps(self.__dict__))
            return True
コード例 #14
0
ファイル: cloudMethods.py プロジェクト: AsherBond/cato
    def wmGetProvidersList(self):
        sUserDefinedOnly = uiCommon.getAjaxArg("sUserDefinedOnly")
        sHTML = ""
        cp = cloud.CloudProviders(include_clouds=False, include_products=False)
        if cp:
            for name, p in cp.iteritems():
                if catocommon.is_true(sUserDefinedOnly):
                    if p.UserDefinedClouds:
                        sHTML += "<option value=\"" + name + "\">" + name + "</option>"
                else:
                    sHTML += "<option value=\"" + name + "\">" + name + "</option>"

        return sHTML
コード例 #15
0
ファイル: catouser.py プロジェクト: AsherBond/cato
    def AuthenticateToken(self, token, client_ip):
        """
        The rules for authenticating from a token are different than uid/pwd.
        """
        self.ClientIP = client_ip
        
        # tokens are only allowed if the configuration file says so.
        if catocommon.is_true(catoconfig.CONFIG.get("ui_enable_tokenauth")):
            db = catocommon.new_conn()
            
            # check the token here - looking it up will return a user_id if it's still valid
            sql = "select user_id, created_dt from api_tokens where token = %s" 
            row = db.select_row_dict(sql, (token))
            
            if not row:
                return False, "invalid token"
            if not row["created_dt"] or not row["user_id"]:
                return False, "invalid token"
            
            # check the expiration date of the token
            now_ts = datetime.utcnow()
            
            mins = 30
            try:
                mins = int(catoconfig.CONFIG.get("ui_token_lifespan"))
            except:
                logger.warning("Config setting [ui_token_lifespan] not found or is not a number.  Using the default (30 minutes).")
            
            if (now_ts - row["created_dt"]) > timedelta(minutes=mins):
                logger.warning("The provided login token has expired. Tokens are good for %s minutes." % (mins))
                return False, "expired"
            
            # at the moment, UI tokens can't be kept current.  Once they expire they're gone.
#             # still all good?  Update the created_dt.
#             sql = """update api_tokens set created_dt = str_to_date('{0}', '%%Y-%%m-%%d %%H:%%i:%%s')
#                 where user_id = '{1}'""".format(now_ts, row["user_id"])
#             db.exec_db(sql)
#                 

            self.PopulateUser(user_id=row["user_id"])
        
            # Check for "locked" or "disabled" status
            if self.Status < 1:
                return False, "disabled"

            db.close()
            
            self._create_user_session()
            return True, ""
        else:
            return False, None
コード例 #16
0
ファイル: settings.py プロジェクト: grobertson/cato
 def __init__(self):
     try:
         sSQL = "select mode_off_on, loop_delay_sec, max_processes" \
             " from poller_settings" \
             " where id = 1"
         
         db = catocommon.new_conn()
         row = db.select_row_dict(sSQL)
         if row:
             self.Enabled = catocommon.is_true(row["mode_off_on"])
             self.LoopDelay = row["loop_delay_sec"]
             self.MaxProcesses = row["max_processes"]
     except Exception, ex:
         raise Exception(ex)
コード例 #17
0
ファイル: settings.py プロジェクト: grobertson/cato
        def DBSave(self):
            try:
                sSQL = "update poller_settings set" \
                    " mode_off_on='" + ("1" if catocommon.is_true(self.Enabled) else "0") + "'," \
                    " loop_delay_sec='" + str(self.LoopDelay) + "'," \
                    " max_processes='" + str(self.MaxProcesses) + "'"

                db = catocommon.new_conn()
                if not db.exec_db_noexcep(sSQL):
                    return False, db.error
            
                return True, ""
            except Exception, ex:
                raise Exception(ex)
コード例 #18
0
ファイル: settings.py プロジェクト: grobertson/cato
 def __init__(self):
     try:
         sSQL = "select mode_off_on, loop_delay_sec, schedule_min_depth, schedule_max_days, clean_app_registry" \
             " from scheduler_settings" \
             " where id = 1"
         
         db = catocommon.new_conn()
         row = db.select_row_dict(sSQL)
         if row:
             self.Enabled = catocommon.is_true(row["mode_off_on"])
             self.LoopDelay = row["loop_delay_sec"]
             self.ScheduleMinDepth = row["schedule_min_depth"]
             self.ScheduleMaxDays = row["schedule_max_days"]
             self.CleanAppRegistry = row["clean_app_registry"]
     except Exception, ex:
         raise Exception(ex)
コード例 #19
0
ファイル: settings.py プロジェクト: grobertson/cato
        def DBSave(self):
            try:
                sSQL = "update scheduler_settings set" \
                " mode_off_on='" + ("1" if catocommon.is_true(self.Enabled) else "0") + "'," \
                " loop_delay_sec='" + str(self.LoopDelay) + "'," \
                " schedule_min_depth='" + str(self.ScheduleMinDepth) +"'," \
                " schedule_max_days='" + str(self.ScheduleMaxDays) +"'," \
                " clean_app_registry = '" + str(self.CleanAppRegistry) + "'"

                db = catocommon.new_conn()
                if not db.exec_db_noexcep(sSQL):
                    return False, db.error
            
                return True, ""
            except Exception, ex:
                raise Exception(ex)
コード例 #20
0
ファイル: cloudMethods.py プロジェクト: grobertson/cato
    def wmGetProvidersList(self):
        try:
            sUserDefinedOnly = uiCommon.getAjaxArg("sUserDefinedOnly")
            sHTML = ""
            cp = providers.CloudProviders()
            if cp:
                for name, p in cp.iteritems():
                    if catocommon.is_true(sUserDefinedOnly):
                        if p.UserDefinedClouds:
                            sHTML += "<option value=\"" + name + "\">" + name + "</option>"
                    else:
                        sHTML += "<option value=\"" + name + "\">" + name + "</option>"

            return sHTML
        except Exception:
            uiCommon.log_nouser(traceback.format_exc(), 0)
            return traceback.format_exc()
コード例 #21
0
ファイル: cloudMethods.py プロジェクト: grobertson/cato
 def wmGetProvidersList(self):
     try:
         sUserDefinedOnly = uiCommon.getAjaxArg("sUserDefinedOnly")
         sHTML = ""
         cp = providers.CloudProviders()
         if cp:
             for name, p in cp.iteritems():
                 if catocommon.is_true(sUserDefinedOnly):
                     if p.UserDefinedClouds:
                         sHTML += "<option value=\"" + name + "\">" + name + "</option>"
                 else:
                     sHTML += "<option value=\"" + name + "\">" + name + "</option>"
 
                 
         return sHTML
     except Exception:
         uiCommon.log_nouser(traceback.format_exc(), 0)
         return traceback.format_exc()
コード例 #22
0
ファイル: uiMethods.py プロジェクト: AsherBond/cato
    def wmAssetSearch(self):
        sFilter = uiCommon.getAjaxArg("sSearch")
        sAllowMultiSelect = uiCommon.getAjaxArg("bAllowMultiSelect")
        bAllowMultiSelect = catocommon.is_true(sAllowMultiSelect)

        a = asset.Assets(sFilter)
        if a.rows:
            sHTML = "<hr />"

            iRowsToGet = len(a.rows)

            if iRowsToGet == 0:
                sHTML += "No results found"
            else:
                if iRowsToGet >= 100:
                    sHTML += "<div>Search found " + iRowsToGet + " results.  Displaying the first 100.</div>"
                    iRowsToGet = 99

                sHTML += "<ul id=\"search_asset_ul\" class=\"search_dialog_ul\">"

                i = 0
                for row in a.rows:
                    if i > iRowsToGet:
                        break

                    sHTML += "<li class=\"ui-widget-content ui-corner-all search_dialog_value\" tag=\"asset_picker_row\"" \
                        " asset_id=\"" + row["ID"] + "\"" \
                        " asset_name=\"" + row["Name"] + "\"" \
                        "\">"
                    sHTML += "<div class=\"search_dialog_value_name\">"
                    if bAllowMultiSelect:
                        sHTML += "<input type='checkbox' name='assetcheckboxes' id='assetchk_" + row["ID"] + "' value='assetchk_" + row["ID"] + "'>"
                    sHTML += "<span>" + row["Name"] + "</span>"
                    sHTML += "</div>"

                    sHTML += "<span class=\"search_dialog_value_inline_item\">Address: " + row["Address"] + "</span>"

                    sHTML += "</li>"

                    i += 1

            sHTML += "</ul>"

        return sHTML
コード例 #23
0
ファイル: settings.py プロジェクト: grobertson/cato
 def __init__(self):
     try:
         sSQL = "select mode_off_on, loop_delay_sec, retry_delay_min, retry_max_attempts," \
             " smtp_server_addr, smtp_server_user, smtp_server_password, smtp_server_port, from_email, from_name, admin_email" \
             " from messenger_settings" \
             " where id = 1"
         
         db = catocommon.new_conn()
         row = db.select_row_dict(sSQL)
         if row:
             self.Enabled = catocommon.is_true(row["mode_off_on"])
             self.PollLoop = row["loop_delay_sec"]
             self.RetryDelay = row["retry_delay_min"]
             self.RetryMaxAttempts = row["retry_max_attempts"]
             self.SMTPServerAddress = row["smtp_server_addr"]
             self.SMTPUserAccount = row["smtp_server_user"]
             self.SMTPUserPassword = catocommon.cato_decrypt(row["smtp_server_password"])
             self.SMTPServerPort = row["smtp_server_port"]
             self.FromEmail = row["from_email"]
             self.FromName = row["from_name"]
             self.AdminEmail = row["admin_email"]
     except Exception, ex:
         raise Exception(ex)
コード例 #24
0
ファイル: uiCommon.py プロジェクト: AsherBond/cato
def GetLog():
    """
    delivers an html page with a refresh timer.  content is the last n rows of the logfile
    """
    lines = getAjaxArg("lines")
    lines = lines if lines else "100"

    refresh = 30
    r = getAjaxArg("refresh")
    if r:
        try:
            refresh = int(r)
        except:
            pass

    instance = getAjaxArg("instance")

    # if 'process' is omitted, return the logfile for this process
    process = getAjaxArg("process")
    selected = process
    if process:
        if process in ["task_instance", "sequence_instance"]:
            d = process.replace("task_instance", "te").replace("sequence_instance", "se")
            process = os.path.join(catolog.LOGPATH, "%s/%s.log" % (d, instance))
        else:
            process = os.path.join(catolog.LOGPATH, "%s.log" % (process))
    else:
        process = catolog.LOGFILE

    buf = os.popen("tail -n %s %s" % (lines, process)).readlines()

    # the 'raw' flag means just return the actual buffer, no markup
    if catocommon.is_true(getAjaxArg("raw")):
        return "".join(buf)

    # if it's not raw, it's reversed
    buf = reversed(buf)

    # this is just easier here
    svcs = [
        "cato_admin_ui",
        "cato_canvas_api",
        "cato_depmarshall",
        "cato_messenger",
        "cato_poller",
        "cato_rest_api",
        "cato_scheduler",
        "cato_user_ui",
        "csk_ui",
        "csk_cd_ui",
        "csk_job_handler",
        "csk_metrics",
        "csk_msghub",
        "maestro_newsfeed_api",
        "maestro_scheduler",
        "task_instance",
        "sequence_instance"
        ]

    pickerhtml = ""
    for x in svcs:
        sel = "selected='selected'" if x in selected else ""
        pickerhtml += '<option %s value="%s">%s</option>' % (sel, x, x)

    html = """<!DOCTYPE html>
    <html>
        <head>
            <title>log - velocity</title>
            <style>
                body {
                    word-wrap: break-word;
                }
            </style>
            <script type="text/javascript">
                function enter(e) {
                    if ( typeof e == 'undefined' && window.event) {
                        e = window.event;
                    }
                    if (e.keyCode == 13) {
                        refresh();
                    }
                }
                function showte() {
                    var p = document.getElementById('process').value;
                    if (p === "task_instance" || p === "sequence_instance") {
                        document.getElementById('instancespan').style.display="";
                    } else {
                        document.getElementById('instancespan').style.display="none";
                    }
                }
                function refresh() {
                    var url = "getlog?";
                    
                    var nl = document.getElementById('num_lines').value;
                    if (nl) {
                        url = url + "&lines=" + nl;
                    }

                    var r = document.getElementById('ref_secs').value;
                    if (r) {
                        url = url + "&refresh=" + r;
                    }

                    var p = document.getElementById('process').value;
                    url = url + "&process=" + p;

                    var i = document.getElementById('instance').value;
                    if (i) {
                        url = url + "&instance=" + i;
                    }

                    location.href = url;
                }
            </script>
        </head>
        <body>
            Lines: <input type="text" id="num_lines" onkeypress="enter(event);" value="%s" />
            Refresh: <input type="text" id="ref_secs" onkeypress="enter(event);" value="%s" />
            Service: <select id="process" onchange="showte();">%s</select>
            <span id="instancespan" style="display: none;">Instance: <input type="text" id="instance" onkeypress="enter(event);" value="%s" /></span>
            <button onclick="refresh();">Go</button>
            <hr>
            <h4>%s</h4>
            <pre>%s</pre>
            <div style="height: 20px;"></div>
            <script>
                setInterval(function() {location.reload();}, %d*1000);
                showte();
            </script>
        </body>
    </html>
    """ % (lines, refresh, pickerhtml, instance, process, "".join(buf), refresh)

    return html
コード例 #25
0
ファイル: settings.py プロジェクト: AsherBond/cato
 def DBSave(self):
     self.Enabled = catocommon.is_true(self.Enabled)
     self.LoopDelay = int(self.LoopDelay) if str(self.LoopDelay).isdigit() else 10
     self.Debug = int(self.Debug) if str(self.Debug).isdigit() else 20
     settings.set_application_section("marshaller", json.dumps(self.__dict__))
     return True
コード例 #26
0
ファイル: sysMethods.py プロジェクト: AsherBond/cato
    def reset_password(self, args):
        """Resets the password of the authenticated, or a specified User.

If a user is specified, and the authenticated user is an Administrator, 
this will reset the password of the specified user to the provided value.

If no user is specified, the password of the authenticated user will be changed.

NOTE: to prevent accidental change of an Administrators password, an extra trap is in place:
    * the username (or id) MUST be provided, even if the authenticated user 
        is the user being changed.

Required Arguments: 

* `password` - the new password.
* - OR -
* `generate` - generate a random password.

Optional Arguments:

* `user` - Either the User ID or Name.

Returns: Success message if successful, error messages on failure.
"""
        user = args.get("user")
        new_pw = args.get("password")
        generate = catocommon.is_true(args.get("generate"))

        # this is a admin function, kick out 
        if user and not api._ADMIN:
            return R(err_code=R.Codes.Forbidden, err_msg="Only Administrators can perform this function.")

        # the only way to reset an "Administrator" role password
        # is to BE an Administrator and SPECIFY a user, even if the user is you
        if not user and api._ADMIN:
            return R(err_code=R.Codes.Forbidden, err_detail="Administrators must specify a user to change.")

        if not new_pw and not generate:
            return R(err_code=R.Codes.Exception, err_detail="A password must be provided, or 'generate' must be true.")

        obj = catouser.User()
        obj.FromName(user)

        if obj.ID:
            # if a password was provided, or the random flag was set...exclusively
            if new_pw:
                # if the user requesting the change *IS* the user being changed...
                # set force_change to False
                force = True
                if obj.ID == api._USER_ID:
                    force = False
                    
                obj.ChangePassword(new_password=new_pw, force_change=force)
            elif generate:
                obj.ChangePassword(generate=generate)
        else:
            return R(err_code=R.Codes.GetError, err_detail="Unable to update password.")

        
        catocommon.write_change_log(api._USER_ID, catocommon.CatoObjectTypes.User, obj.ID, obj.FullName, "Password change/reset via API.")
        return R(response="[%s] password operation successful." % obj.FullName)
コード例 #27
0
ファイル: settings.py プロジェクト: AsherBond/cato
 def DBSave(self):
     self.Enabled = catocommon.is_true(self.Enabled)
     self.LoopDelay = int(self.LoopDelay) if str(self.LoopDelay).isdigit() else 3
     self.MaxProcesses = int(self.MaxProcesses) if str(self.MaxProcesses).isdigit() else 32
     settings.set_application_section("poller", json.dumps(self.__dict__))
     return True
コード例 #28
0
ファイル: sysMethods.py プロジェクト: AsherBond/cato
    def create_user(self, args):
        """Creates a new user account.

Only an 'Administrator' can create other users.  If the credentials used for this API call 
are not an Administrator, the call will not succeed.

Required Arguments: 

* `user` - A login name for the user.
* `name` - The full name of the user.
* `role` - The users role.  Valid values: 
    
    * Administrator
    * Developer
    * User

Optional Arguments:

* `password` - Password for the user. If password is not provided, a random password will be generated.
* `email` - Email address for the user.  Required if 'password' is omitted.
* `authtype` - 'local' or 'ldap'.  Default is 'local' if omitted.
* `forcechange` - Require user to change password. Default is 'true' if omitted. (Valid values: 'true' or 'false')
* `status` - Status of the new account. Default is 'enabled' if omitted. (Valid values: enabled, disabled, locked)
* `expires` - Expiration date for this account.  Default is 'never expires'. Must be in mm/dd/yyyy format.
* `groups` - A list of groups the user belongs to. Group names cannot contain spaces. Comma delimited list.
* `get_token` - If true, will return an automatic login token.  (Valid values: 1, yes, true)

Returns: A [User Object](restapi/api-response-objects.html#User){:target="_blank"}.
"""

        # this is a admin function, kick out 
        if not api._ADMIN:
            return R(err_code=R.Codes.Forbidden, err_msg="Only Administrators can perform this function.")

        # define the required parameters for this call
        required_params = ["user", "name", "role"]
        has_required, resp = api.check_required_params(required_params, args)
        if not has_required:
            return resp

        generate = True if not args.get("password") else False
        if generate and not args.get("email"):
            return R(err_code=R.Codes.Exception, err_detail="Email is required if password is omitted.")

        status = args.get("status", 1)  # default if omitted is 'enabled'

        groups = args.get("groups").split(",") if args.get("groups") else None
        
        # validate the expiration date is properly formatted, otherwise pass None
        import dateutil.parser as parser
        expiration_dt = None
        try:
            tmp = parser.parse(args.get("expires"))
            expiration_dt = tmp.strftime("%m/%d/%Y")
        except:
            pass

        obj = catouser.User.DBCreateNew(username=args["user"],
                                        fullname=args["name"],
                                        role=args["role"],
                                        password=args.get("password"),
                                        generatepw=generate,
                                        authtype=args.get("authtype"),
                                        forcechange=args.get("forcechange"),
                                        email=args.get("email"),
                                        status=status,
                                        expires=expiration_dt,
                                        groups=groups)
        
        # do we get a login token?
        if catocommon.is_true(args.get("get_token")):
            obj.GetToken()

        if obj:
            catocommon.write_add_log(api._USER_ID, catocommon.CatoObjectTypes.User, obj.ID, obj.LoginID, "User created by API.")
            if args.get("output_format") == "json":
                return R(response=obj.AsJSON())
            elif args.get("output_format") == "text":
                return R(response=obj.AsText(args.get("output_delimiter"), args.get("header")))
            else:
                return R(response=obj.AsXML())
        else:
            return R(err_code=R.Codes.CreateError, err_detail="Unable to create User.")
コード例 #29
0
ファイル: catouser.py プロジェクト: AsherBond/cato
    def DBCreateNew(username, fullname, role, password, generatepw, authtype="local", forcechange=1, email=None, status=1, expires=None, groups=None):
        # TODO: All the password testing, etc.
        db = catocommon.new_conn()

        # all sorts of validation
        if re.match("^[\a-zA-Z0-9_.-@]+$", username) is None:
            raise Exception("Usernames cannot contain spaces or any characters other than letters, numbers or these chars [_.@-].")

        newid = catocommon.new_guid()
        authtype = authtype if authtype else "local"
        forcechange = 0 if forcechange == 0 or forcechange == "0" else 1
        email = email if email else ""
        encpw = None
        
        if authtype == "local":
            if password:
                result, msg = User.ValidatePassword(None, password)
                if result:
                    encpw = catocommon.cato_encrypt(password)
                else:
                    raise Exception(msg)
            elif catocommon.is_true(generatepw):
                encpw = catocommon.cato_encrypt(catocommon.generate_password())
            else:
                raise Exception("A password must be provided, or check the box to generate one.")

        if role not in ("Administrator", "Developer", "User"):
            raise Exception("Role must be 'Administrator', 'Developer', or 'User'.")
        
        pw2insert = "'%s'" % encpw if encpw else " null"
        ex2insert = ("str_to_date('{0}', '%%m/%%d/%%Y')".format(expires) if expires else " null")
        sql = """insert into users
            (user_id, username, full_name, authentication_type, force_change, email, status, user_role, user_password, expiration_dt)
            values ('%s', '%s', '%s', '%s', %s, '%s', '%s', '%s', %s, %s)""" % (newid, username, fullname, authtype, forcechange,
                email, status, role, pw2insert, ex2insert)

        if not db.tran_exec_noexcep(sql):
            if db.error == "key_violation":
                raise Exception("A User with that Login ID already exists.  Please select another.")
            else: 
                raise Exception(db.error)

        db.tran_commit()
        
        if groups:
            # if we can't create groups we don't actually fail...
            sql = "select group_concat(tag_name order by tag_name separator ',') as tags from tags"
            alltags = db.select_col_noexcep(sql)
            if alltags:
                alltags = alltags.split(",")
                for tag in groups:
                    if tag in alltags:
                        sql = "insert object_tags (object_type, object_id, tag_name) values (1, '%s','%s')" % (newid, tag)
                        if not db.exec_db_noexcep(sql):
                            logger.error("Error creating Groups for new user %s." % newid)
        
        # now it's inserted... lets get it back from the db as a complete object for confirmation.
        u = User()
        u.FromID(newid)
        u.AddPWToHistory(encpw)
        
        db.close()
        return u
コード例 #30
0
ファイル: sysMethods.py プロジェクト: AsherBond/cato
    def update_user(self, args):
        """Updates a user account.

Only an 'Administrator' can manage other users.  If the credentials used for this API call 
are not an Administrator, the call will not succeed.

Properties will only be updated if the option is provided.  Omitted properties will not be changed.

NOTE: the "username" of a user cannot be changed.

If a user has 'locked' their account by numerous failed login attempts, the flag is reset 
by setting any property.  It's easiest to just the status to 'enabled'.

Required Arguments: 

* `user` - ID or Name of the User to update.

Optional Arguments:

* `name` - The full name of the user.
* `role` - The users role.  (Valid values: Administrator, Developer, User)
* `email` - Email address for the user.  Can be cleared with "None".
* `authtype` - 'local' or 'ldap'.
* `forcechange` - Require user to change password on next login. (Valid values: 'true' or 'false')
* `status` - Status of the account. (Valid values: enabled, disabled, locked)
* `expires` - Expiration date for this account.  Must be in mm/dd/yyyy format. Can be cleared with "None".
* `groups` - Add to the list of groups the user belongs to. Group names cannot contain spaces. Comma delimited list.

* `password` - the new password.
* - OR -
* `generate` - generate a random password.

Returns: A [User Object](restapi/api-response-objects.html#User){:target="_blank"}.
"""

        # this is a admin function, kick out 
        if not api._ADMIN:
            return R(err_code=R.Codes.Forbidden, err_msg="Only Administrators can perform this function.")

        # define the required parameters for this call
        required_params = ["user"]
        has_required, resp = api.check_required_params(required_params, args)
        if not has_required:
            return resp

        obj = catouser.User()
        obj.FromName(args["user"])
        if not obj.ID:
            return R(err_code=R.Codes.GetError, err_detail="Cannot find User.")
            
        # first, we have a procedure for changing password
        new_pw = args.get("password")
        generate = catocommon.is_true(args.get("generate"))
        if new_pw:
            obj.ChangePassword(new_password=new_pw)
        elif generate:
            obj.ChangePassword(generate=generate)
        
        # now we can change the properties
        
        # these can't be null or empty
        obj.FullName = args.get("name", obj.FullName)
        obj.AuthenticationType = args.get("authtype", obj.AuthenticationType)
        obj.Role = args.get("role", obj.Role)
        obj.Status = args.get("status", obj.Status)
        
        # these can be set to null/empty
        obj.Expires = args.get("expires", obj.Expires)

        obj.Email = args.get("email", obj.Email)
        obj.Email = None if obj.Email.lower() == "none" else obj.Email

        
        # this is always reset from the API... one less argument to mess with.
        obj.FailedLoginAttempts = 0

        # these are figured out manually

        # force change
        if args.get("forcechange"):
            obj.ForceChange = 1 if args["forcechange"] == "true" else 0
        
        """
        OK this group stuff is a little tricky.  User.DBUpdate requires us to send in the complete list of Groups we want.

        1) the User object already has a list, self.Tags, of all the tags it has.
        2) the caller might have sent a COMPLETE list of tags (from the UI), or only a list to ADD (from the API)
        doesn't really matter.  
        
        So, we:
            a) MERGE self.Tags with self._Groups, we'll get a distinct list of all groups we HAD or want to ADD
            b) delete all tags
            c) insert our new merged list
        """
        groups = args.get("groups").split(",") if args.get("groups") else []
        if obj.Tags is not None:
            groups = obj.Tags + groups  # merge the lists
        obj._Groups = list(set(groups))  # make it distinct
        
        # all the properties are set... call DBUpdate!
        if obj.DBUpdate():
            catocommon.write_change_log(api._USER_ID, catocommon.CatoObjectTypes.User, obj.ID, obj.FullName, "User updated via API.")

        if args.get("output_format") == "json":
            return R(response=obj.AsJSON())
        elif args.get("output_format") == "text":
            return R(response=obj.AsText(args.get("output_delimiter"), args.get("header")))
        else:
            return R(response=obj.AsXML())
コード例 #31
0
ファイル: catoadminui.py プロジェクト: AsherBond/cato
def main():
    # CATOPROCESS STARTUP

    dbglvl = 20
    if "admin_ui_debug" in catoconfig.CONFIG:
        try:
            dbglvl = int(catoconfig.CONFIG["admin_ui_debug"])
        except:
            raise Exception("admin_ui_debug setting in cato.conf must be an integer between 0-50.")
    catolog.DEBUG = dbglvl

    c_dbglvl = 20
    if "admin_ui_client_debug" in catoconfig.CONFIG:
        try:
            c_dbglvl = int(catoconfig.CONFIG["admin_ui_client_debug"])
        except:
            raise Exception("admin_ui_client_debug setting in cato.conf must be an integer between 0-50.")
    catolog.CLIENTDEBUG = c_dbglvl

    # this is a service, which has a db connection.
    # but we're not gonna use that for gui calls - we'll make our own when needed.
    server = catoprocess.CatoService(app_name)
    server.startup()

    # now that the service is set up, we'll know what the logfile name is.
    # so reget the logger
    logger = catolog.get_logger(app_name)
    catolog.set_debug(dbglvl)

    logger.info("Cato UI - Version %s" % catoconfig.VERSION)
    logger.info("DEBUG set to %d..." % dbglvl)
    logger.info("CLIENTDEBUG set to %d..." % c_dbglvl)

    # we need to build some static html here...
    # caching in the session is a bad idea, and this stuff very very rarely changes.
    # so, when the service is started it will update the files, and the ui
    # will simply pull in the files when requested.
    _build_ui_cache()

    # WEB.PY STARTUP
    if "admin_ui_port" in catoconfig.CONFIG:
        port = catoconfig.CONFIG["admin_ui_port"]
        sys.argv.append(port)

    # enable ssl?
    if catocommon.is_true(catoconfig.CONFIG.get("admin_ui_use_ssl")):
        logger.info("Using SSL/TLS...")
        sslcert = catoconfig.CONFIG.get("admin_ui_ssl_cert", os.path.join(catoconfig.CONFDIR, "cato.crt"))
        sslkey = catoconfig.CONFIG.get("admin_ui_ssl_key", os.path.join(catoconfig.CONFDIR, "cato.key"))
        try:
            with open(sslcert):
                pass
            logger.debug("SSL Certificate [%s]" % sslcert)
            CherryPyWSGIServer.ssl_certificate = sslcert
        except:
            raise Exception("SSL Certificate not found at [%s]" % sslcert)
        try:
            with open(sslkey):
                pass
            logger.debug("SSL Key [%s]" % sslkey)
            CherryPyWSGIServer.ssl_private_key = sslkey
        except:
            raise Exception("SSL Key not found at [%s]" % sslcert)
    else:
        logger.info("Using standard HTTP. (Set admin_ui_use_ssl to 'true' in cato.conf to enable SSL/TLS.)")

    app.add_processor(auth_app_processor)
    app.notfound = notfound

    app.run()