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]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue