From 112979b3afd5c364813b3878a2b51a8631a97d4c Mon Sep 17 00:00:00 2001 From: lars Date: Thu, 23 Nov 2006 19:13:08 +0000 Subject: [PATCH] added setup.py to use distutils for packaging moved python modules to separate packages below src/ renamed "hook" to "event" to avoid confusion --- CHANGELOG | 0 MANIFEST.in | 8 + ...BoxRootActions.py => CryptoBoxRootActions} | 0 bin/CryptoBoxWebserver | 173 ++++++++++++++++++ bin/CryptoBoxWebserver.py | 110 ----------- bin/cryptobox.conf | 2 +- bin/run_webserver.sh | 15 ++ bin/test.complete.CryptoBox.py | 116 ------------ debian/control | 3 +- debian/cryptobox.default | 12 +- debian/cryptobox.init | 72 ++++---- debian/postinst | 2 +- debian/rules | 5 +- {hook-scripts => event-scripts}/README | 0 {hook-scripts => event-scripts}/apache2_dav | 0 {hook-scripts => event-scripts}/samba | 0 plugins/date/date.py | 4 +- plugins/disks/disks.py | 4 +- plugins/help/help.py | 4 +- .../language_selection/language_selection.py | 4 +- plugins/logs/logs.py | 4 +- plugins/network/network.py | 4 +- plugins/partition/partition.py | 26 ++- plugins/plugin_manager/plugin_manager.py | 8 +- plugins/shutdown/shutdown.py | 4 +- .../system_preferences/system_preferences.py | 4 +- plugins/user_manager/user_manager.py | 4 +- plugins/volume_automount/volume_automount.py | 6 +- plugins/volume_chpasswd/volume_chpasswd.py | 6 +- plugins/volume_details/volume_details.py | 4 +- plugins/volume_format_fs/format_fs.py | 6 +- plugins/volume_format_fs/volume_format_fs.py | 6 +- plugins/volume_mount/volume_mount.py | 6 +- plugins/volume_props/volume_props.py | 12 +- plugins/volume_rename/volume_rename.py | 6 +- setup.py | 59 ++++++ src/__init__.py | 1 + src/core/__init__.py | 0 .../core/container.py | 49 +++-- .../core/exceptions.py | 8 +- bin/CryptoBox.py => src/core/main.py | 31 ++-- .../core/settings.py | 48 ++--- bin/CryptoBoxTools.py => src/core/tools.py | 0 src/plugins/__init__.py | 0 bin/CryptoBoxPlugin.py => src/plugins/base.py | 0 bin/Plugins.py => src/plugins/manage.py | 0 src/tests/__init__.py | 0 .../tests/cryptobox.py | 2 +- .../tests/cryptoboxtools.py | 0 .../tests/plugins.py | 4 +- .../tests/websites.py | 6 +- src/web/__init__.py | 0 .../web/dataset.py | 24 +-- bin/WebInterfaceSites.py => src/web/sites.py | 16 +- .../web/testclass.py | 4 +- 55 files changed, 470 insertions(+), 422 deletions(-) create mode 100644 CHANGELOG create mode 100644 MANIFEST.in rename bin/{CryptoBoxRootActions.py => CryptoBoxRootActions} (100%) create mode 100755 bin/CryptoBoxWebserver delete mode 100755 bin/CryptoBoxWebserver.py create mode 100755 bin/run_webserver.sh delete mode 100755 bin/test.complete.CryptoBox.py rename {hook-scripts => event-scripts}/README (100%) rename {hook-scripts => event-scripts}/apache2_dav (100%) rename {hook-scripts => event-scripts}/samba (100%) create mode 100644 setup.py create mode 100644 src/__init__.py create mode 100644 src/core/__init__.py rename bin/CryptoBoxContainer.py => src/core/container.py (95%) mode change 100755 => 100644 rename bin/CryptoBoxExceptions.py => src/core/exceptions.py (93%) rename bin/CryptoBox.py => src/core/main.py (89%) mode change 100755 => 100644 rename bin/CryptoBoxSettings.py => src/core/settings.py (85%) rename bin/CryptoBoxTools.py => src/core/tools.py (100%) create mode 100644 src/plugins/__init__.py rename bin/CryptoBoxPlugin.py => src/plugins/base.py (100%) rename bin/Plugins.py => src/plugins/manage.py (100%) create mode 100644 src/tests/__init__.py rename bin/unittests.CryptoBox.py => src/tests/cryptobox.py (99%) rename bin/unittests.CryptoBoxTools.py => src/tests/cryptoboxtools.py (100%) rename bin/unittests.Plugins.py => src/tests/plugins.py (88%) rename bin/unittests.WebSites.py => src/tests/websites.py (83%) create mode 100644 src/web/__init__.py rename bin/WebInterfaceDataset.py => src/web/dataset.py (84%) rename bin/WebInterfaceSites.py => src/web/sites.py (97%) mode change 100755 => 100644 rename bin/WebInterfaceTestClass.py => src/web/testclass.py (95%) diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..e69de29 diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..a857a0a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,8 @@ +include README +graft www-data +#graft www-data/screenshots +graft templates +graft lang +graft plugins +prune commit.log +prune package.exclude diff --git a/bin/CryptoBoxRootActions.py b/bin/CryptoBoxRootActions similarity index 100% rename from bin/CryptoBoxRootActions.py rename to bin/CryptoBoxRootActions diff --git a/bin/CryptoBoxWebserver b/bin/CryptoBoxWebserver new file mode 100755 index 0000000..e396b9d --- /dev/null +++ b/bin/CryptoBoxWebserver @@ -0,0 +1,173 @@ +#!/usr/bin/python2.4 + +import os, sys +import cryptobox.web.sites +from cryptobox.core.exceptions import * +from optparse import OptionParser + +try: + import cherrypy +except: + print "Could not import the cherrypy module! Try 'apt-get install python-cherrypy'." + sys.exit(1) + + +# TODO: change this for the release version +SERVER_ENVIRONMENT = "development" + +class CryptoBoxWebserver: + '''this class starts the cherryp webserver and serves the single sites''' + + def __init__(self, opts): + ## check conffile + if not os.access(opts.conffile, os.R_OK) or not os.path.isfile(opts.conffile): + sys.stderr.write("Error: could not read configuration file (%s)\n" % opts.conffile) + sys.exit(1) + ## store the absolute path as we will chdir later (for daemons) + self.conffile = os.path.realpath(opts.conffile) + ## initialize site class + try: + cherrypy.root = cryptobox.web.sites.WebInterfaceSites(self.conffile) + except (CBConfigError,CBEnvironmentError), errMsg: + sys.stderr.write("Error: the CryptoBox is misconfigured - please fix it!\n") + sys.stderr.write("%s\n" % str(errMsg)) + sys.exit(1) + #expose static content: + #I currently have no idea how to cleanly extract the stylesheet path from + #the config object without an extra cryptobox.core.main.CryptoBoxProps instance. + #perhaps put config handling into a separate class in CryptoBox.py? + # + # the following manual mapping is necessary, as we may not use relative + # paths in the config file + cherrypy.config.update({ + "global": { + "server.socket_port" : int(opts.port), + "server.socket_host" : opts.host, + "server.log_to_screen" : not opts.background and opts.verbose, + "server.log_tracebacks" : opts.verbose, + "server.environment": SERVER_ENVIRONMENT, + "server.log_file" : opts.logfile }, + "/cryptobox-misc": { + "staticFilter.on" : True, + "staticFilter.dir": os.path.realpath(opts.datadir)} + }) + + def start(self): + cherrypy.server.start() + + +def fork_to_background(): + ## this is just copy'n'pasted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731 + ## check the original for exhaustive comments + try: + pid = os.fork() + except OSError, errMsg: + sys.stderr.write("Error: failed to fork cryptobox daemon process!\n") + sys.stderr.write("%s\n" % errMsg) + sys.exit(1) + if pid == 0: # the first child + os.setsid() + try: + pid = os.fork() + except OSError, errMsg: + sys.stderr.write("Error: failed to fork second cryptobox daemon process!\n") + sys.stderr.write("%s\n" % errMsg) + sys.exit(1) + if pid == 0: # the second child + ## we do not change the directory - otherwise there seems to be a race condition with the python interpreter loading this script file + #os.chdir(os.path.sep) + os.umask(0) + else: + os._exit(0) + else: + os._exit(0) + + +def close_open_files(): + """this is only necessary if we want to go into background""" + import resource # Resource usage information. + maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + if (maxfd == resource.RLIM_INFINITY): + maxfd = 1024 + for fd in range(0, maxfd): + try: + os.close(fd) + except OSError: # ERROR, fd wasn't open to begin with (ignored) + pass + os.open(os.devnull, os.O_RDWR) # standard input (0) + os.dup2(0, 1) # standard output (1) + os.dup2(0, 2) # standard error (2) + + +def write_pid_file(pid_file): + try: + pidf = open(pid_file,"w") + pidf.write(str(os.getpid())) + pidf.close() + except (IOError, OSError), errMsg: + sys.stderr.write("Warning: failed to write pid file (%s): %s\n" % (pid_file, errMsg)) + ## it is just a warning - no need to break + + +def parseOptions(): + version = "%prog" + cryptobox.core.main.VERSION + parser = OptionParser(version=version) + parser.set_defaults(conffile="/etc/cryptobox/webserver.conf", + pidfile="/var/run/cryptobox/webserver.pid", + background=False, + datadir="/usr/share/cryptobox/html", + logfile="/var/log/cryptobox/webserver.log", + port="8080", + host="", + verbose=True) + parser.add_option("-c", "--config", dest="conffile", + help="read configuration from FILE", metavar="FILE") + parser.add_option("","--pidfile", dest="pidfile", + help="write process id to FILE", metavar="FILE") + parser.add_option("-B","", dest="background", action="store_true", + help="run webserver in background (as daemon)") + parser.add_option("-q","", dest="verbose", action="store_false", + help="output only errors") + parser.add_option("","--datadir", dest="datadir", metavar="DIR", + help="set data directory to DIR") + parser.add_option("-p","--port", dest="port", metavar="PORT", + help="listen on PORT") + parser.add_option("-l","--logfile", dest="logfile", metavar="FILE", + help="write webserver log to FILE") + parser.add_option("","--host", dest="host", metavar="HOST", + help="attach to HOST") + (options, args) = parser.parse_args() + ## we do not expect any remaining arguments + if len(args) != 0: + parser.error("unknown argument: %s" % str(args[0])) + if not os.path.isdir(options.datadir) or not os.access(options.datadir,os.X_OK): + parser.error("could not access the data directory (%s)" % options.datadir) + try: + if (int(options.port) < 0) or (int(options.port) > 65535): + parser.error("invalid port number: %s" % str(options.port)) + except ValueError: + parser.error("invalid port specified (%s) - it must be a number" % (options.port)) + return options + + +if __name__ == "__main__": + ## process arguments + options = parseOptions() + ## initialize the webserver class (before forking to get some error messages) + cbw = CryptoBoxWebserver(options) + ## run the webserver as a daemon process + if options.background: fork_to_background() + ## write pid file + write_pid_file(options.pidfile) + ## close open files to allow background execution + if options.background: close_open_files() + ## start the webserver + try: + cbw.start() + except CBError, errMsg: + sys.stderr.write("Failed to start the CryptoBox webserver!\n") + sys.stderr.write("%s\n" % str(errMsg)) + sys.stderr.write("Check the log file for details.\n") + sys.exit(1) + sys.exit(0) + diff --git a/bin/CryptoBoxWebserver.py b/bin/CryptoBoxWebserver.py deleted file mode 100755 index 0cc8aa2..0000000 --- a/bin/CryptoBoxWebserver.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/python2.4 -import os -import WebInterfaceSites -from CryptoBoxExceptions import * -import sys - -try: - import cherrypy -except: - print "Could not import the cherrypy module! Try 'apt-get install python-cherrypy'." - sys.exit(1) - - - -## TODO: it should be possible to override this via commandline arguments -PID_FILE = '/var/run/cryptobox/webserver.pid' - -class CryptoBoxWebserver: - '''this class starts the cherryp webserver and serves the single sites''' - - def __init__(self): - try: - cherrypy.root = WebInterfaceSites.WebInterfaceSites() - except (CBConfigError,CBEnvironmentError), errMsg: - sys.stderr.write("The CryptoBox is misconfigured - please fix it!\n") - sys.stderr.write("%s\n" % str(errMsg)) - sys.exit(1) - #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. - #perhaps put config handling into a separate class in CryptoBox.py? - # - # the following manual mapping is necessary, as we may not use relative - # paths in the config file - cherrypy.config.configMap.update({ - "/cryptobox-misc": { - "staticFilter.on" : True, - "staticFilter.dir": os.path.abspath("/usr/share/cryptobox/html" )} - }) - - def start(self): - # just use this config, when we're started directly - cherrypy.config.update(file = "/etc/cryptobox/cryptoboxwebserver.conf") - cherrypy.server.start() - - -def fork_to_background(): - ## this is just copy'n'pasted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731 - ## check the original for exhaustive comments - try: - pid = os.fork() - except OSError, errMsg: - sys.stderr.write("Failed to fork cryptobox daemon process!\n") - sys.stderr.write("%s\n" % errMsg) - sys.exit(1) - if pid == 0: # the first child - os.setsid() - try: - pid = os.fork() - except OSError, errMsg: - sys.stderr.write("Failed to fork second cryptobox daemon process!\n") - sys.stderr.write("%s\n" % errMsg) - sys.exit(1) - if pid == 0: # the second child - os.chdir(os.path.sep) - os.umask(0) - else: - os._exit(0) - else: - os._exit(0) - import resource # Resource usage information. - maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] - if (maxfd == resource.RLIM_INFINITY): - maxfd = 1024 - for fd in range(0, maxfd): - try: - os.close(fd) - except OSError: # ERROR, fd wasn't open to begin with (ignored) - pass - os.open(os.devnull, os.O_RDWR) # standard input (0) - os.dup2(0, 1) # standard output (1) - os.dup2(0, 2) # standard error (2) - - -def write_pid_file(pid_file): - try: - pidf = open(pid_file,"w") - pidf.write(str(os.getpid())) - pidf.close() - except (IOError, OSError), errMsg: - sys.stderr.write("Failed to write pid file (%s): %s\n" % (pid_file, errMsg)) - ## it is just a warning - no need to break - - -if __name__ == "__main__": - ## TODO: add some argument checking: configFile, daemonMode, ... - cbw = CryptoBoxWebserver() - ## run the webserver as a daemon process - fork_to_background() - ## write pid file - write_pid_file(PID_FILE) - try: - cbw.start() - except Exceptions, errMsg: - sys.stderr.write("Failed to start the CryptoBox webserver!\n") - sys.stderr.write("%s\n" % str(errMsg)) - sys.stderr.write("Check the log file for details.\n") - sys.exit(1) - sys.exit(0) - diff --git a/bin/cryptobox.conf b/bin/cryptobox.conf index 5cb08ee..a499cbe 100644 --- a/bin/cryptobox.conf +++ b/bin/cryptobox.conf @@ -38,7 +38,7 @@ TemplateDir = ../templates LangDir = ../lang # path to documentation files -#DocDir = /usr/share/doc/cryptobox/html +#DocDir = /usr/share/doc/cryptobox/www-data DocDir = ../doc/html # path to the plugin directory diff --git a/bin/run_webserver.sh b/bin/run_webserver.sh new file mode 100755 index 0000000..9a36992 --- /dev/null +++ b/bin/run_webserver.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# example start script to run a local cryptobox webserver +# +# we set some en +# + +BIN_DIR=$(dirname "$0") + +## add the local python directory to the search path +export PYTHONPATH="$BIN_DIR/../src" + +## run the webserver +"$BIN_DIR/CryptoBoxWebserver" --config="$BIN_DIR/cryptobox.conf" --pidfile=/tmp/cryptoboxwebserver.pid --logfile=/tmp/cryptoboxwebser.log --port=8080 --datadir="$BIN_DIR/../www-data" "$@" + diff --git a/bin/test.complete.CryptoBox.py b/bin/test.complete.CryptoBox.py deleted file mode 100755 index db5300d..0000000 --- a/bin/test.complete.CryptoBox.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python2.4 - -""" -BEWARE: this script may overwrite the data of one of your loop devices. You -should restrict the AllowedDevices directive in cryptobox.conf to exclude -your precious black devices from being used by this script. - -the following script runs a number of tests for different parts -""" - -from CryptoBox import CryptoBoxProps -from CryptoBoxContainer import CryptoBoxContainer -import sys - - -def main(): - cb = CryptoBoxProps() - - print "Confguration:" - print "\tConfig file:\t\t%s" % (cb.prefs.prefs.filename, ) - print "\tAllowed devices:\t%s" % (cb.prefs["Main"]["AllowedDevices"], ) - - """for e in cb.getContainerList(filterType=CryptoBoxContainer.Types["luks"]):""" - for e in cb.getContainerList(): - print "\t\t%d\t\t%s - %s - %d" % (cb.getContainerList().index(e), e.getDevice(), e.getName(), e.getType()) - - if not cb.getContainerList() or len(cb.getContainerList()) < 1: - print "no loop devices found for testing" - sys.exit(1) - - if len(cb.getContainerList()) > 1: - print "I found more than one available loop device - I will stop now to avoid risking data loss." - print "Please change the 'AllowedDevices' setting in 'cryptobox.conf' to reduce the number of allowed devices to only one." - sys.exit(1) - - testElement = cb.getContainerList()[0] - print "\nRunning some tests now ..." - if not plain_tests(testElement): - print "some previous tests failed - we should stop now" - sys.exit(1) - luks_tests(testElement) - - -" ***************** some functions ******************** " - -def luks_tests(e): - # umount if necessary - try: - e.umount() - except "MountError": - pass - - e.create(e.Types["luks"], "alt") - print "\tluks create:\tok" - - e.changePassword("alt","neu") - print "\tluks changepw:\tok" - - e.setName("lalla") - print "\tluks setName:\tok" - - try: - e.mount("neu") - except "MountError": - pass - if e.isMounted(): print "\tluks mount:\tok" - else: print "\tluks mount:\tfailed" - - print "\tCapacity (size, free, used) [MB]:\t%s" % (e.getCapacity(), ) - - try: - e.umount() - except "MountError": - pass - if e.isMounted(): print "\tluks umount:\tfailed" - else: print "\tluks umount:\tok" - - if e.isMounted(): return False - else: return True - - -def plain_tests(e): - # umount if necessary - try: - e.umount() - except "MountError": - pass - - e.create(e.Types["plain"]) - print "\tplain create:\tok" - - e.setName("plain-lili") - print "\tplain setName:\tok" - - try: - e.mount() - except "MountError": - pass - if e.isMounted(): print "\tplain mount:\tok" - else: print "\tplain mount:\tfailed" - - print "\tCapacity (size, free, used) [MB]:\t%s" % (e.getCapacity(), ) - - try: - e.umount() - except "MountError": - pass - if e.isMounted(): print "\tplain umount:\tfailed" - else: print "\tplain umount:\tok" - - if e.isMounted(): return False - else: return True - -# ************ main **************** - -main() diff --git a/debian/control b/debian/control index 52839b2..bf40d96 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,8 @@ Source: cryptobox Section: admin Priority: extra Maintainer: Lars Kruse -Build-Depends: debhelper (>= 5.0.37.2), dpatch, python-all-dev (>= 2.4) +Build-Depends: debhelper (>= 5.0.37.2), dpatch, python-all-dev (>= 2.4), python-central (>= 0.5.6) +XS-Python-Version: 2.4 Standards-Version: 3.7.2 Package: cryptobox diff --git a/debian/cryptobox.default b/debian/cryptobox.default index 6c5f111..c802998 100644 --- a/debian/cryptobox.default +++ b/debian/cryptobox.default @@ -7,5 +7,15 @@ # set to "0" to enable the startup of the cryptobox - otherwise "1" NO_START=1 -# the use that should execute the cryptobox +# the user that should execute the cryptobox RUNAS=cryptobox + +# listening port +PORT=8080 + +# log file of the webserver +LOGFILE=/var/log/cryptobox/webserver.log + +# some more server options (rarely necessary) +#SERVER_OPTS="--host localhost --datadir=/usr/share/cryptobox/html" + diff --git a/debian/cryptobox.init b/debian/cryptobox.init index 480775d..d8d9ccf 100644 --- a/debian/cryptobox.init +++ b/debian/cryptobox.init @@ -18,35 +18,27 @@ # read the default setting file, if it exists -[ -e /etc/default/cryptobox ] && source /etc/default/cryptobox +[ -r /etc/default/cryptobox ] && source /etc/default/cryptobox -# startup switch defaults to zero (enabled) +# set default values (if not defined in /etc/default/cryptobox) NO_START=${NO_START:-0} RUNAS=${RUNAS:-cryptobox} +PORT=${PORT:-8080} +HOST=${HOST:-} +LOGFILE=${LOGFILE:-/var/log/cryptobox/webserver.log} +SERVER_OPTS=${SERVER_OPTS:-} +CONF_FILE=/etc/cryptobox/cryptobox.conf -if [ "$NO_START" = "1" ] - then [ $# -eq 0 ] && exit 0 - [ "$1" = "status" ] && exit 1 - [ "$1" = "stop" ] && exit 0 - echo "CryptoBox is disabled by default (check /etc/default/cryptobox)" - exit 0 - fi - -CBXSERVER=CryptoBoxWebserver.py - -if test -e "./$CBXSERVER" - then CBXPATH=$(pwd) - else CBXPATH=/usr/lib/cryptobox - fi +# quit if NO_START is 1 (see /etc/default/cryptobox) +[ "$NO_START" = "1" ] && exit 0 +DAEMON=/usr/bin/CryptoBoxWebserver PIDFILE=/var/run/cryptobox/webserver.pid -DAEMON=/usr/bin/python2.4 -DAEMON_OPTS=$CBXPATH/$CBXSERVER -NAME=cryptoboxd DESC="CryptoBox Daemon (webinterface)" +OPTIONS="-B --pidfile=$PIDFILE --config=$CONF_FILE $SERVER_OPTS" # check if the package is installed -test -e "$CBXPATH/$CBXSERVER" || exit 0 +test -e "$DAEMON" || exit 0 # include some useful functions to unify our output format . /lib/lsb/init-functions @@ -57,24 +49,28 @@ case "$1" in # TODO: create certificate # TODO: run stunnel # the lines above should go into the live-cd scripts - test -e "$PIDFILE" && log_warning_msg "CryptoBox seems to running already (pid file exists) - we will try to start it anyway ..." - log_daemon_msg "Starting cryptobox webserver" "$DESC" + ## create the directory of the pid file if necessary + PIDDIR=$(dirname "$PIDFILE") + if [ -d "$PIDDIR" ] + then mkdir -p "$PIDDIR" + chown $RUNAS:root "$PIDDIR" + chmod 755 "$PIDDIR" + fi + log_daemon_msg "Starting $DESC" if start-stop-daemon \ - --chdir "$CBXPATH" --chuid "$RUNAS" --quiet --start \ - -oknodo --user "$RUNAS" --pidfile "$PIDFILE" \ - --exec "$DAEMON" -- $DAEMON_OPTS + --chuid $RUNAS: --quiet --start \ + --oknodo --user $RUNAS --pidfile "$PIDFILE" \ + --exec /usr/bin/python --startas "$DAEMON" -- $OPTIONS then log_end_msg 0 else log_end_msg 1 exit 1 fi ;; stop ) - if test ! -e "$PIDFILE" - then log_warning_msg "CryptoBox is not running (no pid file found)" - exit 0 - fi log_daemon_msg "Stopping cryptobox webserver" "$DESC" - if start-stop-daemon --quiet --stop --pidfile "$PIDFILE" + if start-stop-daemon --oknodo --quiet --stop \ + --pidfile "$PIDFILE" \ + --user "$RUNAS" then rm "$PIDFILE" log_end_msg 0 else log_end_msg 1 @@ -86,8 +82,22 @@ case "$1" in sleep 1 "$0" start ;; + status ) + echo -n "$DESC " + if start-stop-daemon --stop --signal 0 --quiet \ + --pidfile "$PIDFILE" -user "$RUNAS" + then echo "running" + exit 0 + else if [ -e "$PIDFILE" ] + then echo "failed" + exit 1 + else echo "not running" + exit 0 + fi + fi + ;; * ) - echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 exit 1 ;; esac diff --git a/debian/postinst b/debian/postinst index 9ed87bf..f362b1b 100644 --- a/debian/postinst +++ b/debian/postinst @@ -35,7 +35,7 @@ create_add_super_permission() ## do nothing, if there is already a CryptoBox line grep -q "CRYPTOBOX_MARKER" "$SUPER_FILE" && return 0 echo >>"$SUPER_FILE" "## CRYPTOBOX_MARKER - please do not remove!" - echo >>"$SUPER_FILE" "CryptoBoxRootActions /usr/lib/cryptobox/CryptoBoxRootActions.py $CRYPTOBOX_USER" + echo >>"$SUPER_FILE" "CryptoBoxRootActions /usr/bin/CryptoBoxRootActions $CRYPTOBOX_USER" } create_pid_dir() diff --git a/debian/rules b/debian/rules index 200faa9..848cdd4 100755 --- a/debian/rules +++ b/debian/rules @@ -51,9 +51,10 @@ install: build dh_testroot dh_clean -k dh_installdirs - $(MAKE) install PREFIX=$(DEB_BUILD_DIR)/usr + dh_pycentral + python setup.py install --root=debian/cryptobox install -c -m 644 conf-examples/cryptobox.conf-dist $(DEB_BUILD_DIR)/etc/cryptobox/cryptobox.conf - install -c -m 644 conf-examples/cryptoboxwebserver.conf-dist $(DEB_BUILD_DIR)/etc/cryptobox/cryptoboxwebserver.conf + install -c -m 644 conf-examples/cryptoboxwebserver.conf-dist $(DEB_BUILD_DIR)/etc/cryptobox/webserver.conf # Build architecture-independent files here. diff --git a/hook-scripts/README b/event-scripts/README similarity index 100% rename from hook-scripts/README rename to event-scripts/README diff --git a/hook-scripts/apache2_dav b/event-scripts/apache2_dav similarity index 100% rename from hook-scripts/apache2_dav rename to event-scripts/apache2_dav diff --git a/hook-scripts/samba b/event-scripts/samba similarity index 100% rename from hook-scripts/samba rename to event-scripts/samba diff --git a/plugins/date/date.py b/plugins/date/date.py index 6c6e4e3..0ea0562 100644 --- a/plugins/date/date.py +++ b/plugins/date/date.py @@ -1,7 +1,7 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base -class date(CryptoBoxPlugin.CryptoBoxPlugin): +class date(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences" ] diff --git a/plugins/disks/disks.py b/plugins/disks/disks.py index dddab93..58b3550 100644 --- a/plugins/disks/disks.py +++ b/plugins/disks/disks.py @@ -1,6 +1,6 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base -class disks(CryptoBoxPlugin.CryptoBoxPlugin): +class disks(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "menu" ] diff --git a/plugins/help/help.py b/plugins/help/help.py index 7381253..e0e8b74 100644 --- a/plugins/help/help.py +++ b/plugins/help/help.py @@ -1,6 +1,6 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base -class help(CryptoBoxPlugin.CryptoBoxPlugin): +class help(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "menu" ] diff --git a/plugins/language_selection/language_selection.py b/plugins/language_selection/language_selection.py index 7290ce9..d3af707 100644 --- a/plugins/language_selection/language_selection.py +++ b/plugins/language_selection/language_selection.py @@ -1,7 +1,7 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base -class language_selection(CryptoBoxPlugin.CryptoBoxPlugin): +class language_selection(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "menu", "preferences" ] diff --git a/plugins/logs/logs.py b/plugins/logs/logs.py index 09b033e..6c0b9dd 100644 --- a/plugins/logs/logs.py +++ b/plugins/logs/logs.py @@ -1,7 +1,7 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base import os -class logs(CryptoBoxPlugin.CryptoBoxPlugin): +class logs(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences" ] diff --git a/plugins/network/network.py b/plugins/network/network.py index 7a6f65f..6a6f5ee 100644 --- a/plugins/network/network.py +++ b/plugins/network/network.py @@ -1,13 +1,13 @@ import subprocess import os -import CryptoBoxPlugin +import cryptobox.plugins.base ## specify (in seconds), how long we should wait before redirecting and ip change REDIRECT_DELAY=20 CHANGE_IP_DELAY=1 -class network(CryptoBoxPlugin.CryptoBoxPlugin): +class network(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences" ] diff --git a/plugins/partition/partition.py b/plugins/partition/partition.py index e285fd1..cf5c3c9 100644 --- a/plugins/partition/partition.py +++ b/plugins/partition/partition.py @@ -1,10 +1,10 @@ import subprocess import os import logging -import CryptoBoxTools -import CryptoBoxPlugin +import cryptobox.core.tools as cbxTools +import cryptobox.plugins.base -class partition(CryptoBoxPlugin.CryptoBoxPlugin): +class partition(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences" ] @@ -80,7 +80,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): return False if not self.cbox.isDeviceAllowed(device): return False - if not device in CryptoBoxTools.getParentBlockDevices(): + if not device in cbxTools.getParentBlockDevices(): return False return True @@ -96,14 +96,13 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): def __actionSelectDevice(self, args): - import CryptoBoxTools block_devices = [e - for e in CryptoBoxTools.getParentBlockDevices() + for e in cbxTools.getParentBlockDevices() if self.cbox.isDeviceAllowed(e)] counter = 0 for a in block_devices: self.hdf[self.hdf_prefix + "BlockDevices.%d.name" % counter] = a - self.hdf[self.hdf_prefix + "BlockDevices.%d.size" % counter] = CryptoBoxTools.getBlockDeviceSizeHumanly(a) + self.hdf[self.hdf_prefix + "BlockDevices.%d.size" % counter] = cbxTools.getBlockDeviceSizeHumanly(a) self.cbox.log.debug("found a suitable block device: %s" % a) counter += 1 if self.withConfigPartition: @@ -143,7 +142,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): parts = self.__getPartitionsFromArgs(args) if parts: self.__setPartitionData(parts) - if CryptoBoxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()): + if cbxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()): self.cbox.prefs.umountPartition() if not self.__runFDisk(parts): self.hdf["Data.Warning"] = "Plugins.partition.PartitioningFailed" @@ -189,7 +188,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): ## we do not have to take special care for a possible config partition parts = [ { "size": self.deviceSize, "type": "windows" } ] ## umount partition if necessary - if CryptoBoxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()): + if cbxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()): self.cbox.prefs.umountPartition() ## partition it if not self.__runFDisk(parts): @@ -229,10 +228,10 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): for t in self.PartTypes.keys(): self.hdf[self.hdf_prefix + "Types.%s" % t] = t ## store the currently existing partitions of the choosen block device - current_containers = [ e for e in self.cbox.getContainerList() if CryptoBoxTools.isPartOfBlockDevice(self.device, e.getDevice()) ] + current_containers = [ e for e in self.cbox.getContainerList() if cbxTools.isPartOfBlockDevice(self.device, e.getDevice()) ] for (index, t) in enumerate(current_containers): self.hdf[self.hdf_prefix + "ExistingContainers.%d.name" % index] = t.getName() - self.hdf[self.hdf_prefix + "ExistingContainers.%d.size" % index] = CryptoBoxTools.getBlockDeviceSizeHumanly(t.getDevice()) + self.hdf[self.hdf_prefix + "ExistingContainers.%d.size" % index] = cbxTools.getBlockDeviceSizeHumanly(t.getDevice()) def __getPartitionsFromArgs(self, args): @@ -264,8 +263,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): def __getAvailableDeviceSize(self, device): """calculate the available size (MB) of the device also consider a (possible) configuration partition""" - import CryptoBoxTools - deviceSize = CryptoBoxTools.getBlockDeviceSize(device) + deviceSize = cbxTools.getBlockDeviceSize(device) if deviceSize < 0: return 0 if self.withConfigPartition: deviceSize -= self.ConfigPartition["size"] @@ -279,7 +277,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin): ## we need a partition, if there is no active one if not active: return True ## check if the active one is part of the current device - return CryptoBoxTools.isPartOfBlockDevice(self.device, active) + return cbxTools.isPartOfBlockDevice(self.device, active) return False diff --git a/plugins/plugin_manager/plugin_manager.py b/plugins/plugin_manager/plugin_manager.py index cd6e19b..19d2c62 100644 --- a/plugins/plugin_manager/plugin_manager.py +++ b/plugins/plugin_manager/plugin_manager.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin -import Plugins +import cryptobox.plugins.base +import cryptobox.plugins.manage -class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin): +class plugin_manager(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences" ] @@ -14,7 +14,7 @@ class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin): if plugin_name: ## check for invalid characters if re.search(u'\W', plugin_name): return "plugin_list" - pluginList = Plugins.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"]) + pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"]) plugin = pluginList.getPlugin(plugin_name) if not plugin: return "plugin_list" ## take only plugins, that are of the same type as the choosen one diff --git a/plugins/shutdown/shutdown.py b/plugins/shutdown/shutdown.py index 8f3773a..ca38bc0 100644 --- a/plugins/shutdown/shutdown.py +++ b/plugins/shutdown/shutdown.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base REDIRECT_DELAY = 180 -class shutdown(CryptoBoxPlugin.CryptoBoxPlugin): +class shutdown(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences", "menu" ] diff --git a/plugins/system_preferences/system_preferences.py b/plugins/system_preferences/system_preferences.py index cc67c22..68d9154 100644 --- a/plugins/system_preferences/system_preferences.py +++ b/plugins/system_preferences/system_preferences.py @@ -1,6 +1,6 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base -class system_preferences(CryptoBoxPlugin.CryptoBoxPlugin): +class system_preferences(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "menu" ] diff --git a/plugins/user_manager/user_manager.py b/plugins/user_manager/user_manager.py index f638ead..c762621 100644 --- a/plugins/user_manager/user_manager.py +++ b/plugins/user_manager/user_manager.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base RESERVED_USERS = [ "admin" ] -class user_manager(CryptoBoxPlugin.CryptoBoxPlugin): +class user_manager(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "system" ] pluginVisibility = [ "preferences" ] diff --git a/plugins/volume_automount/volume_automount.py b/plugins/volume_automount/volume_automount.py index 104ec8d..bbfb01c 100644 --- a/plugins/volume_automount/volume_automount.py +++ b/plugins/volume_automount/volume_automount.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin -from CryptoBoxExceptions import * +import cryptobox.plugins.base +from cryptobox.core.exceptions import * -class volume_automount(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_automount(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "properties" ] diff --git a/plugins/volume_chpasswd/volume_chpasswd.py b/plugins/volume_chpasswd/volume_chpasswd.py index 4f38ac2..7fba294 100644 --- a/plugins/volume_chpasswd/volume_chpasswd.py +++ b/plugins/volume_chpasswd/volume_chpasswd.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin -from CryptoBoxExceptions import * +import cryptobox.plugins.base +from cryptobox.core.exceptions import * -class volume_chpasswd(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_chpasswd(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "properties" ] diff --git a/plugins/volume_details/volume_details.py b/plugins/volume_details/volume_details.py index 941ad62..0b4a26a 100644 --- a/plugins/volume_details/volume_details.py +++ b/plugins/volume_details/volume_details.py @@ -1,7 +1,7 @@ -import CryptoBoxPlugin +import cryptobox.plugins.base -class volume_details(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_details(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "volume" ] diff --git a/plugins/volume_format_fs/format_fs.py b/plugins/volume_format_fs/format_fs.py index 3dafed8..d42b734 100644 --- a/plugins/volume_format_fs/format_fs.py +++ b/plugins/volume_format_fs/format_fs.py @@ -1,7 +1,7 @@ -import CryptoBoxPlugin -from CryptoBoxExceptions import * +import cryptobox.plugins.base +from cryptobox.core.exceptions import * -class format_fs(CryptoBoxPlugin.CryptoBoxPlugin): +class format_fs(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "volume" ] diff --git a/plugins/volume_format_fs/volume_format_fs.py b/plugins/volume_format_fs/volume_format_fs.py index 5e02eb9..99af6a5 100644 --- a/plugins/volume_format_fs/volume_format_fs.py +++ b/plugins/volume_format_fs/volume_format_fs.py @@ -1,7 +1,7 @@ -import CryptoBoxPlugin -from CryptoBoxExceptions import * +import cryptobox.plugins.base +from cryptobox.core.exceptions import * -class volume_format_fs(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "volume" ] diff --git a/plugins/volume_mount/volume_mount.py b/plugins/volume_mount/volume_mount.py index 69979c8..827c274 100644 --- a/plugins/volume_mount/volume_mount.py +++ b/plugins/volume_mount/volume_mount.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin -from CryptoBoxExceptions import * +import cryptobox.plugins.base +from cryptobox.core.exceptions import * -class volume_mount(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_mount(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "volume" ] diff --git a/plugins/volume_props/volume_props.py b/plugins/volume_props/volume_props.py index eae23b6..9c82140 100644 --- a/plugins/volume_props/volume_props.py +++ b/plugins/volume_props/volume_props.py @@ -1,9 +1,9 @@ -import CryptoBoxPlugin -import Plugins -from CryptoBoxExceptions import * +import cryptobox.plugins.base +import cryptobox.plugins.manage +from cryptobox.core.exceptions import * -class volume_props(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_props(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "volume" ] @@ -13,7 +13,7 @@ class volume_props(CryptoBoxPlugin.CryptoBoxPlugin): def doAction(self, **args): import os - self.props_plugins = [e for e in Plugins.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"]).getPlugins() if "properties" in e.getVisibility()] + self.props_plugins = [e for e in cryptobox.plugins.manage.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"]).getPlugins() if "properties" in e.getVisibility()] ## sort plugins by rank self.props_plugins.sort(cmp = self.__cmpPluginsRank) ## set the name of the templates for every plugin @@ -42,7 +42,7 @@ class volume_props(CryptoBoxPlugin.CryptoBoxPlugin): for p in self.props_plugins: p.loadDataSet(hdf) ## call our parent's method - CryptoBoxPlugin.CryptoBoxPlugin.loadDataSet(self, hdf) + cryptobox.plugins.base.CryptoBoxPlugin.loadDataSet(self, hdf) def __cmpPluginsRank(self, p1, p2): diff --git a/plugins/volume_rename/volume_rename.py b/plugins/volume_rename/volume_rename.py index 73cffe9..0cdef71 100644 --- a/plugins/volume_rename/volume_rename.py +++ b/plugins/volume_rename/volume_rename.py @@ -1,8 +1,8 @@ -import CryptoBoxPlugin -from CryptoBoxExceptions import * +import cryptobox.plugins.base +from cryptobox.core.exceptions import * -class volume_rename(CryptoBoxPlugin.CryptoBoxPlugin): +class volume_rename(cryptobox.plugins.base.CryptoBoxPlugin): pluginCapabilities = [ "volume" ] pluginVisibility = [ "properties" ] diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..eed4743 --- /dev/null +++ b/setup.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +from distutils.core import setup +import distutils.sysconfig +import os + +## define some strings (not patterns) to exclude specific files or directories +IGNORE_FILES = [ '.svn' ] + +## define the data destination directory (below the python directory - we will fix this for debian in the rules file) +datadir = distutils.sysconfig.get_python_lib() +## remove installation prefix to get relative path +datadir = datadir.replace(distutils.sysconfig.get_config_var("prefix") + os.path.sep, '') +datadir = os.path.join(datadir, 'cryptobox','share') + +def getdatafiles(dirs): + filelist = [] + def listfiles(srcdir): + ## add the files of this directory + result = [(os.path.join(datadir,srcdir), [ os.path.join(srcdir, f) for f in os.listdir(srcdir) if os.path.isfile(os.path.join(srcdir, f)) and not f in IGNORE_FILES ])] + ## add the files in subdirectories + for d in os.listdir(os.path.join(srcdir)): + if os.path.isdir(os.path.join(srcdir,d)) and not d in IGNORE_FILES: + result.extend(listfiles(os.path.join(srcdir,d))) + return result + for d in dirs: + filelist.extend(listfiles(d)) + return filelist + + +setup( + name = 'cryptobox', + version = '0.3.0', + description = 'webinterface for handling encrypted disks', + author = 'Lars Kruse', + author_email = 'devel@sumpfralle.de', + maintainer = 'Lars Kruse', + maintainer_email = 'devel@sumpfralle.de', + license = 'GPL', + url = 'http://cryptobox.org', + packages = [ 'cryptobox', 'cryptobox.core', 'cryptobox.web', 'cryptobox.plugins', 'cryptobox.tests' ], + data_files = getdatafiles(['templates','www-data','lang','plugins','event-scripts','conf-examples']) + [ + (datadir, ['README']), + (datadir, ['CHANGELOG']), + (datadir, ['LICENSE'])], + package_dir = { 'cryptobox': 'src' }, + scripts = [ 'bin/CryptoBoxWebserver', 'bin/CryptoBoxRootActions' ], + classifiers = [ + 'Development Status :: 2 - Beta', + 'Environment :: Web Environment', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Topic :: System :: Systems Administration', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Programming Language :: Python'], + ) + diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..161c961 --- /dev/null +++ b/src/__init__.py @@ -0,0 +1 @@ +__all__ = ['core','web','plugins','tests'] diff --git a/src/core/__init__.py b/src/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bin/CryptoBoxContainer.py b/src/core/container.py old mode 100755 new mode 100644 similarity index 95% rename from bin/CryptoBoxContainer.py rename to src/core/container.py index 6929d8b..ced4197 --- a/bin/CryptoBoxContainer.py +++ b/src/core/container.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python2.4 - ## check python version import sys (ver_major, ver_minor, ver_sub, ver_desc, ver_subsub) = sys.version_info @@ -11,7 +9,7 @@ import subprocess import os import re import logging -from CryptoBoxExceptions import * +from cryptobox.core.exceptions import * """exceptions: CBVolumeIsActive @@ -24,14 +22,15 @@ from CryptoBoxExceptions import * CBChangePasswordError """ -class CryptoBoxContainer: +ContainerTypes = { + "unused":0, + "plain":1, + "luks":2, + "swap":3, + } - Types = { - "unused":0, - "plain":1, - "luks":2, - "swap":3} - + +class CryptoBoxContainer: __fsTypes = { "plain":["ext3", "ext2", "vfat", "reiser"], @@ -126,8 +125,8 @@ class CryptoBoxContainer: the result is a value in megabyte an error is indicated by "-1" """ - import CryptoBoxTools - return CryptoBoxTools.getBlockDeviceSize(self.device) + import cryptobox.core.tools as cbxtools + return cbxtools.getBlockDeviceSize(self.device) def resetObject(self): @@ -137,19 +136,19 @@ class CryptoBoxContainer: self.type = self.__getTypeOfPartition() self.name = self.__getNameOfContainer() self.__setAttributes() - if self.type == self.Types["luks"]: + if self.type == ContainerTypes["luks"]: self.mount = self.__mountLuks self.umount = self.__umountLuks - elif self.type == self.Types["plain"]: + elif self.type == ContainerTypes["plain"]: self.mount = self.__mountPlain self.umount = self.__umountPlain def create(self, type, password=None): old_name = self.getName() - if type == self.Types["luks"]: + if type == ContainerTypes["luks"]: self.__createLuks(password) - elif type == self.Types["plain"]: + elif type == ContainerTypes["plain"]: self.__createPlain() else: raise CBInvalidType("invalid container type (%d) supplied" % (type, )) @@ -161,7 +160,7 @@ class CryptoBoxContainer: def changePassword(self, oldpw, newpw): - if self.type != self.Types["luks"]: + if self.type != ContainerTypes["luks"]: raise CBInvalidType("changing of password is possible only for luks containers") if not oldpw: raise CBInvalidPassword("no old password supplied for password change") @@ -247,7 +246,7 @@ class CryptoBoxContainer: def __getUUID(self): - if self.__getTypeOfPartition() == self.Types["luks"]: + if self.__getTypeOfPartition() == ContainerTypes["luks"]: guess = self.__getLuksUUID() else: guess = self.__getNonLuksUUID() @@ -302,14 +301,14 @@ class CryptoBoxContainer: def __getTypeOfPartition(self): - "retrieve the type of the given partition (see CryptoBoxContainer.Types)" - if self.__isLuksPartition(): return self.Types["luks"] + "retrieve the type of the given partition (see cryptobox.core.container.ContainerTypes)" + if self.__isLuksPartition(): return ContainerTypes["luks"] typeOfPartition = self.__getTypeIdOfPartition() if typeOfPartition in self.__fsTypes["plain"]: - return self.Types["plain"] + return ContainerTypes["plain"] if typeOfPartition in self.__fsTypes["swap"]: - return self.Types["swap"] - return self.Types["unused"] + return ContainerTypes["swap"] + return ContainerTypes["unused"] def __getTypeIdOfPartition(self): @@ -645,8 +644,8 @@ class CryptoBoxContainer: def __getEventArgs(self): - """return an array of arguments for hook scripts handling pre/post-mount/umount + """return an array of arguments for event scripts handling pre/post-mount/umount events""" - typeText = [e for e in self.Types.keys() if self.Types[e] == self.getType()][0] + typeText = [e for e in ContainerTypes.keys() if ContainerTypes[e] == self.getType()][0] return [self.getDevice(), self.getName(), typeText, self.__getMountPoint()] diff --git a/bin/CryptoBoxExceptions.py b/src/core/exceptions.py similarity index 93% rename from bin/CryptoBoxExceptions.py rename to src/core/exceptions.py index 9619337..f40e426 100644 --- a/bin/CryptoBoxExceptions.py +++ b/src/core/exceptions.py @@ -3,12 +3,12 @@ exceptions of the cryptobox package """ -class CryptoBoxError(Exception): +class CBError(Exception): """base class for exceptions of the cryptobox""" pass -class CBConfigError(CryptoBoxError): +class CBConfigError(CBError): """any kind of error related to the configuration of a cryptobox""" pass @@ -57,7 +57,7 @@ class CBConfigInvalidValueError(CBConfigError): return "invalid configuration setting [%s]->%s (%s): %s" % (self.section, self.name, self.value, self.reason) -class CBEnvironmentError(CryptoBoxError): +class CBEnvironmentError(CBError): """some part of the environment of the cryptobox is broken e.g. the wrong version of a required program """ @@ -69,7 +69,7 @@ class CBEnvironmentError(CryptoBoxError): return "misconfiguration detected: %s" % self.desc -class CBContainerError(CryptoBoxError): +class CBContainerError(CBError): """any error raised while manipulating a cryptobox container""" def __init__(self, desc): diff --git a/bin/CryptoBox.py b/src/core/main.py old mode 100755 new mode 100644 similarity index 89% rename from bin/CryptoBox.py rename to src/core/main.py index a130d6b..4212a0e --- a/bin/CryptoBox.py +++ b/src/core/main.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python2.4 ''' This is the web interface for a fileserver managing encrypted filesystems. @@ -14,14 +13,15 @@ if (ver_major < 2) or ((ver_major == 2) and (ver_minor < 4)): sys.stderr.write("You need a python version >= 2.4\nCurrent version is:\n %s\n" % sys.version) sys.exit(1) -import CryptoBoxContainer -from CryptoBoxExceptions import * +import cryptobox.core.container as cbxContainer +from cryptobox.core.exceptions import * import re import os -import CryptoBoxTools +import cryptobox.core.tools as cbxTools import subprocess +VERSION = "0.3~1" class CryptoBox: '''this class rules them all! @@ -29,12 +29,11 @@ class CryptoBox: put things like logging, conf and oter stuff in here, that might be used by more classes, it will be passed on to them''' - VERSION = "0.3~1" def __init__(self, config_file=None): - import CryptoBoxSettings + import cryptobox.core.settings as cbxSettings self.log = self.__getStartupLogger() - self.prefs = CryptoBoxSettings.CryptoBoxSettings(config_file) + self.prefs = cbxSettings.CryptoBoxSettings(config_file) self.__runTests() @@ -124,9 +123,9 @@ class CryptoBoxProps(CryptoBox): def reReadContainerList(self): self.log.debug("rereading container list") self.containers = [] - for device in CryptoBoxTools.getAvailablePartitions(): + for device in cbxTools.getAvailablePartitions(): if self.isDeviceAllowed(device) and not self.isConfigPartition(device): - self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self)) + self.containers.append(cbxContainer.CryptoBoxContainer(device, self)) ## sort by container name self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1) @@ -187,7 +186,7 @@ class CryptoBoxProps(CryptoBox): try: result = self.containers[:] if filterType != None: - if filterType in range(len(CryptoBoxContainer.Types)): + if filterType in range(len(cbxContainer.Types)): return [e for e in self.containers if e.getType() == filterType] else: self.log.info("invalid filterType (%d)" % filterType) @@ -221,14 +220,14 @@ class CryptoBoxProps(CryptoBox): def sendEventNotification(self, event, event_infos): - """call all available scripts in the hook directory with some event information""" - hook_dir = self.prefs["Locations"]["HookDir"] - for fname in os.listdir(hook_dir): - real_fname = os.path.join(hook_dir, fname) + """call all available scripts in the event directory with some event information""" + event_dir = self.prefs["Locations"]["EventDir"] + for fname in os.listdir(event_dir): + real_fname = os.path.join(event_dir, fname) if os.path.isfile(real_fname) and os.access(real_fname, os.X_OK): cmd_args = [ self.prefs["Programs"]["super"], self.prefs["Programs"]["CryptoBoxRootActions"], - "hook", real_fname, event] + "event", real_fname, event] cmd_args.extend(event_infos) proc = subprocess.Popen( shell = False, @@ -237,7 +236,7 @@ class CryptoBoxProps(CryptoBox): args = cmd_args) (stdout, stderr) = proc.communicate() if proc.returncode != 0: - self.log.warn("a hook script (%s) failed (exitcode=%d) to handle an event (%s): %s" % (real_fname, proc.returncode, event, stderr.strip())) + self.log.warn("an event script (%s) failed (exitcode=%d) to handle an event (%s): %s" % (real_fname, proc.returncode, event, stderr.strip())) else: self.log.info("event handler (%s) finished successfully: %s" % (real_fname, event)) diff --git a/bin/CryptoBoxSettings.py b/src/core/settings.py similarity index 85% rename from bin/CryptoBoxSettings.py rename to src/core/settings.py index 9cf2d6d..23f9ff1 100644 --- a/bin/CryptoBoxSettings.py +++ b/src/core/settings.py @@ -1,15 +1,15 @@ +from cryptobox.core.exceptions import * import logging try: import validate except: - raise CryptoBoxExceptions.CBEnvironmentError("couldn't import 'validate'! Try 'apt-get install python-formencode'.") + raise CBEnvironmentError("couldn't import 'validate'! Try 'apt-get install python-formencode'.") import os -import CryptoBoxExceptions import subprocess try: import configobj ## needed for reading and writing of the config file except: - raise CryptoBoxExceptions.CBEnvironmentError("couldn't import 'configobj'! Try 'apt-get install python-configobj'.") + raise CBEnvironmentError("couldn't import 'configobj'! Try 'apt-get install python-configobj'.") @@ -172,9 +172,9 @@ class CryptoBoxSettings: if prefs: self.log.info("found config: %s" % prefs.items()) else: - raise CryptoBoxExceptions.CBConfigUnavailableError("failed to load the config file: %s" % config_file) + raise CBConfigUnavailableError("failed to load the config file: %s" % config_file) except IOError: - raise CryptoBoxExceptions.CBConfigUnavailableError("unable to open the config file: %s" % config_file) + raise CBConfigUnavailableError("unable to open the config file: %s" % config_file) return prefs @@ -190,7 +190,7 @@ class CryptoBoxSettings: else: errorMsg = "invalid configuration value (%s) in section '%s': %s" % (key, section_name, text) errorMsgs.append(errorMsg) - raise CryptoBoxExceptions.CBConfigError, "\n".join(errorMsgs) + raise CBConfigError, "\n".join(errorMsgs) def __checkUnknownPreferences(self): @@ -228,9 +228,9 @@ class CryptoBoxSettings: try: pluginConf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.PLUGINCONF_FILE) except KeyError: - raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") + raise CBConfigUndefinedError("Locations", "SettingsDir") except SyntaxError: - raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", pluginConf_file, "failed to interprete the filename of the plugin config file correctly (%s)" % pluginConf_file) + raise CBConfigInvalidValueError("Locations", "SettingsDir", pluginConf_file, "failed to interprete the filename of the plugin config file correctly (%s)" % pluginConf_file) ## create pluginConf_file if necessary if os.path.exists(pluginConf_file): pluginConf = configobj.ConfigObj(pluginConf_file, configspec=plugin_rules) @@ -240,7 +240,7 @@ class CryptoBoxSettings: pluginConf.validate(validate.Validator()) ## check if pluginConf_file file was created successfully? if not os.path.exists(pluginConf_file): - raise CryptoBoxExceptions.CBEnvironmentError("failed to create plugin configuration file (%s)" % pluginConf_file) + raise CBEnvironmentError("failed to create plugin configuration file (%s)" % pluginConf_file) return pluginConf @@ -249,9 +249,9 @@ class CryptoBoxSettings: try: conf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.VOLUMESDB_FILE) except KeyError: - raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") + raise 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) + raise 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) @@ -259,7 +259,7 @@ class CryptoBoxSettings: 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) + raise CBEnvironmentError("failed to create volume database file (%s)" % conf_file) return conf @@ -270,9 +270,9 @@ class CryptoBoxSettings: try: userDB_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.USERDB_FILE) except KeyError: - raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") + raise CBConfigUndefinedError("Locations", "SettingsDir") except SyntaxError: - raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", userDB_file, "failed to interprete the filename of the users database file correctly (%s)" % userDB_file) + raise CBConfigInvalidValueError("Locations", "SettingsDir", userDB_file, "failed to interprete the filename of the users database file correctly (%s)" % userDB_file) ## create userDB_file if necessary if os.path.exists(userDB_file): userDB = configobj.ConfigObj(userDB_file, configspec=userDB_rules) @@ -282,7 +282,7 @@ class CryptoBoxSettings: userDB.validate(validate.Validator()) ## check if userDB file was created successfully? if not os.path.exists(userDB_file): - raise CryptoBoxExceptions.CBEnvironmentError("failed to create user database file (%s)" % userDB_file) + raise CBEnvironmentError("failed to create user database file (%s)" % userDB_file) ## define password hash function - never use "sha" directly - SPOT userDB.getDigest = lambda password: sha.new(password).hexdigest() return userDB @@ -307,14 +307,14 @@ class CryptoBoxSettings: if os.path.exists(os.path.expanduser(f))] if not conf_file_list: # no possible config file found in the usual locations - raise CryptoBoxExceptions.CBConfigUnavailableError() + raise CBConfigUnavailableError() config_file = conf_file_list[0] else: # a config file was specified (e.g. via command line) if type(config_file) != types.StringType: - raise CryptoBoxExceptions.CBConfigUnavailableError("invalid config file specified: %s" % config_file) + raise CBConfigUnavailableError("invalid config file specified: %s" % config_file) if not os.path.exists(config_file): - raise CryptoBoxExceptions.CBConfigUnavailableError("could not find the specified configuration file (%s)" % config_file) + raise CBConfigUnavailableError("could not find the specified configuration file (%s)" % config_file) return config_file @@ -325,16 +325,16 @@ class CryptoBoxSettings: if not log_level in log_level_avail: raise TypeError except KeyError: - raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Level") + raise CBConfigUndefinedError("Log", "Level") except TypeError: - raise CryptoBoxExceptions.CBConfigInvalidValueError("Log", "Level", log_level, "invalid log level: only %s are allowed" % log_level_avail) + raise CBConfigInvalidValueError("Log", "Level", log_level, "invalid log level: only %s are allowed" % log_level_avail) try: try: log_handler = logging.FileHandler(self.prefs["Log"]["Details"]) except KeyError: - raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Details") + raise CBConfigUndefinedError("Log", "Details") except IOError: - raise CryptoBoxExceptions.CBEnvironmentError("could not create the log file (%s)" % self.prefs["Log"]["Details"]) + raise CBEnvironmentError("could not create the log file (%s)" % self.prefs["Log"]["Details"]) log_handler.setFormatter(logging.Formatter('%(asctime)s CryptoBox %(levelname)s: %(message)s')) cbox_log = logging.getLogger("CryptoBox") ## remove previous handlers @@ -362,9 +362,9 @@ MountParentDir = directoryExists(default="/var/cache/cryptobox/mnt") SettingsDir = directoryExists(default="/var/cache/cryptobox/settings") TemplateDir = directoryExists(default="/usr/share/cryptobox/template") LangDir = directoryExists(default="/usr/share/cryptobox/lang") -DocDir = directoryExists(default="/usr/share/doc/cryptobox/html") +DocDir = directoryExists(default="/usr/share/doc/cryptobox/www-data") PluginDir = directoryExists(default="/usr/share/cryptobox/plugins") -HookDir = directoryExists(default="/etc/cryptobox/hooks") +EventDir = directoryExists(default="/etc/cryptobox/events.d") [Log] Level = option("debug", "info", "warn", "error", default="warn") diff --git a/bin/CryptoBoxTools.py b/src/core/tools.py similarity index 100% rename from bin/CryptoBoxTools.py rename to src/core/tools.py diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bin/CryptoBoxPlugin.py b/src/plugins/base.py similarity index 100% rename from bin/CryptoBoxPlugin.py rename to src/plugins/base.py diff --git a/bin/Plugins.py b/src/plugins/manage.py similarity index 100% rename from bin/Plugins.py rename to src/plugins/manage.py diff --git a/src/tests/__init__.py b/src/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bin/unittests.CryptoBox.py b/src/tests/cryptobox.py similarity index 99% rename from bin/unittests.CryptoBox.py rename to src/tests/cryptobox.py index b109d8a..9ee1fd4 100755 --- a/bin/unittests.CryptoBox.py +++ b/src/tests/cryptobox.py @@ -51,7 +51,7 @@ TemplateDir = ../templates LangDir = ../lang DocDir = ../doc/html PluginDir = ../plugins -HookDir = ../hook-scripts +EventDir = ../event-scripts [Log] Level = debug Destination = file diff --git a/bin/unittests.CryptoBoxTools.py b/src/tests/cryptoboxtools.py similarity index 100% rename from bin/unittests.CryptoBoxTools.py rename to src/tests/cryptoboxtools.py diff --git a/bin/unittests.Plugins.py b/src/tests/plugins.py similarity index 88% rename from bin/unittests.Plugins.py rename to src/tests/plugins.py index 929c9de..4042f17 100755 --- a/bin/unittests.Plugins.py +++ b/src/tests/plugins.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.4 import unittest -import Plugins +import cryptobox.plugins.manage class CheckForUndefinedTestCases(unittest.TestCase): """here we will add failing test functions for every non-existing testcase""" @@ -9,7 +9,7 @@ class CheckForUndefinedTestCases(unittest.TestCase): def create_testcases(): - plugins = Plugins.PluginManager(None, "../plugins").getPlugins() + plugins = cryptobox.plugins.manage.PluginManager(None, "../plugins").getPlugins() glob_dict = globals() loc_dict = locals() for pl in plugins: diff --git a/bin/unittests.WebSites.py b/src/tests/websites.py similarity index 83% rename from bin/unittests.WebSites.py rename to src/tests/websites.py index 89e514d..3662d7a 100755 --- a/bin/unittests.WebSites.py +++ b/src/tests/websites.py @@ -7,11 +7,11 @@ from twill.errors import * from mechanize import BrowserStateError, LinkNotFoundError ## import the module of the common super class of all web interface test classes -import WebInterfaceTestClass +import cryptobox.web.testclass -class WebServer(WebInterfaceTestClass.WebInterfaceTestClass): +class WebServer(cryptobox.web.testclass.WebInterfaceTestClass): def test_is_server_running(self): '''the server should run under given name and port''' @@ -19,7 +19,7 @@ class WebServer(WebInterfaceTestClass.WebInterfaceTestClass): ## other URLs must not be checked, as we do not know, if they are valid -class BuiltinPages(WebInterfaceTestClass.WebInterfaceTestClass): +class BuiltinPages(cryptobox.web.testclass.WebInterfaceTestClass): def test_goto_index(self): diff --git a/src/web/__init__.py b/src/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bin/WebInterfaceDataset.py b/src/web/dataset.py similarity index 84% rename from bin/WebInterfaceDataset.py rename to src/web/dataset.py index 8f7fffa..feadfa9 100644 --- a/bin/WebInterfaceDataset.py +++ b/src/web/dataset.py @@ -1,9 +1,8 @@ import os -import CryptoBoxContainer -import CryptoBoxTools +from cryptobox.core.exceptions import * +import cryptobox.core.container as cbxContainer +import cryptobox.core.tools as cbxTools -## useful constant for some functions -CONT_TYPES = CryptoBoxContainer.CryptoBoxContainer.Types class WebInterfaceDataset(dict): """this class contains all data that should be available for the clearsilver @@ -22,7 +21,8 @@ class WebInterfaceDataset(dict): def setCryptoBoxState(self): import cherrypy - self["Data.Version"] = self.cbox.VERSION + import cryptobox.core.main + self["Data.Version"] = cryptobox.core.main.VERSION langs = self.cbox.getAvailableLanguages() langs.sort() for (index, lang) in enumerate(langs): @@ -60,15 +60,15 @@ class WebInterfaceDataset(dict): 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 + isEncrypted = (container.getType() == cbxContainer.ContainerTypes["luks"]) and 1 or 0 + isPlain = (container.getType() == cbxContainer.ContainerTypes["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 - self["Data.CurrentDisk.size"] = CryptoBoxTools.getBlockDeviceSizeHumanly(container.getDevice()) + self["Data.CurrentDisk.size"] = cbxTools.getBlockDeviceSizeHumanly(container.getDevice()) if isMounted: (size, avail, used) = container.getCapacity() percent = used / size @@ -85,15 +85,15 @@ class WebInterfaceDataset(dict): for container in self.cbox.getContainerList(): ## useful if the container was changed during an action container.resetObject() - isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 - isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 + isEncrypted = (container.getType() == cbxContainer.ContainerTypes["luks"]) and 1 or 0 + isPlain = (container.getType() == cbxContainer.ContainerTypes["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 - self["Data.Disks.%d.size" % avail_counter] = CryptoBoxTools.getBlockDeviceSizeHumanly(container.getDevice()) + self["Data.Disks.%d.size" % avail_counter] = cbxTools.getBlockDeviceSizeHumanly(container.getDevice()) if isMounted: active_counter += 1 avail_counter += 1 self["Data.activeDisksCount"] = active_counter @@ -131,7 +131,7 @@ class WebInterfaceDataset(dict): try: import neo_cgi, neo_util, neo_cs except: - raise CryptoBoxExceptions.CBEnvironmentError("couldn't import 'neo_*'! Try 'apt-get install python-clearsilver'.") + raise CBEnvironmentError("couldn't import 'neo_*'! Try 'apt-get install python-clearsilver'.") hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf") hdf = neo_util.HDF() hdf.readFile(hdf_path) diff --git a/bin/WebInterfaceSites.py b/src/web/sites.py old mode 100755 new mode 100644 similarity index 97% rename from bin/WebInterfaceSites.py rename to src/web/sites.py index 65fbb55..4650e28 --- a/bin/WebInterfaceSites.py +++ b/src/web/sites.py @@ -1,8 +1,8 @@ -import CryptoBox -import WebInterfaceDataset +import cryptobox.core.main +import cryptobox.web.dataset +import cryptobox.plugins.manage +from cryptobox.core.exceptions import * import re -import Plugins -from CryptoBoxExceptions import * import cherrypy import types import os @@ -36,9 +36,9 @@ class WebInterfaceSites: defaultTemplate = "empty" - def __init__(self): + def __init__(self, conf_file=None): import logging,sys - self.cbox = CryptoBox.CryptoBoxProps() + self.cbox = cryptobox.core.main.CryptoBoxProps(conf_file) self.log = logging.getLogger("CryptoBox") self.prefs = self.cbox.prefs self.__resetDataset() @@ -51,7 +51,7 @@ class WebInterfaceSites: also take care for the plugins, as they also contain datasets """ self.__loadPlugins() - self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs, self.pluginList.getPlugins()) + self.dataset = cryptobox.web.dataset.WebInterfaceDataset(self.cbox, self.prefs, self.pluginList.getPlugins()) ## publish plugin icons self.icons = PluginIconHandler(self.pluginList) self.icons.exposed = True @@ -60,7 +60,7 @@ class WebInterfaceSites: def __loadPlugins(self): - self.pluginList = Plugins.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"]) + self.pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"]) for plugin in self.pluginList.getPlugins(): if not plugin: continue plname = plugin.getName() diff --git a/bin/WebInterfaceTestClass.py b/src/web/testclass.py similarity index 95% rename from bin/WebInterfaceTestClass.py rename to src/web/testclass.py index c210a0f..fa1d6ae 100644 --- a/bin/WebInterfaceTestClass.py +++ b/src/web/testclass.py @@ -7,7 +7,7 @@ just inherit this class and add some test functions import unittest import twill import cherrypy -import WebInterfaceSites +import cryptobox.web.dataset ## we do the following, for easy surfing ## e.g. use: cbx.go(your_url) @@ -42,7 +42,7 @@ class WebInterfaceTestClass(unittest.TestCase): 'server.threadPool': 1, 'server.environment': 'production', }) - cherrypy.root = WebInterfaceSites.WebInterfaceSites() + cherrypy.root = cryptobox.web.dataset.WebInterfaceSites() cherrypy.server.start(initOnly=True, serverClass=None) from cherrypy._cpwsgi import wsgiApp