diff --git a/bin/CryptoBox.py b/bin/CryptoBox.py index 0612b23..a130d6b 100755 --- a/bin/CryptoBox.py +++ b/bin/CryptoBox.py @@ -208,56 +208,6 @@ class CryptoBoxProps(CryptoBox): return None - def setNameForUUID(self, uuid, name): - "assign a name to a uuid in the ContainerNameDatabase" - used_uuid = self.getUUIDForName(name) - "first remove potential conflicting uuid/name combination" - if used_uuid: - ## remember the container which name was overriden - for e in self.containers: - if e.getName() == name: - forcedRename = e - break - del self.prefs.nameDB[used_uuid] - self.prefs.nameDB[uuid] = name - self.prefs.nameDB.write() - ## rename the container that lost its name (necessary while we use cherrypy) - if used_uuid: - ## this is surely not the best way to regenerate the name - dev = e.getDevice() - old_index = self.containers.index(e) - self.containers.remove(e) - self.containers.insert(old_index, CryptoBoxContainer.CryptoBoxContainer(dev,self)) - ## there should be no reason for any failure - return True - - - def getNameForUUID(self, uuid): - "get the name belonging to a specified key (usually the UUID of a fs)" - try: - return self.prefs.nameDB[uuid] - except KeyError: - return None - - - def getUUIDForName(self, name): - """ get the key belonging to a value in the ContainerNameDatabase - this is the reverse action of 'getNameForUUID' """ - for key in self.prefs.nameDB.keys(): - if self.prefs.nameDB[key] == name: return key - "the uuid was not found" - return None - - - def removeUUID(self, uuid): - if uuid in self.prefs.nameDB.keys(): - del self.prefs.nameDB[uuid] - self.prefs.nameDB.write() - return True - else: - return False - - def getAvailableLanguages(self): '''reads all files in path LangDir and returns a list of basenames from existing hdf files, that should are all available diff --git a/bin/CryptoBoxContainer.py b/bin/CryptoBoxContainer.py index 31e1509..6929d8b 100755 --- a/bin/CryptoBoxContainer.py +++ b/bin/CryptoBoxContainer.py @@ -52,22 +52,46 @@ class CryptoBoxContainer: return self.name + def __setAttributes(self): + try: + ## is there already an entry in the database? + self.attributes = self.cbox.prefs.volumesDB[self.getName()] + self.attributes["uuid"] = self.uuid + except KeyError: + ## set default values + self.attributes = { "uuid": self.uuid } + self.cbox.prefs.volumesDB[self.getName()] = self.attributes + + def setName(self, new_name): + old_name = self.getName() if new_name == self.name: return - # TODO: check why the following test was/is (?) necessary - side effects? - #if self.isMounted(): - # raise CBVolumeIsActive("the container must be inactive during renaming") + ## renaming is not possible, if the volume is active, as the mountpoint name + ## is the same as the volume name + if self.isMounted(): + raise CBVolumeIsActive("the container must not be active during renaming") if not re.search(r'^[a-zA-Z0-9_\.\- ]+$', new_name): raise CBInvalidName("the supplied new name contains illegal characters") - "check for active partitions with the same name" - prev_name_owner = self.cbox.getContainerList(filterName=new_name) - if prev_name_owner: - for a in prev_name_owner: - if a.isMounted(): - raise CBNameActivelyUsed("the supplied new name is already in use for an active partition") - if not self.cbox.setNameForUUID(self.uuid, new_name): - raise CBContainerError("failed to change the volume name for unknown reasons") + ## check for another partitions with the same name + if self.cbox.getContainerList(filterName=new_name): + raise CBNameIsInUse("the supplied new name is already in use for anonther partition") + ## maybe there a is an entry in the volumes database (but the partition is not active + try: + ## remove possibly existing inactive database item + del self.cbox.prefs.volumesDB[new_name] + except KeyError: + ## no entry - so nothing happens + pass + ## set new name self.name = new_name + ## remove old database entry + try: + del self.cbox.prefs.volumesDB[old_name] + except KeyError: + pass + ## set new volumes database entry + self.cbox.prefs.volumesDB[new_name] = self.attributes + self.cbox.prefs.volumesDB.write() def getDevice(self): @@ -112,6 +136,7 @@ class CryptoBoxContainer: self.uuid = self.__getUUID() self.type = self.__getTypeOfPartition() self.name = self.__getNameOfContainer() + self.__setAttributes() if self.type == self.Types["luks"]: self.mount = self.__mountLuks self.umount = self.__umountLuks @@ -201,20 +226,23 @@ class CryptoBoxContainer: " ****************** internal stuff ********************* " def __getNameOfContainer(self): - "retrieve the name of the container by querying the database" - def_name = self.cbox.getNameForUUID(self.uuid) - if def_name: return def_name - "there is no name defined for this uuid - we will propose a good one" + """retrieve the name of the container by querying the database + call this function only for the initial setup of the container object""" + found_name = None + for key in self.cbox.prefs.volumesDB.keys(): + if self.cbox.prefs.volumesDB[key]["uuid"] == self.uuid: + found_name = key + if found_name: return found_name + ## there is no name defined for this uuid - we will propose a good one prefix = self.cbox.prefs["Main"]["DefaultVolumePrefix"] unused_found = False counter = 1 while not unused_found: guess = prefix + str(counter) - if self.cbox.getUUIDForName(guess): + if self.cbox.prefs.volumesDB.has_key(guess): counter += 1 else: unused_found = True - self.cbox.setNameForUUID(self.uuid, guess) return guess diff --git a/bin/CryptoBoxExceptions.py b/bin/CryptoBoxExceptions.py index 743bfcd..9619337 100644 --- a/bin/CryptoBoxExceptions.py +++ b/bin/CryptoBoxExceptions.py @@ -87,7 +87,7 @@ class CBVolumeIsActive(CBContainerError): class CBInvalidName(CBContainerError): pass -class CBNameActivelyUsed(CBContainerError): +class CBNameIsInUse(CBContainerError): pass class CBInvalidType(CBContainerError): diff --git a/bin/CryptoBoxSettings.py b/bin/CryptoBoxSettings.py index 56e9f4f..9cf2d6d 100644 --- a/bin/CryptoBoxSettings.py +++ b/bin/CryptoBoxSettings.py @@ -20,7 +20,7 @@ class CryptoBoxSettings: "~/.cryptobox.conf", "/etc/cryptobox/cryptobox.conf"] - NAMEDB_FILE = "cryptobox_names.db" + VOLUMESDB_FILE = "cryptobox_volumes.db" PLUGINCONF_FILE = "cryptobox_plugins.conf" USERDB_FILE = "cryptobox_users.db" @@ -34,7 +34,7 @@ class CryptoBoxSettings: self.__configureLogHandler() self.__checkUnknownPreferences() self.preparePartition() - self.nameDB = self.__getNameDatabase() + self.volumesDB = self.__getVolumesDatabase() self.pluginConf = self.__getPluginConfig() self.userDB = self.__getUserDB() self.misc_files = self.__getMiscFiles() @@ -46,9 +46,9 @@ class CryptoBoxSettings: """ ok = True try: - self.nameDB.write() + self.volumesDB.write() except IOError: - self.log.warn("could not save the name database") + self.log.warn("could not save the volume database") ok = False try: self.pluginConf.write() @@ -221,25 +221,6 @@ class CryptoBoxSettings: self.log.warn("unknown configuration setting: %s" % element_path) - def __getNameDatabase(self): - try: - try: - nameDB_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.NAMEDB_FILE) - except KeyError: - raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") - except SyntaxError: - raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", nameDB_file, "failed to interprete the filename of the name database correctly (%s)" % nameDB_file) - ## create nameDB if necessary - if os.path.exists(nameDB_file): - nameDB = configobj.ConfigObj(nameDB_file) - else: - nameDB = configobj.ConfigObj(nameDB_file, create_empty=True) - ## check if nameDB file was created successfully? - if not os.path.exists(nameDB_file): - raise CryptoBoxExceptions.CBEnvironmentError("failed to create name database (%s)" % nameDB_file) - return nameDB - - def __getPluginConfig(self): import StringIO plugin_rules = StringIO.StringIO(self.pluginValidationSpec) @@ -263,6 +244,25 @@ class CryptoBoxSettings: return pluginConf + def __getVolumesDatabase(self): + try: + try: + conf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.VOLUMESDB_FILE) + except KeyError: + raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") + except SyntaxError: + raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", conf_file, "failed to interprete the filename of the volume database correctly (%s)" % conf_file) + ## create conf_file if necessary + if os.path.exists(conf_file): + conf = configobj.ConfigObj(conf_file) + else: + conf = configobj.ConfigObj(conf_file, create_empty=True) + ## check if conf_file file was created successfully? + if not os.path.exists(conf_file): + raise CryptoBoxExceptions.CBEnvironmentError("failed to create volume database file (%s)" % conf_file) + return conf + + def __getUserDB(self): import StringIO, sha userDB_rules = StringIO.StringIO(self.userDatabaseSpec) @@ -398,7 +398,7 @@ rank = integer(default=None) [admins] admin = string(default=d033e22ae348aeb5660fc2140aec35850c4da997) """ - + class CryptoBoxSettingsValidator(validate.Validator): diff --git a/bin/unittests.CryptoBox.py b/bin/unittests.CryptoBox.py index 3315d4b..b109d8a 100755 --- a/bin/unittests.CryptoBox.py +++ b/bin/unittests.CryptoBox.py @@ -32,7 +32,7 @@ class CryptoBoxPropsConfigTests(unittest.TestCase): files = { "configFileOK" : "cbox-test_ok.conf", "configFileBroken" : "cbox-test_broken.conf", - "nameDBFile" : "cryptobox_names.db", + "nameDBFile" : "cryptobox_volumes.db", "pluginConf" : "cryptobox_plugins.conf", "userDB" : "cryptobox_users.db", "logFile" : "cryptobox.log",