def are_valid_credentials(self, username, password): """The valid users string in the config file is in the form: username=bill password=frank """ valid_username = rdw_config.get_config( "username", self.configFilePath) valid_password = rdw_config.get_config( "password", self.configFilePath) return valid_username == username and valid_password == password
def _connect(self): import MySQLdb sqlHost = rdw_config.get_config("MySQLHost", self.configFilePath) sqlUsername = rdw_config.get_config( "MySQLUsername", self.configFilePath) sqlPassword = rdw_config.get_config( "MySQLPassword", self.configFilePath) sqlDatabaseName = rdw_config.get_config( "MySQLDatabase", self.configFilePath) self.sqlConnection = MySQLdb.connect( host=sqlHost, user=sqlUsername, passwd=sqlPassword, db=sqlDatabaseName)
def restore(self, name, restore_date, use_zip): """Used to restore the given file located in this path.""" assert isinstance(name, str) assert isinstance(restore_date, rdw_helpers.rdwTime) name = name.lstrip(b"/") # Determine the file name to be restore (from rdiff-backup # point of view). file_to_restore = os.path.join(self.full_path, name) file_to_restore = self.repo.unquote(file_to_restore) # Convert the date into epoch. date_epoch = str(restore_date.getSeconds()) # Define a location where to restore the data if name == b"" and self.path == b"": filename = b"root" if self.path != b"": filename = os.path.basename(self.path) if name != b"": filename = name # Generate a temporary location used to restore data. tempdir = rdw_helpers.encode_s(rdw_config.get_config("tempdir", default=None)) output = os.path.join(tempfile.mkdtemp(dir=tempdir), filename) # Execute rdiff-backup to restore the data. logger.info(b"execute rdiff-backup --restore-as-of=%s '%s' '%s'" % (date_epoch, file_to_restore, output)) results = self._execute( b"rdiff-backup", b"--restore-as-of=" + date_epoch, file_to_restore, output) # Check the result if results['exitCode'] != 0 or not os.access(output, os.F_OK): error = results['stderr'] if not error: error = '''rdiff-backup claimed success, but did not restore anything. This indicates a bug in rdiffweb. Please report this to a developer.''' raise UnknownError('unable to restore!\n' + error) # The path restored is a directory and need to be archived using zip # or tar if os.path.isdir(output): output_dir = output try: if use_zip: output = output_dir + ZIP_SUFFIX self._recursiveZipDir(output_dir, output) else: output = output_dir + TARGZ_SUFFIX self._recursiveTarDir(output_dir, output) finally: rdw_helpers.remove_dir(output_dir) # Return the location of the file to be restored return output
def run(self): spiderInterval = rdw_config.get_config("autoUpdateRepos") if spiderInterval: spiderInterval = int(spiderInterval) while True: findReposForAllUsers() self.killEvent.wait(60 * spiderInterval) if self.killEvent.isSet(): return
def _migrateExistingData(self): """ If we don't have any data, we may be using a sqlite interface for the first time. See if they have another database backend specified, and if they do, try to migrate the data.""" if self._getTables(): return cursor = self.sqlConnection.cursor() cursor.execute("BEGIN TRANSACTION") for statement in self._getCreateStatements(): cursor.execute(statement) if self._autoConvertDatabase: prevDBType = rdw_config.get_config( "UserDB", self.configFilePath) if prevDBType.lower() == "mysql": print 'Converting database from mysql...' import db_mysql prevDB = db_mysql.mysqlUserDB(self.configFilePath) users = prevDB._executeQuery( "SELECT UserID, Username, Password, UserRoot, IsAdmin, UserEmail, RestoreFormat FROM users") cursor.executemany( "INSERT INTO users (UserID, Username, Password, UserRoot, IsAdmin, UserEmail, RestoreFormat) values (?, ?, ?, ?, ?, ?, ?)", users) repos = prevDB._executeQuery( "SELECT UserID, RepoPath, MaxAge FROM repos") cursor.executemany( "INSERT INTO repos (UserID, RepoPath, MaxAge) values (?, ?, ?)", repos) elif prevDBType.lower() == "file": print 'Converting database from file...' import db_file prevDB = db_file.fileUserDB(self.configFilePath) username = rdw_config.get_config( "username", self.configFilePath) password = rdw_config.get_config( "password", self.configFilePath) self.add_user(username) self.set_password(username, None, password) self.set_info(username, prevDB.get_root_dir(username), True) self.set_repos(username, prevDB.get_repos(username)) cursor.execute("COMMIT TRANSACTION")
def __init__(self, configFilePath=None, autoConvertDatabase=True): self.configFilePath = configFilePath # Get database location. self._databaseFilePath = rdw_config.get_config( "SqliteDBFile", self.configFilePath) # If the database path is not define default to /etc/rdiffweb/rdw.db if self._databaseFilePath == "": self._databaseFilePath = "/etc/rdiffweb/rdw.db" self._autoConvertDatabase = autoConvertDatabase self.userRootCache = {} self._connect() self._migrateExistingData()
def __init__(self, delegate, configFilePath=None): """Create a new LDAP Database for authentication. Some behaviour are delegate to external database.""" self.delegate = delegate self.configFilePath = configFilePath # Get LDAP configuration parameters self.uri = rdw_config.get_config( "LdapUri", self.configFilePath, None) if self.uri is None: raise "LdapUri must be define in configuration" self.tls = rdw_config.get_config( "LdapTls", self.configFilePath).lower() == "true" self.base_dn = rdw_config.get_config( "LdapBaseDn", self.configFilePath, None) if self.uri is None: raise "LdapUri must be define in configuration" self.attribute = rdw_config.get_config( "LdapAttribute", self.configFilePath, "uid") self.scope = rdw_config.get_config( "LdapScope", self.configFilePath, "subtree") if self.scope == "base": self.scope = ldap.SCOPE_BASE elif self.scope == "onelevel": self.scope = ldap.SCOPE_ONELEVEL else: self.scope = ldap.SCOPE_SUBTREE self.filter = rdw_config.get_config( "LdapFilter", self.configFilePath, "(objectClass=*)") self.bind_dn = rdw_config.get_config( "LdapBindDn", self.configFilePath, "") self.bind_password = rdw_config.get_config( "LdapBindPassword", self.configFilePath, "") # Get Version self.version = rdw_config.get_config_int( "LdapVersion", self.configFilePath, 3) # Get Network timeout self.network_timeout = rdw_config.get_config_int( "LdapNetworkTimeout", self.configFilePath, 100) # Get Timeout self.timeout = rdw_config.get_config_int( "LdapTimeout", self.configFilePath, 300) # Check if password change are allowed. self.allow_password_change = rdw_config.get_config_boolean( "LdapAllowPasswordChange", self.configFilePath)
def run(self): self.notifier = emailNotifier() if not self.notifier.notificationsEnabled(): return emailTimeStr = rdw_config.get_config("emailNotificationTime") while True: emailTime = time.strptime(emailTimeStr, "%H:%M") now = datetime.datetime.now() nextEmailTime = now.replace( hour=emailTime.tm_hour, minute=emailTime.tm_min, second=0, microsecond=0) if nextEmailTime < now: nextEmailTime = nextEmailTime.replace( day=nextEmailTime.day + 1) delta = (nextEmailTime - now).seconds self.killEvent.wait(delta) if self.killEvent.isSet(): return self.notifier.sendEmails()
def get_userdb_module(self): # Return a different implementation according to UserDB configuration. prevDBType = rdw_config.get_config("UserDB") if prevDBType.lower() == "ldap": import db_ldap import db_sqlite return db_ldap.ldapUserDB(db_sqlite.sqliteUserDB()) elif prevDBType.lower() == "mysql": import db_mysql return db_mysql.mysqlUserDB() elif prevDBType.lower() == "file": import db_file return db_file.fileUserDB() elif prevDBType == "" or prevDBType.lower() == "sqlite": import db_sqlite return db_sqlite.sqliteUserDB() else: raise ValueError( "Invalid user database type. Re-configure rdiffweb.")
def _getEmailUsername(self): return rdw_config.get_config("emailUsername")
def _getEmailHost(self): return rdw_config.get_config("emailHost")
def _getNotificationTimeStr(self): return rdw_config.get_config("emailNotificationTime")
def _getEmailPassword(self): return rdw_config.get_config("emailPassword")
def get_repos(self, username): """The user home dirs string in the config file is in the form of username:/data/dir|/data/dir2...""" if not self.exists(username): return None return rdw_config.get_config("UserRepoPaths", self.configFilePath).split("|")
def get_root_dir(self, username): if not self.exists(username): return None return rdw_config.get_config("UserRoot", self.configFilePath)
def start(): """Start rdiffweb deamon.""" # Parse command line options debug = False autoReload = False pidFile = "" logFile = "" logAccessFile = "" opts, extraparams = getopt.getopt(sys.argv[1:], 'vdr', ['debug', 'log-file=', 'log-access-file=', 'pid-file=', 'background', 'autoreload']) for option, value in opts: if option in ['-d', '--debug']: debug = True if option in ['-r', '--autoreload']: autoReload = True elif option in ['--log-file']: logFile = value elif option in ['--log-access-file']: logAccessFile = value elif option in ['--pid-file']: pidFile = value elif option in ['--background']: rdw_helpers.daemonize() # Wait to write out to the pidfile until after we've (possibly) been # daemonized if pidFile: # Write our process id to specified file, so we can be killed later open(pidFile, 'a').write(str(os.getpid()) + "\n") # Configure logging logformat = '[%(asctime)s][%(levelname)-7s][%(name)s] %(message)s' level = logging.DEBUG if debug else logging.INFO if logFile: logging.basicConfig(filename=logFile, level=level, format=logformat) else: logging.basicConfig(level=level, format=logformat) if logAccessFile: logging.root.handlers[0].addFilter(NotFilter("cherrypy.access")) logging.root.handlers[0].addFilter(ContextFilter()) # Check if configuration file exists config_file = rdw_config.get_config_file() if not os.access(config_file, os.F_OK): logger.warn("configuration file is not accessible: %s" % config_file) # Get configuration serverHost = rdw_config.get_config("ServerHost", default="0.0.0.0") try: serverPort = int(rdw_config.get_config("ServerPort", default="8080")) except ValueError: logger.error("ServerPort should be a port number") sys.exit(1) sslCertificate = rdw_config.get_config("SslCertificate") sslPrivateKey = rdw_config.get_config("SslPrivateKey") # Define the locales directory localesdir = os.path.split(inspect.getfile(inspect.currentframe()))[0] localesdir = os.path.realpath(os.path.abspath(localesdir)) localesdir = os.path.join(localesdir, 'locales/') environment = "development" if not debug: environment = "production" global_settings = { 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', 'tools.gzip.on': True, 'tools.sessions.on': True, 'tools.authform.on': True, 'autoreload.on': autoReload, 'server.socket_host': serverHost, 'server.socket_port': serverPort, 'server.log_file': logFile, 'server.ssl_certificate': sslCertificate, 'server.ssl_private_key': sslPrivateKey, 'log.screen': False, 'log.access_file': logAccessFile, 'server.environment': environment, } page_settings = { '/': { 'tools.authform.on': True, 'tools.setup.on': True, 'tools.i18n.on': True, 'tools.i18n.default': 'en_US', 'tools.i18n.mo_dir': localesdir, 'tools.i18n.domain': 'messages' }, '/login': { 'tools.authform.on': False, }, '/status/feed': { 'tools.authform.on': False, 'tools.authbasic.on': True, 'tools.authbasic.checkpassword': page_login.rdiffLoginPage().checkpassword }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.root': os.path.abspath(os.path.dirname(__file__)), 'tools.staticdir.dir': "static", 'tools.authform.on': False, 'tools.setup.on': False, }, '/setup': { 'tools.setup.on': False, 'tools.authform.on': False, 'tools.sessions.on': False, } } if rdw_config.get_config("SessionStorage").lower() == "disk": sessionDir = rdw_config.get_config("SessionDir") if (os.path.exists(sessionDir) and os.path.isdir(sessionDir) and os.access(sessionDir, os.W_OK)): logger.info("Setting session mode to disk in directory %s" % sessionDir) global_settings['tools.sessions.on'] = True global_settings['tools.sessions.storage_type'] = 'file' global_settings['tools.sessions.storage_path'] = sessionDir cherrypy.config.update(global_settings) root = page_locations.rdiffLocationsPage() root.setup = page_setup.rdiffSetupPage() root.login = page_login.rdiffLoginPage() root.logout = page_logout.rdiffLogoutPage() root.browse = page_browse.rdiffBrowsePage() root.restore = page_restore.rdiffRestorePage() root.history = page_history.rdiffHistoryPage() root.status = page_status.rdiffStatusPage() root.admin = page_admin.rdiffAdminPage() root.prefs = page_prefs.rdiffPreferencesPage() # Start repo spider thread if not debug: killEvent = threading.Event() rdw_spider_repos.startRepoSpiderThread(killEvent) email_notification.startEmailNotificationThread(killEvent) if hasattr(cherrypy.engine, 'subscribe'): # CherryPy >= 3.1 cherrypy.engine.subscribe('stop', lambda: killEvent.set()) else: cherrypy.engine.on_stop_engine_list.append(lambda: killEvent.set()) # @UndefinedVariable # Start web server cherrypy.quickstart(root, config=page_settings)
def exists(self, username): valid_username = rdw_config.get_config( "username", self.configFilePath) return valid_username == username
def _getEmailSender(self): return rdw_config.get_config("emailSender")