diff --git a/plugins/date/date.py b/plugins/date/date.py new file mode 100644 index 0000000..88b0229 --- /dev/null +++ b/plugins/date/date.py @@ -0,0 +1,116 @@ +# +# Copyright 2006 sense.lab e.V. +# +# This file is part of the CryptoBox. +# +# The CryptoBox is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The CryptoBox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the CryptoBox; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +"""Change date and time. + +requires: + - date + - ntpdate (planned) +""" + +__revision__ = "$Id$" + +import cryptobox.plugins.base + + +class date(cryptobox.plugins.base.CryptoBoxPlugin): + """The date feature of the CryptoBox. + """ + + plugin_capabilities = [ "system" ] + plugin_visibility = [ "preferences" ] + request_auth = False + rank = 10 + + def do_action(self, store=None, year=0, month=0, day=0, hour=0, minute=0): + """The action handler. + """ + import datetime + if store: + try: + year, month, day = int(year), int(month), int(day) + hour, minute = int(hour), int(minute) + ## check if the values are valid + datetime.datetime(year, month, day, hour, minute) + except ValueError: + self.hdf["Data.Warning"] = "Plugins.date.InvalidDate" + else: + new_date = "%02d%02d%02d%02d%d" % (month, day, hour, minute, year) + if self.__set_date(new_date): + self.cbox.log.info("changed date to: %s" % new_date) + self.hdf["Data.Success"] = "Plugins.date.DateChanged" + else: + ## a failure should usually be an invalid date (we do not check it really) + self.cbox.log.info("failed to set date: %s" % new_date) + self.hdf["Data.Warning"] = "Plugins.date.InvalidDate" + self.__prepare_form_data() + return "form_date" + + + def get_status(self): + """Retrieve the status of the feature. + """ + now = self.__get_current_date() + return "%d/%d/%d/%d/%d/%d" % \ + (now.year, now.month, now.day, now.hour, now.minute, now.second) + + + def get_warnings(self): + import os + warnings = [] + if not os.path.isfile(self.root_action.DATE_BIN): + warnings.append((48, "Plugins.%s.MissingProgramDate" % self.get_name())) + return warnings + + + def __prepare_form_data(self): + """Set some hdf values. + """ + cur_date = self.__get_current_date() + self.hdf[self.hdf_prefix + "year"] = cur_date.year + self.hdf[self.hdf_prefix + "month"] = cur_date.month + self.hdf[self.hdf_prefix + "day"] = cur_date.day + self.hdf[self.hdf_prefix + "hour"] = cur_date.hour + self.hdf[self.hdf_prefix + "minute"] = cur_date.minute + + + def __get_current_date(self): + """Retrieve the current date and time. + """ + import datetime + return datetime.datetime(2000, 1, 1).now() + + + def __set_date(self, new_date): + """Set a new date and time. + """ + import subprocess + import os + proc = subprocess.Popen( + shell = False, + args = [ + self.cbox.prefs["Programs"]["super"], + self.cbox.prefs["Programs"]["CryptoBoxRootActions"], + "plugin", + os.path.join(self.plugin_dir, "root_action.py"), + new_date]) + proc.wait() + return proc.returncode == 0 + diff --git a/plugins/date/form_date.cs b/plugins/date/form_date.cs new file mode 100644 index 0000000..71d0d47 --- /dev/null +++ b/plugins/date/form_date.cs @@ -0,0 +1,51 @@ + + + + +
+ + + + + + + + + +


+ + +

+ +


+  :  +

+ +

+ +

+ + +
+ diff --git a/plugins/date/language.hdf b/plugins/date/language.hdf index 9f83e62..610ca89 100644 --- a/plugins/date/language.hdf +++ b/plugins/date/language.hdf @@ -1,23 +1,47 @@ -Name = Network restart -Link = Network +Name = Change date and time +Link = Date -Title = Network restart +Title = Date and time setting -Button.NetworkRestart = Restart network connections +Button.ConfigDate = Set date and time -Help.NetworkRestart = Here you can restart all network connections of the cryptobox at once. +Text.Date = Date +Text.Time = Time +Text.Months { + 1 = January + 2 = February + 3 = March + 4 = April + 5 = May + 6 = June + 7 = July + 8 = August + 9 = September + 10 = October + 11 = November + 12 = December +} + +Help.ChangeDate = Change the time and date for the CryptoBox server. SuccessMessage { - Restart { - Title = Network restart - Text = The network connections were restarted + DateChanged { + Title = Date changed + Text = The date was changed successfully. } } WarningMessage { - RestartFailed { - Title = Network restart failed - Text = The network connections couldn't be restarted + InvalidDate { + Title = Invalid value + Text = An invalid value for date or time was supplied. Please try again. + } +} + +EnvironmentWarning { + MissingProgramDate { + Title = Missing program + Text = The program 'date' is not installed. Please ask the administrator of the CryptoBox server to configure it properly. } } diff --git a/plugins/date/network_restart.cs b/plugins/date/network_restart.cs deleted file mode 100644 index 1e1b1f7..0000000 --- a/plugins/date/network_restart.cs +++ /dev/null @@ -1,20 +0,0 @@ - - - - -
- - - - - - - - -

- -

- - -
- diff --git a/plugins/date/network_restart.py b/plugins/date/network_restart.py deleted file mode 100644 index 7cd6e6d..0000000 --- a/plugins/date/network_restart.py +++ /dev/null @@ -1,74 +0,0 @@ -# -# Copyright 2006 sense.lab e.V. -# -# This file is part of the CryptoBox. -# -# The CryptoBox is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# The CryptoBox is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with the CryptoBox; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -"""Change date and time. - -""" - -__revision__ = "$Id: date.py 916 2007-03-21 18:35:31Z lars $" - -import cryptobox.plugins.base - - -class network_restart(cryptobox.plugins.base.CryptoBoxPlugin): - """The network restart feature of the CryptoBox. - """ - - plugin_capabilities = [ "system" ] - # this plugin is per default invisible - plugin_visibility = [ ] - request_auth = True - rank = 31 - - def do_action(self, restart=None): - """Show the user interface. - """ - self.cbox.log.debug("executing network_restart plugin") - if restart == "yes": - if self.__net_restart(): - self.cbox.log.info("network restarted") - self.hdf["Data.Success"] = "Plugins.network_restart.Restart" - else: - self.cbox.log.error("failure while restarting network") - self.hdf["Data.Warning"] = "Plugins.network_restart.RestartFailed" - return "network_restart" - - - def get_status(self): - """ - """ - return - - - def __net_restart(self): - """Restart all local network connections. - """ - import subprocess - import os - proc = subprocess.Popen( - shell = False, - args = [ - self.cbox.prefs["Programs"]["super"], - self.cbox.prefs["Programs"]["CryptoBoxRootActions"], - "plugin", - os.path.join(self.plugin_dir, "root_action.py")]) - proc.wait() - return proc.returncode == 0 - diff --git a/plugins/date/plugin_icon.gif b/plugins/date/plugin_icon.gif index 4afc6bd..7b660d0 100644 Binary files a/plugins/date/plugin_icon.gif and b/plugins/date/plugin_icon.gif differ diff --git a/plugins/date/plugin_icon.png b/plugins/date/plugin_icon.png index 700c980..f263906 100644 Binary files a/plugins/date/plugin_icon.png and b/plugins/date/plugin_icon.png differ diff --git a/plugins/date/root_action.py b/plugins/date/root_action.py index f3f7abd..7d3b91d 100755 --- a/plugins/date/root_action.py +++ b/plugins/date/root_action.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2007 sense.lab e.V. +# Copyright 2006 sense.lab e.V. # # This file is part of the CryptoBox. # @@ -25,19 +25,34 @@ __revision__ = "$Id$" ## necessary: otherwise CryptoBoxRootActions.py will refuse to execute this script PLUGIN_TYPE = "cryptobox" -BIN = "/etc/init.d/networking" -ACTION = "restart" +DATE_BIN = "/bin/date" import subprocess +import re import sys -#import re -#import os +import os if __name__ == "__main__": + args = sys.argv[1:] + + self_bin = sys.argv[0] + + if len(args) > 1: + sys.stderr.write("%s: too many arguments (%s)\n" % (self_bin, args)) + sys.exit(1) + + if len(args) == 0: + sys.stderr.write("%s: no argument supplied\n" % self_bin) + sys.exit(1) + + if re.search(r'\D', args[0]): + sys.stderr.write("%s: illegal argument (%s)\n" % (self_bin, args[0])) + sys.exit(1) + proc = subprocess.Popen( shell = False, stdout = subprocess.PIPE, - args = [BIN, ACTION]) + args = [DATE_BIN, args[0]]) proc.wait() sys.exit(proc.returncode) diff --git a/plugins/date/unittests.py b/plugins/date/unittests.py new file mode 100644 index 0000000..4d90010 --- /dev/null +++ b/plugins/date/unittests.py @@ -0,0 +1,97 @@ +# +# Copyright 2006 sense.lab e.V. +# +# This file is part of the CryptoBox. +# +# The CryptoBox is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The CryptoBox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the CryptoBox; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +__revision__ = "$Id$" + +from cryptobox.tests.base import WebInterfaceTestClass + +class unittests(WebInterfaceTestClass): + + def test_get_date(self): + """retrieve the current date""" + date = self._get_current_date() + + + def test_change_date(self): + """set the date back and forth""" + now = self._get_current_date() + ## copy current time + new_date = dict(now) + ## move three minutes forward (more is not nice because of screensavers) + new_date["minute"] = (now["minute"] + 3) % 60 + ## in case of minute-overflow we also have to move the hour a little bit forward + new_date["hour"] = now["hour"] + ((now["minute"] + 3) / 60) + ## move forward ... + self._setDate(new_date) + self.assertEquals(new_date, self._get_current_date()) + ## ... and backward + self._setDate(now) + self.assertEquals(now, self._get_current_date()) + + + def test_try_broken_date(self): + """expect error messages for invalid dates""" + self._setDate({"hour":12, "minute":40, "year":2004, "month":7, "day":0}) + self.cmd.find("invalid value for date") + self._setDate({"hour":12, "minute":40, "year":"x", "month":7, "day":2}) + self.cmd.find("invalid value for date") + self._setDate({"hour":12, "minute":40, "year":2004, "month":2, "day":31}) + self.cmd.find("invalid value for date") + + + def _get_current_date(self): + date_url = self.url + "date" + self.register_auth(date_url) + self.cmd.go(date_url) + self.cmd.find("Data.Status.Plugins.date=([0-9]+/[0-9]+/[0-9]+/[0-9]+/[0-9]+/[0-9]+)$", "m") + dateNumbers = self.locals["__match__"].split("/") + self.assertEquals(len(dateNumbers), 6) + ## we ignore seconds + dateField = { + "year" : int(dateNumbers[0]), + "month" : int(dateNumbers[1]), + "day" : int(dateNumbers[2]), + "hour" : int(dateNumbers[3]), + "minute" : int(dateNumbers[4])} + return dateField + + + def _setDate(self, date): + """for now we have to use this function instead of the one below""" + date_url = self.url + "date?weblang=en&store=1&year=%s&month=%s&day=%s&hour=%s&minute=%s"\ + % (str(date["year"]), str(date["month"]), str(date["day"]), + str(date["hour"]), str(date["minute"])) + self.register_auth(date_url) + self.cmd.go(date_url) + + + def _setDateBroken(self, date): + """this should work, but the parsing of twill seems to be broken + as soon as the twill bug is fixed, we should use this function""" + date_url = self.url + "date" + self.register_auth(date_url) + self.cmd.go(date_url) + self.cmd.formvalue("set_date", "year", str(date["year"])) + self.cmd.formvalue("set_date", "month", str(date["month"])) + self.cmd.formvalue("set_date", "day", str(date["day"])) + self.cmd.formvalue("set_date", "hour", str(date["hour"])) + self.cmd.formvalue("set_date", "minute", str(date["minute"])) + self.cmd.submit() +