german language file updated
WebInterfaceDataset replaces CryptoBoxWebserverSettings WebInterfaceSites replaces CryptoBoxWebserverSites input validation rewritten clearsiler macro 'print_form_header' now expects the 'action' as a parameter
This commit is contained in:
parent
0835144ad1
commit
0aa1f9f74b
23 changed files with 644 additions and 392 deletions
|
@ -262,6 +262,16 @@ class CryptoBoxProps(CryptoBox):
|
|||
return []
|
||||
|
||||
|
||||
def getContainer(self, device):
|
||||
"retrieve the container element for this device"
|
||||
all = [e for e in self.getContainerList() if e.device == device]
|
||||
if all:
|
||||
return all[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def setNameForUUID(self, uuid, name):
|
||||
"assign a name to a uuid in the ContainerNameDatabase"
|
||||
used_uuid = self.getUUIDForName(name)
|
||||
|
|
|
@ -508,7 +508,7 @@ class CryptoBoxContainer:
|
|||
"luksFormat",
|
||||
self.device,
|
||||
"--batch-mode",
|
||||
"--cipher", self.cbox.cbxPrefs["System"]["DefaultCipher"],
|
||||
"--cipher", self.cbox.cbxPrefs["Main"]["DefaultCipher"],
|
||||
"--iter-time", "2000"])
|
||||
proc.stdin.write(password)
|
||||
(output, errout) = proc.communicate()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python2.4
|
||||
import os
|
||||
import CryptoBoxWebserverSites
|
||||
import WebInterfaceSites
|
||||
|
||||
try:
|
||||
import cherrypy
|
||||
|
@ -12,7 +12,7 @@ class CryptoBoxWebserver:
|
|||
'''this class starts the cherryp webserver and serves the single sites'''
|
||||
|
||||
def __init__(self):
|
||||
cherrypy.root = CryptoBoxWebserverSites.CryptoBoxWebserverSites()
|
||||
cherrypy.root = WebInterfaceSites.WebInterfaceSites()
|
||||
#expose static content:
|
||||
#I currently have no idea how to cleanly extract the stylesheet path from
|
||||
#the config object without an extra CryptoBox.CryptoBoxProps instance.
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
import os
|
||||
try:
|
||||
import neo_cgi, neo_util, neo_cs
|
||||
except ImportError:
|
||||
raise ImportError("could not import clearsilver modules! Try apt-get install python-clearsilver.")
|
||||
|
||||
class CryptoBoxWebserverRender:
|
||||
'''renders the site with clearsilver template and languagefile
|
||||
|
||||
'''
|
||||
def render(self, website):
|
||||
'''renders from clearsilver templates and returns the resulting html
|
||||
|
||||
Gets a dictionary with all settings, nessessary for rendering.
|
||||
In fact the dictionary is a copy of the CryptoBoxWerbserverSite
|
||||
object, that calls this render method. This might be bloat but
|
||||
this way the render method has always a complete, actual set of values.
|
||||
'''
|
||||
|
||||
website.log.info("rendering site: "+website.settings["Data.Action"])
|
||||
|
||||
cs_path = website.cbxPrefs["Locations"]["TemplateDir"]+"/main.cs"
|
||||
if not os.access(cs_path, os.R_OK):
|
||||
website.log.error("Couldn't read cs file: %s" % cs_path)
|
||||
return "Couldn't read cs file: %s" % cs_path
|
||||
|
||||
#hdf_path = website.cbxPrefs["Locations"]["LangDir"]+"/"+website.cbxPrefs["WebSettings"]["Language"]+".hdf"
|
||||
# use the user selected language ('Settings.Language') instead of the configured
|
||||
hdf_path = website.cbxPrefs["Locations"]["LangDir"]+"/"+website.settings["Settings.Language"]+".hdf"
|
||||
if not os.access(hdf_path, os.R_OK):
|
||||
website.log.error("Couldn't read hdf file: %s" % hdf_path)
|
||||
return "Couldn't read hdf file: %s" % hdf_path
|
||||
|
||||
hdf = neo_util.HDF()
|
||||
hdf.readFile(hdf_path)
|
||||
website.log.debug(website.settings)
|
||||
for key in website.settings.keys():
|
||||
hdf.setValue(key,str(website.settings[key]))
|
||||
cs = neo_cs.CS(hdf)
|
||||
cs.parseFile(cs_path)
|
||||
return cs.render()
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
class CryptoBoxWebserverSettings:
|
||||
'''this is the motherclass of all cbx site settings
|
||||
|
||||
put the stuff in here, that every site will need access to'''
|
||||
|
||||
def setSettings(self, website):
|
||||
'''fills a dictionary with values from the configfile
|
||||
|
||||
There may also be set some useful standards here.'''
|
||||
website.settings={}
|
||||
#TODO: this is nessessary since the last config split in different sections
|
||||
## put all found WebSettings values in the dictionary
|
||||
## RFC: arbitrarily importing all available keys does not sound very secure [l]
|
||||
## RFC: settings with the same names in different sections (Log, Main, ...) will collide silently - right? [l]
|
||||
## yep, we'll have to divide between settings for clearsilver and settings we need for other webstuff [a]
|
||||
## I think it would be better to expose only the necessary settings (manually - not just everything) [l]
|
||||
for key in self.cbxPrefs["WebSettings"].keys():
|
||||
website.settings["Settings."+key] = self.cbxPrefs["WebSettings"][key]
|
||||
## also all Log values
|
||||
for key in self.cbxPrefs["Log"].keys():
|
||||
website.settings["Log."+key] = self.cbxPrefs["Log"][key]
|
||||
## also Main
|
||||
for key in self.cbxPrefs["Main"].keys():
|
||||
website.settings["Settings."+key] = self.cbxPrefs["Main"][key]
|
||||
## Locations dito
|
||||
for key in self.cbxPrefs["Locations"].keys():
|
||||
website.settings["Settings."+key] = self.cbxPrefs["Locations"][key]
|
||||
|
||||
## put available languages also in the dictionary
|
||||
website.settings["Settings.AvailableLanguages"] = self.getAvailableLanguages()
|
||||
website.settings["Settings.AvailableDocLanguages"] = self.getAvailableDocLanguages()
|
||||
#self.log.info(self.settings)
|
||||
|
||||
|
||||
def print_foo(self):
|
||||
'''a stupid demo method
|
||||
|
||||
if there are methods necessary for more than one site,
|
||||
put them in here like this stupid demo'''
|
||||
self.log.info("'print_foo' was called by some site and triggerd an inheritated method")
|
||||
self.cbx_inheritance_test("fooooooooooooobaaaaaaaaaaaaaaaaaaaar")
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
import CryptoBox
|
||||
import CryptoBoxWebserverSettings
|
||||
import CryptoBoxWebserverRender
|
||||
# RFC: is this global variable necessary? [l]
|
||||
website = CryptoBoxWebserverRender.CryptoBoxWebserverRender()
|
||||
|
||||
# RFC: where should we put the information gathering? (available harddisks, current volume info, ...) - selectively for every "site" or always (as before)? [l]
|
||||
|
||||
# RFC: is it necessary to inherit these both classes?
|
||||
# for clarity they should be just instanciated - or not? [l]
|
||||
class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettings.CryptoBoxWebserverSettings):
|
||||
'''
|
||||
url2func = {'index':'show_status','doc':'show_doc','logs':'show_log'}
|
||||
'''
|
||||
|
||||
def __prepare(self, action="show_status"):
|
||||
'''handles stuff that all sites need as preparation
|
||||
|
||||
The default site to render is 'show_status'.
|
||||
Self.settings is filled by the following methodcall
|
||||
thus every rendered site will get actual values from the configfile.
|
||||
After that the corresponding site-method (e.g. doc) may set individual values.
|
||||
'''
|
||||
|
||||
# RFC: the following line somehow implicitly calls 'setSettings(self, self)'
|
||||
# should it be that way? [l]
|
||||
self.setSettings(self)
|
||||
#self.settings
|
||||
self.settings["Data.Action"] = action
|
||||
#TODO: check ssl status
|
||||
|
||||
|
||||
def __sanitize_input(self, evilparams):
|
||||
'''mistrusts every given parameter and wipes crap out
|
||||
|
||||
Every single site method has to call this before even looking
|
||||
at url-given parameters.
|
||||
This has to be called manually, since I don't see any other way of
|
||||
sanitizing input automatically for all sites.
|
||||
|
||||
To take full effect it is good style not to use any given
|
||||
parameter for any website. Instead use "settings.["..." if it
|
||||
isn't already defined. Then define it in here, after carefully
|
||||
checking.
|
||||
# RFC: why shouldn't it be called in __init__? [l]
|
||||
there is no such thing like __init__ in cherrypy sites [a]
|
||||
what about the unnamed place, where 'exposed' attributes are set? [l]
|
||||
'''
|
||||
# RFC: this dictionary is not sufficient for arbitrary text inputs (e.g.: names) or numbers [l]
|
||||
# what way would we sanizite such input? just exclude forbidden elements? [a]
|
||||
# I would prefer a seperate function for each possible setting [l]
|
||||
niceparams = {
|
||||
'weblang': ["Settings.Language", self.settings["Settings.AvailableLanguages"]],
|
||||
'loglevel': ["Log.Level", ('','info', 'warn', 'debug', 'error')],
|
||||
'type': ["Data.Type", ('reboot', 'poweroff')]
|
||||
}
|
||||
## check all given evil parameters against the nice ones
|
||||
## set them to self.settings if accepted, otherwise do nothing
|
||||
for evilkey in evilparams.keys():
|
||||
# TODO: should be easier without the following for-loop
|
||||
for nicekey in niceparams.keys():
|
||||
if evilkey == nicekey:
|
||||
#self.log.warn(niceparams[nicekey][0])
|
||||
#self.log.warn(niceparams[nicekey][1])
|
||||
if evilparams[nicekey] and evilparams[nicekey] in niceparams[nicekey][1]:
|
||||
# RFC: isn't "self.settings" a non-obvious name for user input? [l]
|
||||
# self.settings is used by clearsilver [a]
|
||||
# yes, but why should clearsilver have access to the user input? [l]
|
||||
self.settings[niceparams[nicekey][0]] = evilparams[nicekey]
|
||||
#self.log.warn(niceparams[nicekey][0])
|
||||
#self.log.warn(evilparams[nicekey])
|
||||
|
||||
'''
|
||||
## e.g. do this manually
|
||||
if evilkey == "weblang":
|
||||
if evilparams["weblang"] and evilparams["weblang"] in niceparams["weblang"]:
|
||||
self.settings["Settings.Language"] = evilparams["weblang"]
|
||||
if evilkey == "loglevel":
|
||||
if evilparams["loglevel"] and evilparams["loglevel"] in niceparams["loglevel"]:
|
||||
self.settings["Log.Level"] = evilparams["loglevel"]
|
||||
if evilkey == "type":
|
||||
if evilparams["type"] and evilparams["type"] in niceparams["type"]:
|
||||
self.settings["Data.Type"] = evilparams["type"]
|
||||
'''
|
||||
|
||||
return
|
||||
|
||||
def __isHDAvailable(self):
|
||||
#TODO: implement this
|
||||
return True
|
||||
|
||||
def __check_config(self):
|
||||
#TODO: from now on a cryptobox is always configured
|
||||
return True
|
||||
|
||||
|
||||
def __check_init_running(self):
|
||||
#TODO: implement this check (is mkfs still running?)
|
||||
return False
|
||||
|
||||
######################################################################
|
||||
## put real sites down here and don't forget to expose them at the end
|
||||
|
||||
def logs(self, loglevel=""):
|
||||
'''displays a HTML version of the logfile
|
||||
|
||||
The loglevel has to be set and nothing else, as we just log in english.
|
||||
RFC: what does this mean? We still have to save the current language - or not? [l]
|
||||
|
||||
Be aware not to name this method just "log" as it seems to be a
|
||||
reserved word.
|
||||
# RFC: maybe it conflicts with CryptoBoxProps.log - which we inherited? [l]
|
||||
'''
|
||||
self.__prepare("show_log")
|
||||
self.__sanitize_input({"loglevel":loglevel})
|
||||
self.settings["Data.Log"] = "<br/>".join(self.getLogData(lines=30, maxSize=2000))
|
||||
return website.render(self)
|
||||
|
||||
|
||||
def status(self, weblang=""):
|
||||
'''shows the current status of the box
|
||||
'''
|
||||
self.__prepare("show_status")
|
||||
self.__sanitize_input({"weblang":weblang})
|
||||
if not self.__check_config():
|
||||
self.settings["Data.Warning"] = "NotInitialized"
|
||||
self.settings["Data.Action"] = "form_init"
|
||||
elif self.__check_init_running():
|
||||
self.settings["Data.Warning"] = "InitNotFinished"
|
||||
self.settings["Data.Action"] = "empty"
|
||||
self.settings["Data.Redirect.Action"] = "form_config"
|
||||
self.settings["Data.Redirect.Delay"] = "30"
|
||||
else:
|
||||
self.settings["Data.Action"] = "show_status"
|
||||
self.settings["Data.Redirect.Delay"] = "60"
|
||||
return website.render(self)
|
||||
|
||||
|
||||
def config(self,weblang=""):
|
||||
pass
|
||||
|
||||
|
||||
# TODO: add "doclang" - it is selected by each link in the doc pages
|
||||
# according to scripts/docexport it's weblang [a]
|
||||
def doc(self,page="",weblang=""):
|
||||
'''prints the offline wikipage
|
||||
'''
|
||||
self.__prepare("show_doc")
|
||||
# TODO: single pagenames should be sanitized
|
||||
self.__sanitize_input({"weblang":weblang})
|
||||
# TODO: check the supplied page name for validity (is it text? pattern match?)
|
||||
if page:
|
||||
self.settings["Data.Doc.Page"] = page
|
||||
else:
|
||||
## display this site as default helpsite
|
||||
self.settings["Data.Doc.Page"] ="CryptoBoxUser"
|
||||
if len(self.settings["Settings.AvailableDocLanguages"]) < 1:
|
||||
self.settings["Data.Error"] = "NoDocumentation"
|
||||
# TODO: what should be done, if there is an error?
|
||||
# do you mean this is not an error? [a]
|
||||
# it is, but the current action is still "show_doc" - despite the error - maybe "blank" would be better? [l]
|
||||
## set doclang to weblang, otherwise the default weblang from the config will be used for doclang
|
||||
elif self.settings["Settings.Language"] in self.settings["Settings.AvailableDocLanguages"]:
|
||||
self.settings["Settings.DocLang"] = self.settings["Settings.Language"]
|
||||
# TODO: missing 'else'?
|
||||
|
||||
return website.render(self)
|
||||
|
||||
|
||||
def system(self, type="", weblang=""):
|
||||
self.__prepare("form_system")
|
||||
self.__sanitize_input({"type":type,"weblang":weblang})
|
||||
if type == "reboot":
|
||||
self.settings["Data.Success"] = "ReBoot"
|
||||
self.settings["Data.Redirect.Action"] = "show_status"
|
||||
self.settings["Data.Redirect.Delay"] = "180"
|
||||
self.log.info("TODO: call function for system reboot")
|
||||
elif type == "poweroff":
|
||||
self.settings["Data.Success"] = "PowerOff"
|
||||
self.log.info("TODO: call function for system shutdown")
|
||||
else:
|
||||
self.log.warn("This shutdown-mode (%s) is not supplied." % type)
|
||||
return website.render(self)
|
||||
|
||||
|
||||
def index(self):
|
||||
self.__prepare("show_status")
|
||||
return website.render(self)
|
||||
|
||||
def test(self):
|
||||
return "test passed"
|
||||
|
||||
def umount_do(self):
|
||||
if not __isHDAvailable():
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
'''
|
||||
## DONE: these functions are pythonized
|
||||
#################### show_log #######################
|
||||
##################### doc ############################
|
||||
##################### poweroff ######################
|
||||
##################### reboot ########################
|
||||
|
||||
## but there are even more TODO
|
||||
#-------------------------------------------------------#
|
||||
# here you may define all cases that require a harddisk #
|
||||
#-------------------------------------------------------#
|
||||
################ umount_do #######################
|
||||
elif action == "unmount_do":
|
||||
if not device:
|
||||
self.log.debug("invalid device chosen: %s" device
|
||||
settings["Data.Warning"] = "InvalidDevice"
|
||||
settings["Data.Action"] = "empty"
|
||||
elif not True: #TODO: replace True with check_config()
|
||||
settings["Data.Warning"] = "NotInitialized"
|
||||
settings["Data.Action"] = "form_init"
|
||||
elif True: #TODO: replace True with check_init_running()
|
||||
settings["Data.Warning"] = "InitNotFinished"
|
||||
settings["Data.Action"] = "empty"
|
||||
settings["Data.Redirect.Action"] = "form_config"
|
||||
settings["Data.Redirect.Delay"] = "30"
|
||||
elif not True: #TODO: replace True with check_mounted(device)
|
||||
settings["Data.Warning"] = "NotMounted"
|
||||
settings["Data.Action"] = "show_volume"
|
||||
else: #unmount
|
||||
#TODO: replace this line with umount_vol(device)
|
||||
if True: #TODO: replace True with check_mounted(device)
|
||||
settings["Data.Warning"] = "UmountFailed"
|
||||
settings["Data.Action"] = "show_volume"
|
||||
else:
|
||||
settings["Data.Action"] = "show_volume"
|
||||
################ mount_do ########################
|
||||
elif action == "mount_do":
|
||||
if device:
|
||||
pass #TODO: is_encrypted = check_device_encryption(device)
|
||||
else:
|
||||
self.log.debug("invalid device chosen: %s" device
|
||||
settings["Data.Warning"] = "InvalidDevice"
|
||||
settings["Data.Action"] = "empty"
|
||||
elif not True: #TODO: replace True with check_config()
|
||||
settings["Data.Warning"] = "NotInitialized"
|
||||
settings["Data.Action"] = "form_init"
|
||||
#at cryptobox.pl line 568
|
||||
'''
|
||||
|
||||
|
||||
############################################################################
|
||||
## to make the sites visible through the webserver they must be exposed here
|
||||
index.exposed = True
|
||||
doc.exposed = True
|
||||
logs.exposed = True
|
||||
system.exposed = True
|
||||
status.exposed = True
|
||||
test.exposed = True
|
||||
|
||||
|
74
pythonrewrite/bin2/WebInterfaceDataset.py
Normal file
74
pythonrewrite/bin2/WebInterfaceDataset.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
import os
|
||||
import CryptoBoxContainer
|
||||
|
||||
## useful constant for many functions
|
||||
CONT_TYPES = CryptoBoxContainer.CryptoBoxContainer.Types
|
||||
|
||||
class WebInterfaceDataset(dict):
|
||||
"""this class contains all data that should be available for the clearsilver
|
||||
templates
|
||||
"""
|
||||
|
||||
def __init__(self, cbox, prefs):
|
||||
self.prefs = prefs
|
||||
self.cbox = cbox
|
||||
self.__setConfigValues()
|
||||
self.__setCryptoBoxState()
|
||||
|
||||
|
||||
def __setConfigValues(self):
|
||||
self["Settings.TemplateDir"] = os.path.abspath(self.prefs["Locations"]["TemplateDir"])
|
||||
self["Settings.LanguageDir"] = os.path.abspath(self.prefs["Locations"]["LangDir"])
|
||||
self["Settings.DocDir"] = os.path.abspath(self.prefs["Locations"]["DocDir"])
|
||||
self["Settings.Stylesheet"] = self.prefs["WebSettings"]["Stylesheet"]
|
||||
self["Settings.Language"] = self.prefs["WebSettings"]["Language"]
|
||||
self["Settings.DocLang"] = self.prefs["WebSettings"]["DocLanguage"]
|
||||
|
||||
|
||||
def __setCryptoBoxState(self):
|
||||
avail_counter = 0
|
||||
active_counter = 0
|
||||
for container in self.cbox.getContainerList():
|
||||
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0
|
||||
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0
|
||||
isMounted = container.isMounted() and 1 or 0
|
||||
self["Data.Disks.%d.device" % avail_counter] = container.getDevice()
|
||||
self["Data.Disks.%d.name" % avail_counter] = container.getName()
|
||||
self["Data.Disks.%d.encryption" % avail_counter] = isEncrypted
|
||||
self["Data.Disks.%d.plaintext" % avail_counter] = isPlain
|
||||
self["Data.Disks.%d.active" % avail_counter] = isMounted
|
||||
if isMounted: active_counter += 1
|
||||
avail_counter += 1
|
||||
self["Data.activeDisksCount"] = active_counter
|
||||
for lang in self.cbox.getAvailableLanguages():
|
||||
self["Data.Languages." + lang] = self.__getLanguageName(lang)
|
||||
## TODO: open issues: Data.Config.AdminPasswordIsSet
|
||||
|
||||
|
||||
def setCurrentDiskState(self, device):
|
||||
for container in self.cbox.getContainerList():
|
||||
if container.getDevice() == device:
|
||||
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0
|
||||
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0
|
||||
isMounted = container.isMounted() and 1 or 0
|
||||
self["Data.CurrentDisk.device"] = container.getDevice()
|
||||
self["Data.CurrentDisk.name"] = container.getName()
|
||||
self["Data.CurrentDisk.encryption"] = isEncrypted
|
||||
self["Data.CurrentDisk.plaintext"] = isPlain
|
||||
self["Data.CurrentDisk.active"] = isMounted
|
||||
|
||||
if isMounted:
|
||||
(size, avail, used) = container.getCapacity()
|
||||
percent = used / size
|
||||
self["Data.CurrentDisk.capacity.used"] = used
|
||||
self["Data.CurrentDisk.capacity.free"] = avail
|
||||
self["Data.CurrentDisk.capacity.size"] = size
|
||||
self["Data.CurrentDisk.capacity.percent"] = percent
|
||||
|
||||
def __getLanguageName(self, lang):
|
||||
import neo_cgi, neo_util, neo_cs
|
||||
hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf")
|
||||
hdf = neo_util.HDF()
|
||||
hdf.readFile(hdf_path)
|
||||
return hdf.getValue("Lang.Name",lang)
|
||||
|
470
pythonrewrite/bin2/WebInterfaceSites.py
Executable file
470
pythonrewrite/bin2/WebInterfaceSites.py
Executable file
|
@ -0,0 +1,470 @@
|
|||
import CryptoBox
|
||||
import WebInterfaceDataset
|
||||
import re
|
||||
|
||||
class WebInterfaceSites:
|
||||
'''
|
||||
url2func = {'index':'show_status','doc':'show_doc','logs':'show_log'}
|
||||
'''
|
||||
|
||||
|
||||
def __init__(self):
|
||||
import logging
|
||||
self.cbox = CryptoBox.CryptoBoxProps()
|
||||
self.log = logging.getLogger("CryptoBox")
|
||||
self.prefs = self.cbox.cbxPrefs
|
||||
self.__resetDataset()
|
||||
|
||||
|
||||
def __resetDataset(self):
|
||||
self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs)
|
||||
|
||||
|
||||
def __isHDAvailable(self):
|
||||
#TODO: implement this
|
||||
return True
|
||||
|
||||
|
||||
def __check_config(self):
|
||||
#TODO: from now on a cryptobox is always configured
|
||||
return True
|
||||
|
||||
|
||||
def __check_init_running(self):
|
||||
#TODO: implement this check (is mkfs still running?)
|
||||
return False
|
||||
|
||||
|
||||
######################################################################
|
||||
## put real sites down here and don't forget to expose them at the end
|
||||
|
||||
def logs(self, weblang=""):
|
||||
'''displays a HTML version of the logfile
|
||||
'''
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
self.dataset["Data.Log"] = "<br/>".join(self.cbox.getLogData(lines=30, maxSize=2000))
|
||||
return self.__render("show_log")
|
||||
|
||||
|
||||
def status(self, weblang=""):
|
||||
'''shows the current status of the box
|
||||
'''
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if not self.__check_config():
|
||||
self.dataset["Data.Warning"] = "NotInitialized"
|
||||
return self.__render("form_init")
|
||||
elif self.__check_init_running():
|
||||
self.dataset["Data.Warning"] = "InitNotFinished"
|
||||
self.dataset["Data.Redirect.Action"] = "form_config"
|
||||
self.dataset["Data.Redirect.Delay"] = "30"
|
||||
return self.__render("empty")
|
||||
else:
|
||||
self.dataset["Data.Redirect.Delay"] = "60"
|
||||
return self.__render("show_status")
|
||||
|
||||
|
||||
def config(self,weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
pass
|
||||
|
||||
|
||||
def doc(self,page="",weblang=""):
|
||||
'''prints the offline wikipage
|
||||
'''
|
||||
import re
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
|
||||
## check for invalid characters
|
||||
if page and not re.search(u'\W', page):
|
||||
self.dataset["Data.Doc.Page"] = page
|
||||
else:
|
||||
## display this page as default help page
|
||||
self.dataset["Data.Doc.Page"] ="CryptoBoxUser"
|
||||
|
||||
return self.__render("show_doc")
|
||||
|
||||
|
||||
def system(self, shutdowntype="", weblang=""):
|
||||
# TODO: check weblang
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if shutdowntype == "reboot":
|
||||
self.dataset["Data.Success"] = "ReBoot"
|
||||
self.dataset["Data.Redirect.Action"] = "show_status"
|
||||
self.dataset["Data.Redirect.Delay"] = "180"
|
||||
self.log.info("TODO: call function for system reboot")
|
||||
elif shutdowntype == "poweroff":
|
||||
self.dataset["Data.Success"] = "PowerOff"
|
||||
self.log.info("TODO: call function for system shutdown")
|
||||
else:
|
||||
self.log.warn("This shutdown-mode (%s) is not supported." % shutdowntype)
|
||||
return self.__render("form_system")
|
||||
|
||||
|
||||
def index(self, weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
return self.__render("show_status")
|
||||
|
||||
|
||||
def show_volume(self, device="", weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if self.__setDevice(device):
|
||||
return self.__render("show_volume")
|
||||
else:
|
||||
if self.cbox.getContainerList():
|
||||
return self.__render("show_volumes")
|
||||
else:
|
||||
return self.__render("show_status")
|
||||
|
||||
|
||||
def show_volumes(self, weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
return self.__render("show_volumes")
|
||||
|
||||
|
||||
def volume_name_set(self, device="", volume_name="", weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if self.__setDevice(device):
|
||||
volume_name = volume_name.strip()
|
||||
if self.__checkVolumeName(volume_name):
|
||||
container = self.cbox.getContainer(device)
|
||||
try:
|
||||
container.setName(volume_name)
|
||||
# TODO: specify the possible exceptions
|
||||
except Exception:
|
||||
self.log.warn("failed to rename the volume '%s' to '%s'" % (device, volume_name))
|
||||
self.dataset["Data.Warning"] = "SetVolumeNameFailed"
|
||||
else:
|
||||
self.log.info("successfully renamed volume '%s' to '%s'" % (device, volume_name))
|
||||
# reread the dataset
|
||||
self.__resetDataset()
|
||||
self.dataset.setCurrentDiskState(device)
|
||||
else:
|
||||
self.dataset["Data.Warning"] = "InvalidVolumeName"
|
||||
return self.__render("show_volume")
|
||||
else:
|
||||
if self.cbox.getContainerList():
|
||||
return self.__render("show_volumes")
|
||||
else:
|
||||
return self.__render("show_status")
|
||||
|
||||
|
||||
def mount_do(self, device, crypto_password=None, weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if self.__setDevice(device):
|
||||
container = self.cbox.getContainer(device)
|
||||
if container.isMounted():
|
||||
self.dataset["Data.Warning"] = "IsMounted"
|
||||
self.log.warn("the device (%s) is already mounted" % device)
|
||||
else:
|
||||
try:
|
||||
if container.getType() == container.Types["luks"]:
|
||||
## encrypted luks container
|
||||
if not crypto_password:
|
||||
self.dataset["Data.Warning"] = "EmptyCryptoPassword"
|
||||
self.log.warn("no password was supplied for mounting of device '%s'" % device)
|
||||
return self.__render("show_volume")
|
||||
else:
|
||||
container.mount(crypto_password)
|
||||
elif container.getType() == container.Types["plain"]:
|
||||
## plain container
|
||||
container.mount()
|
||||
else:
|
||||
## mounting is not possible
|
||||
# TODO: wrong warning message - replace it
|
||||
self.dataset["Data.Warning"] = "MountFailed"
|
||||
self.log.warn("this type of container (%s) cannot be mounted - sorry!" % device)
|
||||
except (Exception, "MountError"):
|
||||
self.dataset["Data.Warning"] = "MountFailed"
|
||||
self.log.warn("failed to mount the device (%s)" % device)
|
||||
else:
|
||||
self.log.info("successfully mounted the container (%s)" % device)
|
||||
# reread the dataset
|
||||
self.__resetDataset()
|
||||
self.dataset.setCurrentDiskState(device)
|
||||
else:
|
||||
if self.cbox.getContainerList():
|
||||
return self.__render("show_volumes")
|
||||
else:
|
||||
return self.__render("show_status")
|
||||
return self.__render("show_volume")
|
||||
|
||||
|
||||
def volume_init_ask(self, device, encryption=None, weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if self.__setDevice(device):
|
||||
container = self.cbox.getContainer(device)
|
||||
if container.isMounted():
|
||||
self.dataset["Data.Warning"] = "VolumeMayNotBeMounted"
|
||||
self.log.warn("initialization is not possible as long as the device (%s) is mounted" % device)
|
||||
return self.__render("show_volume")
|
||||
else:
|
||||
if encryption is None:
|
||||
self.dataset["Data.Init.isCrypto"] = 0
|
||||
else:
|
||||
self.dataset["Data.Init.isCrypto"] = 1
|
||||
return self.__render("form_init")
|
||||
else:
|
||||
if self.cbox.getContainerList():
|
||||
return self.__render("show_volumes")
|
||||
else:
|
||||
return self.__render("show_status")
|
||||
|
||||
|
||||
def init_do(self, device, confirm, crypto_password=None, crypto_password2=None, encryption=None, weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if self.__setDevice(device):
|
||||
container = self.cbox.getContainer(device)
|
||||
## set 'Data.Init.isCrypto' - just in case, we have to show the same form again
|
||||
if encryption is None:
|
||||
self.dataset["Data.Init.isCrypto"] = 0
|
||||
else:
|
||||
self.dataset["Data.Init.isCrypto"] = 1
|
||||
if container.isMounted():
|
||||
self.dataset["Data.Warning"] = "VolumeMayNotBeMounted"
|
||||
self.log.warn("initialization is not possible as long as the device (%s) is mounted" % device)
|
||||
return self.__render("form_init")
|
||||
else:
|
||||
# TODO: we have to compare 'confirm' with the value in the language file - IMPORTANT!
|
||||
if not confirm:
|
||||
self.dataset["Data.Warning"] = "InitNotConfirmed"
|
||||
self.log.warn("the confirmation sentence for initialization of the device '%s' was wrong" % device)
|
||||
return self.__render("form_init")
|
||||
try:
|
||||
if not encryption is None:
|
||||
if not crypto_password:
|
||||
self.dataset["Data.Warning"] = "EmptyCryptoPassword"
|
||||
self.log.warn("no crypto password was supplied for initialization of device '%s'" % device)
|
||||
return self.__render("form_init")
|
||||
if crypto_password != crypto_password2:
|
||||
self.dataset["Data.Warning"] = "DifferentCryptoPasswords"
|
||||
self.log.warn("the crypto password was not repeated correctly for initialization of device '%s'" % device)
|
||||
return self.__render("form_init")
|
||||
container.create(container.Types["luks"], crypto_password)
|
||||
else:
|
||||
container.create(container.Types["plain"])
|
||||
# TODO: specify the exception
|
||||
except Exception, errMsg:
|
||||
# TODO: wrong error/warning message - change it
|
||||
self.dataset["Data.Error"] = "InitFailed"
|
||||
self.log.warn("initialization of device '%s' failed" % device)
|
||||
self.log.warn("reason: %s" % errMsg)
|
||||
return self.__render("form_init")
|
||||
else:
|
||||
self.log.info("successfully initialized device '%s'" % device)
|
||||
# reread the dataset
|
||||
self.__resetDataset()
|
||||
self.dataset.setCurrentDiskState(device)
|
||||
return self.__render("show_volume")
|
||||
else:
|
||||
if self.cbox.getContainerList():
|
||||
return self.__render("show_volumes")
|
||||
else:
|
||||
return self.__render("show_status")
|
||||
|
||||
|
||||
def test(self):
|
||||
self.__resetDataset()
|
||||
return "test passed"
|
||||
|
||||
|
||||
def umount_do(self, device, weblang=""):
|
||||
self.__resetDataset()
|
||||
self.__setWebLang(weblang)
|
||||
if self.__setDevice(device):
|
||||
container = self.cbox.getContainer(device)
|
||||
if not container.isMounted():
|
||||
self.dataset["Data.Warning"] = "NotMounted"
|
||||
self.log.warn("the device (%s) is currently not mounted" % device)
|
||||
else:
|
||||
try:
|
||||
if container.getType() == container.Types["luks"]:
|
||||
## encrypted luks container
|
||||
container.umount()
|
||||
elif container.getType() == container.Types["plain"]:
|
||||
## plain container
|
||||
container.umount()
|
||||
else:
|
||||
## mounting is not possible
|
||||
# TODO: wrong warning message - replace it
|
||||
self.dataset["Data.Warning"] = "UmountFailed"
|
||||
self.log.warn("this type of container (%s) cannot be umounted - sorry!" % device)
|
||||
except (Exception, "UmountError"):
|
||||
self.dataset["Data.Warning"] = "UmountFailed"
|
||||
self.log.warn("failed to unmount the device (%s)" % device)
|
||||
else:
|
||||
self.log.info("successfully unmounted the container (%s)" % device)
|
||||
# reread the dataset
|
||||
self.__resetDataset()
|
||||
self.dataset.setCurrentDiskState(device)
|
||||
else:
|
||||
if self.cbox.getContainerList():
|
||||
return self.__render("show_volumes")
|
||||
else:
|
||||
return self.__render("show_status")
|
||||
return self.__render("show_volume")
|
||||
|
||||
|
||||
'''
|
||||
## DONE: these functions are pythonized
|
||||
#################### show_log #######################
|
||||
##################### doc ############################
|
||||
##################### poweroff ######################
|
||||
##################### reboot ########################
|
||||
|
||||
## but there are even more TODO
|
||||
#-------------------------------------------------------#
|
||||
# here you may define all cases that require a harddisk #
|
||||
#-------------------------------------------------------#
|
||||
################ umount_do #######################
|
||||
elif action == "unmount_do":
|
||||
if not device:
|
||||
self.log.debug("invalid device chosen: %s" device
|
||||
settings["Data.Warning"] = "InvalidDevice"
|
||||
settings["Data.Action"] = "empty"
|
||||
elif not True: #TODO: replace True with check_config()
|
||||
settings["Data.Warning"] = "NotInitialized"
|
||||
settings["Data.Action"] = "form_init"
|
||||
elif True: #TODO: replace True with check_init_running()
|
||||
settings["Data.Warning"] = "InitNotFinished"
|
||||
settings["Data.Action"] = "empty"
|
||||
settings["Data.Redirect.Action"] = "form_config"
|
||||
settings["Data.Redirect.Delay"] = "30"
|
||||
elif not True: #TODO: replace True with check_mounted(device)
|
||||
settings["Data.Warning"] = "NotMounted"
|
||||
settings["Data.Action"] = "show_volume"
|
||||
else: #unmount
|
||||
#TODO: replace this line with umount_vol(device)
|
||||
if True: #TODO: replace True with check_mounted(device)
|
||||
settings["Data.Warning"] = "UmountFailed"
|
||||
settings["Data.Action"] = "show_volume"
|
||||
else:
|
||||
settings["Data.Action"] = "show_volume"
|
||||
################ mount_do ########################
|
||||
elif action == "mount_do":
|
||||
if device:
|
||||
pass #TODO: is_encrypted = check_device_encryption(device)
|
||||
else:
|
||||
self.log.debug("invalid device chosen: %s" device
|
||||
settings["Data.Warning"] = "InvalidDevice"
|
||||
settings["Data.Action"] = "empty"
|
||||
elif not True: #TODO: replace True with check_config()
|
||||
settings["Data.Warning"] = "NotInitialized"
|
||||
settings["Data.Action"] = "form_init"
|
||||
#at cryptobox.pl line 568
|
||||
'''
|
||||
|
||||
|
||||
##################### input checker ##########################
|
||||
def __setWebLang(self, value):
|
||||
## TODO: add some code to evaluate the language setting of the browser
|
||||
guess = value
|
||||
availLangs = self.cbox.getAvailableLanguages()
|
||||
## TODO: add some warnings for an invalid choosen language
|
||||
if not guess or \
|
||||
not guess in availLangs or \
|
||||
re.search(u'\W', guess):
|
||||
guess = self.prefs["WebSettings"]["Language"]
|
||||
## maybe the language is still not valid
|
||||
if not guess in availLangs:
|
||||
self.log.warn("the configured language is invalid: %s" % guess)
|
||||
guess = availLangs[0]
|
||||
self.dataset["Settings.Language"] = guess
|
||||
self.dataset["Settings.DocLang"] = guess
|
||||
self.dataset["Settings.LinkAttrs.weblang"] = guess
|
||||
|
||||
|
||||
def __setDevice(self, device):
|
||||
if device and re.match(u'[\w /\-]+$', device) and self.cbox.getContainer(device):
|
||||
self.log.debug("select device: %s" % device)
|
||||
self.dataset.setCurrentDiskState(device)
|
||||
return True
|
||||
else:
|
||||
self.log.warn("invalid device: %s" % device)
|
||||
self.dataset["Data.Warning"] = "InvalidDevice"
|
||||
return False
|
||||
|
||||
|
||||
def __checkVolumeName(self, name):
|
||||
if name and re.match(u'[\w \-]+$', name):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def __render(self, template):
|
||||
'''renders from clearsilver templates and returns the resulting html
|
||||
|
||||
Gets a dictionary with all settings, nessessary for rendering.
|
||||
In fact the dictionary is a copy of the CryptoBoxWerbserverSite
|
||||
object, that calls this render method. This might be bloat but
|
||||
this way the render method has always a complete, actual set of values.
|
||||
'''
|
||||
|
||||
import os
|
||||
try:
|
||||
import neo_cgi, neo_util, neo_cs
|
||||
except ImportError:
|
||||
errorMsg = "Could not import clearsilver modules. Try 'apt-get install python-clearsilver'."
|
||||
self.log.error(errorMsg)
|
||||
sys.stderr.write(errorMsg)
|
||||
raise ImportError, errorMsg
|
||||
|
||||
self.dataset["Data.Action"] = template
|
||||
self.log.info("rendering site: " + template)
|
||||
|
||||
cs_path = os.path.join(self.prefs["Locations"]["TemplateDir"], "main.cs")
|
||||
if not os.access(cs_path, os.R_OK):
|
||||
log.error("Couldn't read clearsilver file: %s" % cs_path)
|
||||
return "Couldn't read clearsilver file: %s" % cs_path
|
||||
|
||||
# use the user selected language instead of the configured
|
||||
hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], self.dataset["Settings.Language"] + ".hdf")
|
||||
if not os.access(hdf_path, os.R_OK):
|
||||
log.error("Couldn't read language file: %s" % hdf_path)
|
||||
return "Couldn't read language file: %s" % hdf_path
|
||||
|
||||
hdf = neo_util.HDF()
|
||||
hdf.readFile(hdf_path)
|
||||
self.log.debug(self.dataset)
|
||||
for key in self.dataset.keys():
|
||||
hdf.setValue(key,str(self.dataset[key]))
|
||||
cs = neo_cs.CS(hdf)
|
||||
cs.parseFile(cs_path)
|
||||
return cs.render()
|
||||
|
||||
|
||||
############################################################################
|
||||
## to make the sites visible through the webserver they must be exposed here
|
||||
index.exposed = True
|
||||
doc.exposed = True
|
||||
logs.exposed = True
|
||||
system.exposed = True
|
||||
status.exposed = True
|
||||
show_volume.exposed = True
|
||||
volume_name_set.exposed = True
|
||||
mount_do.exposed = True
|
||||
volume_init_ask.exposed = True
|
||||
init_do.exposed = True
|
||||
umount_do.exposed = True
|
||||
show_volumes.exposed = True
|
||||
test.exposed = True
|
||||
|
||||
|
||||
"""
|
||||
## TODO: check this before anything else
|
||||
if self.cbox.getAvailableDocLanguages():
|
||||
self.dataset["Data.Error"] = "NoDocumentation"
|
||||
return self.__render("show_status")
|
||||
"""
|
|
@ -59,7 +59,7 @@ Stylesheet = /cryptobox-misc/cryptobox.css
|
|||
Language = de
|
||||
|
||||
# default language for documentation
|
||||
DocLang = de
|
||||
DocLanguage = de
|
||||
|
||||
|
||||
[Programs]
|
||||
|
|
|
@ -14,6 +14,7 @@ Lang {
|
|||
Log = Protokoll der CryptoBox
|
||||
System = System
|
||||
Status = Status der CryptoBox
|
||||
Volume = Eigenschaften von
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +41,12 @@ Lang {
|
|||
Configuration = Einstellungen
|
||||
CryptoIsActive = Die Crypto-Daten sind verfügbar.
|
||||
CryptoIsDown = Die Crypto-Daten sind vor jedem Zugriff geschützt.
|
||||
ChoosePartition = Welchen Daten-Container möchtest du auswählen?
|
||||
ChosenPartition = Der aktuelle Daten-Container ist
|
||||
ActivePartitions = Die folgenden Daten-Container sind derzeit aktiv
|
||||
PassivePartitions = Die folgenden Daten-Container sind derzeit inaktiv
|
||||
ContainerName = Der Name des Daten-Containers
|
||||
ContainerEncryption = Aktiviere Verschlüsselung
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,6 +63,8 @@ Lang {
|
|||
Documentation = Hilfe
|
||||
Status = Status
|
||||
System = System
|
||||
ContainerNameSet = Setze den neuen Namen
|
||||
InitContainer = Reinitialisiere den Container
|
||||
}
|
||||
|
||||
|
||||
|
@ -154,6 +163,36 @@ Lang {
|
|||
Title = Änderung der Netzwerk-Adresse
|
||||
Text = Die Netzwerk-Adresse der CryptoBox wurde verändert. In wenigen Sekunden werden sie zu der neuen Adresse umgeleitet.
|
||||
}
|
||||
|
||||
NoDiskAvailableForMount {
|
||||
Title = Kein Daten-Container verfügbar
|
||||
Text = Es ist kein inaktiver Daten-Container verfügbar. Vielleicht sind bereits alle Container aktiv?
|
||||
}
|
||||
|
||||
NoDiskAvailableForUmount {
|
||||
Title = Kein Daten-Container verfügbar
|
||||
Text = Kein Daten-Container ist aktiv. Vielleicht wurden alle Container deaktiviert.
|
||||
}
|
||||
|
||||
InvalidDevice {
|
||||
Title = Ungültiger Container
|
||||
Text = Der angegebene Daten-Container ist nicht zulässig.
|
||||
}
|
||||
|
||||
InvalidVolumeName {
|
||||
Title = Umbenennung fehlgeschlagen
|
||||
Text = Der gewählte neue Name des Containers ist ungültig. Versuche es erneut.
|
||||
}
|
||||
|
||||
SetVolumeNameFailed {
|
||||
Title = Umbenennung fehlgeschlagen
|
||||
Text = Die Umbenennung des Containers schlug fehl. Details findest du in der Log-Datei.
|
||||
}
|
||||
|
||||
VolumeMayNotBeMounted {
|
||||
Title = Der Container ist derzeit aktiv
|
||||
Text = Die gewünschte Aktion kann nicht durchgeführt werden, solange der Container aktiv ist.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ Lang {
|
|||
ChosenPartition = The chosen container is
|
||||
ActivePartitions = The following containers are enabled
|
||||
PassivePartitions = The following containers are disabled
|
||||
ContainerName = Container's name:
|
||||
ContainerName = Container's name
|
||||
ContainerEncryption = Enable encryption
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div id="config">
|
||||
<h1><?cs var:html_escape(Lang.Title.Config) ?></h1>
|
||||
|
||||
<?cs call:print_form_header() ?>
|
||||
<?cs call:print_form_header("config_do") ?>
|
||||
<?cs if:Data.Config.AdminPasswordIsSet ?>
|
||||
<p><label for="current_admin_password"><?cs var:html_escape(Lang.Text.EnterCurrentAdminPassword) ?></label><br/>
|
||||
<input type="password" id="current_admin_password" name="current_admin_password" size="20" maxlength="40" /> </p>
|
||||
|
@ -26,7 +26,6 @@
|
|||
<?cs /each ?>
|
||||
</select></p>
|
||||
|
||||
<input type="hidden" name="action" value="config_do" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Button.SaveConfig) ?></button>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -3,14 +3,19 @@
|
|||
<h1><?cs var:html_escape(Lang.Title.Init) ?></h1>
|
||||
|
||||
<div class="init">
|
||||
<?cs call:print_form_header() ?>
|
||||
<?cs call:print_form_header("init_do") ?>
|
||||
|
||||
<p class="note"><?cs var:html_escape(Lang.Text.InitWarning) ?></p>
|
||||
<p><label for="confirm"><?cs var:html_escape(Lang.Text.ConfirmInitHint) ?><br/>
|
||||
<span class="note" id="confirmtext"><?cs var:html_escape(Lang.Text.ConfirmInit)
|
||||
?></span></label><br/>
|
||||
<input type="text" id="confirm" name="confirm" size="30" maxlength="50" /></p>
|
||||
<input type="hidden" name="action" value="init_do" />
|
||||
<?cs if:Data.Init.isCrypto ?>
|
||||
<p><label for="crypto_password"><?cs var:html_escape(Lang.Text.EnterNewCryptoPassword) ?></label> <input type="password" id="crypto_password" name="crypto_password" /></p>
|
||||
<p><label for="crypto_password2"><?cs var:html_escape(Lang.Text.EnterSameCryptoPassword) ?></label> <input type="password" id="crypto_password2" name="crypto_password2" /></p>
|
||||
<input type="hidden" name="encryption" value="1" />
|
||||
<?cs /if ?>
|
||||
<input type="hidden" name="device" value="<?cs var:Data.CurrentDisk.device ?>" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Button.DoInit) ?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<h1><?cs var:html_escape(Lang.Title.Init) ?></h1>
|
||||
|
||||
<?cs call:print_form_header() ?>
|
||||
<?cs call:print_form_header("volume_init_do") ?>
|
||||
|
||||
<p class="note"><?cs var:html_escape(Lang.Text.InitWarning) ?></p>
|
||||
<?cs if:Data.Config.AdminPasswordIsSet ?>
|
||||
|
@ -27,7 +27,6 @@
|
|||
<input type="text" id="confirm" name="confirm" size="30" maxlength="50" /></p>
|
||||
|
||||
<p><input type="hidden" name="device" value="<?cs var:html_escape(Data.CurrentDisk.device) ?>" />
|
||||
<input type="hidden" name="action" value="volume_init_do" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Button.InitContainer) ?></button></p>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<div align="center">
|
||||
|
||||
<?cs call:print_form_header() ?>
|
||||
<?cs call:print_form_header("mount_do") ?>
|
||||
|
||||
<?cs if:subcount(Data.Disks.passive) > 1 ?>
|
||||
<p><label for="device"><?cs var:html_escape(Lang.Text.ChoosePartition) ?></label>
|
||||
|
@ -30,7 +30,6 @@
|
|||
?></label>
|
||||
<input type="password" id="crypto_password" name="crypto_password" size="20" maxlength="40" /></p>
|
||||
|
||||
<input type="hidden" name="action" value="mount_do" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Button.Mount) ?></button>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?cs # $Id$ ?>
|
||||
|
||||
<?cs if:subcount(Data.Disks.active) == 0 ?>
|
||||
<?cs if:Data.activeDisksCount == 0 ?>
|
||||
|
||||
<?cs call:warning('NoDiskAvailableForUmount') ?>
|
||||
|
||||
|
@ -9,25 +9,28 @@
|
|||
<h1><?cs var:html_escape(Lang.Title.Umount) ?></h1>
|
||||
|
||||
<div align="center">
|
||||
<?cs call:print_form_header() ?>
|
||||
<?cs call:print_form_header("umount_do") ?>
|
||||
|
||||
<?cs if:subcount(Data.Disks.active) > 1 ?>
|
||||
<?cs if:Data.activeDisksCount > 1 ?>
|
||||
<p><label for="device"><?cs var:html_escape(Lang.Text.ChoosePartition) ?></label>
|
||||
<select name="device" id="device" size="0">
|
||||
<?cs each:partition = Data.Disks.active ?><option value="<?cs
|
||||
<?cs each:partition = Data.Disks
|
||||
?><?cs if:partition.active ?><option value="<?cs
|
||||
var:partition.device ?>"><?cs
|
||||
var:partition.name ?></option>
|
||||
var:partition.name ?></option><?cs /if ?>
|
||||
<?cs /each ?>
|
||||
</select></p>
|
||||
<?cs else ?>
|
||||
<?cs # the perl code should take care, that there is at least
|
||||
one mounted disk - otherwise it should display a warning ?>
|
||||
<?cs each:partition = Data.Disks ?><?cs
|
||||
if:partition.active ?><?cs set:act_name = partition.name ?><?cs
|
||||
act_device = partition.device ?><?cs /if ?><?cs /each ?>
|
||||
<p><?cs var:html_escape(Lang.Text.ChosenPartition) ?>: <?cs
|
||||
var:Data.Disks.active.0.name ?></p>
|
||||
var:act_name ?></p>
|
||||
<input type="hidden" name="device" value="<?cs
|
||||
var:Data.Disks.active.0.device ?>"/>
|
||||
var:act_device ?>"/>
|
||||
<?cs /if ?>
|
||||
<input type="hidden" name="action" value="umount_do" />
|
||||
<button type="submit"><?cs var:html_escape(Lang.Button.Umount) ?></button>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<?cs if:subcount(Data.Disks.available) > 0 ?>
|
||||
<?cs if:subcount(Data.Disks) > 0 ?>
|
||||
<div id="volumes">
|
||||
<?cs include:Settings.TemplateDir + '/show_volumes.cs' ?>
|
||||
</div>
|
||||
|
@ -24,14 +24,13 @@
|
|||
|
||||
<div id="lang">
|
||||
<?cs each:item = Data.Languages ?>
|
||||
<a href="<?cs call:link('weblang',name(item),'','','') ?><?cs
|
||||
if:Data.QueryString ?>&<?cs var:Data.QueryString ?><?cs /if ?>"><?cs
|
||||
<a href="<?cs call:link('','weblang',name(item),'','') ?>"><?cs
|
||||
var:item ?></a><br/>
|
||||
<?cs /each ?>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
<?cs if:subcount(Data.Disks.active) > 0 ?>
|
||||
<?cs if:Data.activeDisksCount > 0 ?>
|
||||
<div id="head_red">
|
||||
<?cs else ?>
|
||||
<div id="head_green">
|
||||
|
|
|
@ -75,8 +75,8 @@ def:link(path, attr1, value1, attr2, value2)
|
|||
?><?cs /if ?><?cs
|
||||
/def ?><?cs
|
||||
|
||||
def:print_form_header() ?><?cs #
|
||||
def:print_form_header(action) ?><?cs #
|
||||
# the header of a form - including Setting.LinkAttrs
|
||||
?><form action="<?cs call:link("","","","","") ?>" method="post" enctype="application/x-www-from-urlencoded" accept-charset="utf-8"><?cs
|
||||
?><form action="<?cs call:link(action,"","","","") ?>" method="post" enctype="application/x-www-from-urlencoded" accept-charset="utf-8"><?cs
|
||||
/def ?>
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
<!-- TODO: remove the following lines, as soon as we completely switched to the volume-based user interface
|
||||
<?cs if:subcount(Data.Disks.passive) > 0 ?>
|
||||
<a href="<?cs call:link('mount_ask','','','','') ?>" title="<?cs var:html_escape(Lang.Text.DoMount) ?>"><?cs var:html_escape(Lang.Button.Mount) ?></a><?cs /if ?>
|
||||
<?cs if:subcount(Data.Disks.active) > 0 ?>
|
||||
<?cs if:Data.activeDisksCount > 0 ?>
|
||||
<a href="<?cs call:link('umount_ask','','','','') ?>" title="<?cs var:html_escape(Lang.Text.DoUmount) ?>"><?cs var:html_escape(Lang.Button.Umount) ?></a><?cs /if ?>
|
||||
-->
|
||||
|
||||
<a href="<?cs if:subcount(Data.Disks.available) > 1
|
||||
<a href="<?cs if:subcount(Data.Disks) > 1
|
||||
?><?cs call:link('show_status','','','','')
|
||||
?><?cs else
|
||||
?><?cs call:link('show_volume','device',Data.Disks.available.0.device,'','')
|
||||
?><?cs call:link('show_volume','device',Data.Disks.0.device,'','')
|
||||
?><?cs /if
|
||||
?>" title="<?cs var:html_escape(Lang.Button.Status) ?>"><?cs var:html_escape(Lang.Button.Status) ?></a>
|
||||
<?cs /if ?>
|
||||
|
|
|
@ -2,27 +2,27 @@
|
|||
|
||||
<h1><?cs var:html_escape(Lang.Title.Status) ?></h1>
|
||||
|
||||
<?cs if:subcount(Data.Disks.available) == 0 ?>
|
||||
<?cs if:subcount(Data.Disks) == 0 ?>
|
||||
<?cs # there are no partitions available ?>
|
||||
<?cs # this case may never be true, as it should trigger a warning before ?>
|
||||
<p>Sorry - you should have never seen this ...</p>
|
||||
<?cs # elif:subcount(Data.Disks.active) == subcount(Data.Disks.available) ?>
|
||||
<?cs # elif:Data.activeDisksCount == subcount(Data.Disks) ?>
|
||||
<?cs # all available disks are mounted ?>
|
||||
<?cs # we do not use this special condition now - or should we? ?>
|
||||
<?cs # elif:subcount(Data.Disks.passive) == subcount(Data.Disks.available) ?>
|
||||
<?cs # elif:subcount(Data.Disks.passive) == subcount(Data.Disks) ?>
|
||||
<?cs # no available disk is mounted ?>
|
||||
<?cs # we do not use this special condition now - or should we? ?>
|
||||
<?cs else ?>
|
||||
<?cs # some are mounted - and some are not ... ?>
|
||||
<?cs if:subcount(Data.Disks.active) > 0 ?>
|
||||
<?cs if:Data.activeDisksCount > 0 ?>
|
||||
<p><?cs var:html_escape(Lang.Text.ActivePartitions) ?>:
|
||||
<ul><?cs each:partition = Data.Disks.active ?>
|
||||
<ul><?cs each:partition = Data.Disks ?><?cs if:partition.active ?>
|
||||
<li><a href="<?cs call:link('show_volume','device',partition.device,'','')
|
||||
?>"><?cs var:partition.name ?></a></li><?cs /each ?></ul><?cs /if ?>
|
||||
<?cs if:subcount(Data.Disks.passive) > 0 ?>
|
||||
?>"><?cs var:partition.name ?></a></li><?cs /if ?><?cs /each ?></ul><?cs /if ?>
|
||||
<?cs if:Data.activeDisksCount < subcount(Data.Disks) ?>
|
||||
<p><?cs var:html_escape(Lang.Text.PassivePartitions) ?>:
|
||||
<ul><?cs each:partition = Data.Disks.passive ?>
|
||||
<ul><?cs each:partition = Data.Disks ?><?cs if:partition.active ?>
|
||||
<li><a href="<?cs call:link('show_volume','device',partition.device,'','')
|
||||
?>"><?cs var:partition.name ?></a></li><?cs /each ?></ul><?cs /if ?>
|
||||
?>"><?cs var:partition.name ?></a></li><?cs /if ?><?cs /each ?></ul><?cs /if ?>
|
||||
<?cs /if ?>
|
||||
|
||||
|
|
|
@ -7,21 +7,19 @@
|
|||
<?cs # is the disc active? ?>
|
||||
<?cs if:!Data.CurrentDisk.active ?>
|
||||
<h2>Mount container</h2>
|
||||
<?cs call:print_form_header() ?>
|
||||
<?cs call:print_form_header("mount_do") ?>
|
||||
<p>
|
||||
<?cs if:Data.CurrentDisk.encryption ?>
|
||||
<label for="crypto_passwort"><?cs var:html_escape(Lang.Text.EnterCurrentCryptoPassword) ?></label>
|
||||
<input type="password" id="crypto_password" name="crypto_password" size="20" maxlength="40" />
|
||||
< |