From 2f784ca08157c16a993845a9375e8b7ac6e44f37 Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel Date: Fri, 3 Apr 2009 12:16:35 +0200 Subject: [PATCH] Initial import of koward. This application should replace the kolab-webadmin in the long run. It is primarily intended as an LDAP database manager based on the Kolab_Server library. --- koward/app/controllers/ApplicationController.php | 40 ++++ koward/app/controllers/CheckController.php | 59 ++++++ koward/app/controllers/IndexController.php | 21 ++ koward/app/controllers/ObjectController.php | 144 ++++++++++++++ koward/app/views/Check/run.html.php | 10 + koward/app/views/Check/show.html.php | 9 + koward/app/views/Index/index.html.php | 6 + koward/app/views/Modify/add.html.php | 6 + koward/app/views/Object/delete.html.php | 2 + koward/app/views/Object/edit.html.php | 4 + koward/app/views/Object/listall.html.php | 37 ++++ koward/app/views/Object/view.html.php | 3 + koward/app/views/shared/_header.html.php | 36 ++++ koward/app/views/shared/_menu.html.php | 5 + koward/bin/bootstrap.php | 15 ++ koward/config/attributes.php | 26 +++ koward/config/conf.php | 3 + koward/config/objects.php | 44 +++++ koward/config/routes.php | 12 ++ koward/doc/QUESTIONS.txt | 5 + koward/lib/Exception.php | 30 +++ koward/lib/Form/Object.php | 118 ++++++++++++ koward/lib/Koward.php | 87 +++++++++ koward/lib/Test.php | 173 +++++++++++++++++ koward/lib/Test/AllTests.php | 78 ++++++++ koward/lib/Test/Renderer.php | 44 +++++ koward/lib/Test/Server/UserTest.php | 43 +++++ koward/lib/Test/Template/scenario.html.dist | 13 ++ koward/lib/Test/Template/scenario_header.html.dist | 6 + koward/lib/Test/Template/scenarios.html.dist | 54 ++++++ koward/lib/Test/Template/step.html.dist | 6 + koward/test/AllTests.php | 83 ++++++++ koward/test/KowardTest.php | 95 +++++++++ koward/test/TestInit.php | 25 +++ koward/themes/graphics/favicon.ico | Bin 0 -> 1406 bytes koward/themes/graphics/query.png | Bin 0 -> 223 bytes koward/themes/kolab/screen.css | 212 +++++++++++++++++++++ 37 files changed, 1554 insertions(+) create mode 100644 koward/app/controllers/ApplicationController.php create mode 100644 koward/app/controllers/CheckController.php create mode 100644 koward/app/controllers/IndexController.php create mode 100644 koward/app/controllers/ObjectController.php create mode 100644 koward/app/views/Check/run.html.php create mode 100644 koward/app/views/Check/show.html.php create mode 100644 koward/app/views/Index/index.html.php create mode 100644 koward/app/views/Modify/add.html.php create mode 100644 koward/app/views/Object/delete.html.php create mode 100644 koward/app/views/Object/edit.html.php create mode 100644 koward/app/views/Object/listall.html.php create mode 100644 koward/app/views/Object/view.html.php create mode 100644 koward/app/views/shared/_header.html.php create mode 100644 koward/app/views/shared/_menu.html.php create mode 100644 koward/bin/bootstrap.php create mode 100644 koward/config/attributes.php create mode 100644 koward/config/conf.php create mode 100644 koward/config/objects.php create mode 100644 koward/config/routes.php create mode 100644 koward/doc/QUESTIONS.txt create mode 100644 koward/lib/Exception.php create mode 100644 koward/lib/Form/Object.php create mode 100644 koward/lib/Koward.php create mode 100644 koward/lib/Test.php create mode 100644 koward/lib/Test/AllTests.php create mode 100644 koward/lib/Test/Renderer.php create mode 100644 koward/lib/Test/Server/UserTest.php create mode 100644 koward/lib/Test/Template/scenario.html.dist create mode 100644 koward/lib/Test/Template/scenario_header.html.dist create mode 100644 koward/lib/Test/Template/scenarios.html.dist create mode 100644 koward/lib/Test/Template/step.html.dist create mode 100644 koward/test/AllTests.php create mode 100644 koward/test/KowardTest.php create mode 100644 koward/test/TestInit.php create mode 100644 koward/themes/graphics/favicon.ico create mode 100644 koward/themes/graphics/query.png create mode 100644 koward/themes/kolab/screen.css diff --git a/koward/app/controllers/ApplicationController.php b/koward/app/controllers/ApplicationController.php new file mode 100644 index 000000000..55cfd478e --- /dev/null +++ b/koward/app/controllers/ApplicationController.php @@ -0,0 +1,40 @@ +koward = Koward_Koward::singleton(); + + $this->types = array_keys($this->koward->objects); + if (empty($this->types)) { + throw new KowardException('No object types have been configured!'); + } + + $this->menu = $this->getMenu(); + + $this->theme = isset($this->koward->conf['koward']['theme']) ? $this->koward->conf['koward']['theme'] : 'koward'; + } + + /** + * Builds Koward's list of menu items. + */ + public function getMenu() + { + global $registry; + + require_once 'Horde/Menu.php'; + $menu = new Menu(); + + $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'listall')), + _("_Objects"), 'user.png', $registry->getImageDir('horde')); + $menu->add($this->urlFor(array('controller' => 'object', 'action' => 'edit')), + _("_Add"), 'plus.png', $registry->getImageDir('horde')); + $menu->add(Horde::applicationUrl('search'), _("_Search"), 'search.png', $registry->getImageDir('horde')); + $menu->add(Horde::applicationUrl('Queries'), _("_Queries"), 'query.png', $registry->getImageDir('koward')); + $menu->add($this->urlFor(array('controller' => 'check', 'action' => 'show')), + _("_Test"), 'problem.png', $registry->getImageDir('horde')); + + return $menu; + } +} diff --git a/koward/app/controllers/CheckController.php b/koward/app/controllers/CheckController.php new file mode 100644 index 000000000..39bf83e5b --- /dev/null +++ b/koward/app/controllers/CheckController.php @@ -0,0 +1,59 @@ +suite = Koward_Test_AllTests::suite(); + } + + public function show() + { + $this->list = array(); + + $this->list[0] = Horde::link( + $this->urlFor(array('controller' => 'check', + 'action' => 'run', + 'id' => 'all')), + _("All tests")) . _("All tests") . ''; + + $this->list[1] = ''; + + for ($i = 0; $i < $this->suite->count(); $i++) { + $class_name = $this->suite->testAt($i)->getName(); + $this->list[$i + 2] = Horde::link( + $this->urlFor(array('controller' => 'check', + 'action' => 'run', + 'id' => $i + 1)), + $class_name) . $class_name . ''; + } + } + + public function run() + { + + if ($this->params['id'] == 'all') { + $this->test = $this->suite; + } else { + $id = (int) $this->params['id']; + if (!empty($id)) { + $this->test = $this->suite->testAt($id - 1); + } else { + $this->test = null; + $this->koward->notification->push(_("You selected no test!")); + } + } + } +} \ No newline at end of file diff --git a/koward/app/controllers/IndexController.php b/koward/app/controllers/IndexController.php new file mode 100644 index 000000000..40e2c7702 --- /dev/null +++ b/koward/app/controllers/IndexController.php @@ -0,0 +1,21 @@ +title = _("Index"); + $this->welcome = _("Welcome to the Koward administration interface"); + } +} \ No newline at end of file diff --git a/koward/app/controllers/ObjectController.php b/koward/app/controllers/ObjectController.php new file mode 100644 index 000000000..f76f32dac --- /dev/null +++ b/koward/app/controllers/ObjectController.php @@ -0,0 +1,144 @@ +object_type = $this->params->get('id', $this->types[0]); + + if (isset($this->koward->objects[$this->object_type])) { + $this->attributes = $this->koward->objects[$this->object_type]['attributes']; + $params = array('attributes' => array_keys($this->attributes)); + $this->objectlist = $this->koward->server->listHash($this->object_type, + $params); + foreach ($this->objectlist as $uid => $info) { + $this->objectlist[$uid]['edit_url'] = Horde::link( + $this->urlFor(array('controller' => 'object', + 'action' => 'edit', + 'id' => $uid)), + _("Edit")) . Horde::img('edit.png', _("Edit"), '', + $GLOBALS['registry']->getImageDir('horde')) + . ''; + $this->objectlist[$uid]['delete_url'] = Horde::link( + $this->urlFor(array('controller' => 'object', + 'action' => 'delete', + 'id' => $uid)), + _("Delete")) . Horde::img('delete.png', _("Delete"), '', + $GLOBALS['registry']->getImageDir('horde')) + . ''; + $this->objectlist[$uid]['view_url'] = Horde::link( + $this->urlFor(array('controller' => 'object', + 'action' => 'view', + 'id' => $uid)), _("View")); + } + } else { + $this->objectlist = 'Unkown object type.'; + } + $this->tabs = new Horde_UI_Tabs(null, Variables::getDefaultVariables()); + foreach ($this->koward->objects as $key => $configuration) { + $this->tabs->addTab($configuration['list_label'], + $this->urlFor(array('controller' => 'object', + 'action' => 'listall', + 'id' => $key)), + $key); + } + + $this->render(); + } + + public function delete() + { + try { + if (empty($this->params->id)) { + $this->koward->notification->push(_("The object that should be deleted has not been specified."), + 'horde.error'); + } else { + $this->object = $this->koward->getObject($this->params->id); + if (empty($this->params->submit)) { + $this->token = $this->koward->getRequestToken('object.delete'); + } else { + $this->koward->checkRequestToken('object.delete', $this->params->token); + $this->object->delete(); + $this->koward->notification->push(sprintf(_("Successfully deleted the object \"%s\""), + $this->params->id), + 'horde.message'); + header('Location: ' . $this->urlFor(array('controller' => 'object', + 'action' => 'listall', + 'id' => get_class($this->object)))); + exit; + } + } + } catch (Exception $e) { + $this->koward->notification->push($e->getMessage(), 'horde.error'); + } + + $this->render(); + } + + public function view() + { + try { + if (empty($this->params->id)) { + $this->koward->notification->push(_("The object that should be viewed has not been specified."), + 'horde.error'); + } else { + $this->object = $this->koward->getObject($this->params->id); + + require_once 'Horde/Variables.php'; + $this->vars = Variables::getDefaultVariables(); + $this->form = new Koward_Form_Object($this->vars, $this->object, + array('title' => _("View object"))); + } + } catch (Exception $e) { + $this->koward->notification->push($e->getMessage(), 'horde.error'); + } + + $this->render(); + } + + public function edit() + { + try { + if (empty($this->params->id)) { + $this->object = null; + } else { + $this->object = $this->koward->getObject($this->params->id); + } + + require_once 'Horde/Variables.php'; + $this->vars = Variables::getDefaultVariables(); + $this->form = new Koward_Form_Object($this->vars, $this->object); + + if ($this->form->validate()) { + $object = $this->form->execute(); + + header('Location: ' . $this->urlFor(array('controller' => 'object', + 'action' => 'view', + 'id' => $object->get(Horde_Koward_Server_Object::ATTRIBUTE_UID)))); + exit; + } + } catch (Exception $e) { + $this->koward->notification->push($e->getMessage(), 'horde.error'); + } + + $this->post = $this->urlFor(array('controller' => 'object', + 'action' => 'edit', + 'id' => $this->params->id)); + + $this->render(); + } +} \ No newline at end of file diff --git a/koward/app/views/Check/run.html.php b/koward/app/views/Check/run.html.php new file mode 100644 index 000000000..ea945e832 --- /dev/null +++ b/koward/app/views/Check/run.html.php @@ -0,0 +1,10 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> + +test)) { + ob_start(); + $listener = new Koward_Test_Renderer(); + PHPUnit_TextUI_TestRunner::run($this->test, array('listeners' => array($listener))); + echo ob_get_clean(); +} \ No newline at end of file diff --git a/koward/app/views/Check/show.html.php b/koward/app/views/Check/show.html.php new file mode 100644 index 000000000..f58908fef --- /dev/null +++ b/koward/app/views/Check/show.html.php @@ -0,0 +1,9 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> + +list as $test) { + echo $test; + echo '
'; +} \ No newline at end of file diff --git a/koward/app/views/Index/index.html.php b/koward/app/views/Index/index.html.php new file mode 100644 index 000000000..0696b72ec --- /dev/null +++ b/koward/app/views/Index/index.html.php @@ -0,0 +1,6 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> + +
+

welcome ?>

+
diff --git a/koward/app/views/Modify/add.html.php b/koward/app/views/Modify/add.html.php new file mode 100644 index 000000000..fb15bbee4 --- /dev/null +++ b/koward/app/views/Modify/add.html.php @@ -0,0 +1,6 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> + +form->renderActive(new Horde_Form_Renderer(), $vars, 'modify', 'post'); + diff --git a/koward/app/views/Object/delete.html.php b/koward/app/views/Object/delete.html.php new file mode 100644 index 000000000..055e78c2a --- /dev/null +++ b/koward/app/views/Object/delete.html.php @@ -0,0 +1,2 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> diff --git a/koward/app/views/Object/edit.html.php b/koward/app/views/Object/edit.html.php new file mode 100644 index 000000000..5185924e7 --- /dev/null +++ b/koward/app/views/Object/edit.html.php @@ -0,0 +1,4 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> +form->renderActive(new Horde_Form_Renderer(), $this->vars, + $this->post, 'post'); ?> \ No newline at end of file diff --git a/koward/app/views/Object/listall.html.php b/koward/app/views/Object/listall.html.php new file mode 100644 index 000000000..d53aa87c2 --- /dev/null +++ b/koward/app/views/Object/listall.html.php @@ -0,0 +1,37 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> + +tabs->render($this->object_type); ?> + + + + + + + attributes as $attribute => $info): ?> + + + + + + objectlist as $dn => $info): ?> + + + + attributes as $attribute => $ainfo): ?> + + + + + +
getImageDir('horde')) ?>getImageDir('horde')) ?>
+ + + + + + escape($info[$attribute]) . ''; ?> + + escape($info[$attribute]) ?> + +
diff --git a/koward/app/views/Object/view.html.php b/koward/app/views/Object/view.html.php new file mode 100644 index 000000000..f26176458 --- /dev/null +++ b/koward/app/views/Object/view.html.php @@ -0,0 +1,3 @@ +renderPartial('header'); ?> +renderPartial('menu'); ?> +form->renderInactive(new Horde_Form_Renderer(), $this->vars); ?> \ No newline at end of file diff --git a/koward/app/views/shared/_header.html.php b/koward/app/views/shared/_header.html.php new file mode 100644 index 000000000..dc72ba84e --- /dev/null +++ b/koward/app/views/shared/_header.html.php @@ -0,0 +1,36 @@ + + + + +' : '' ?> + +get('name'); +$page_title .= !empty($this->title) ? ' :: ' . $this->title : ''; + +Horde::includeScriptFiles(); +?> +<?php echo htmlspecialchars($page_title) ?> + + +print_view) ? $this->theme : 'print') ?> + + + + diff --git a/koward/app/views/shared/_menu.html.php b/koward/app/views/shared/_menu.html.php new file mode 100644 index 000000000..3be3269c7 --- /dev/null +++ b/koward/app/views/shared/_menu.html.php @@ -0,0 +1,5 @@ + +koward->notification->notify(array('listeners' => 'status')) ?> + diff --git a/koward/bin/bootstrap.php b/koward/bin/bootstrap.php new file mode 100644 index 000000000..8003cabb8 --- /dev/null +++ b/koward/bin/bootstrap.php @@ -0,0 +1,15 @@ + 'int')), +); +$parser = new Horde_Argv_Parser(array('optionList' => $options)); +list($opts, $tags) = $parser->parseArgs(); + +if (!$opts->not_defined) { + throw new InvalidArgumentException(''); +} + +exit(0); diff --git a/koward/config/attributes.php b/koward/config/attributes.php new file mode 100644 index 000000000..3a4908610 --- /dev/null +++ b/koward/config/attributes.php @@ -0,0 +1,26 @@ + _("First Name"), + 'type' => 'text', + 'required' => true, + 'params' => array('regex' => '', 'size' => 40, 'maxlength' => 255) +); +$attributes['sn'] = array( + 'label' => _("Last Name"), + 'type' => 'text', + 'required' => true, + 'params' => array('regex' => '', 'size' => 40, 'maxlength' => 255) +); +$attributes['mail'] = array( + 'label' => _("Mail address"), + 'type' => 'text', + 'required' => true, + 'params' => array('regex' => '', 'size' => 40, 'maxlength' => 255) +); +$attributes['uid'] = array( + 'label' => _("User ID"), + 'type' => 'text', + 'required' => true, + 'params' => array('regex' => '', 'size' => 40, 'maxlength' => 255) +); diff --git a/koward/config/conf.php b/koward/config/conf.php new file mode 100644 index 000000000..656621cbe --- /dev/null +++ b/koward/config/conf.php @@ -0,0 +1,3 @@ + _("Object"), + 'list_label' => _("Objects"), + 'attributes' => array( + 'id' => array( + 'title' => _("Object id"), + 'width' => 80, + 'link_view'=> true, + ), + ), +); + +$objects['Horde_Kolab_Server_Object_user'] = array( + 'label' => _("User"), + 'list_label' => _("Users"), + 'attributes' => array( + 'sn' => array( + 'title' => _("Last name"), + 'width' => 20, + ), + 'givenName' => array( + 'title' => _("First name"), + 'width' => 20, + ), + 'mail' => array( + 'title' => _("E-mail"), + 'width' => 20, + 'link_view'=> true, + ), + 'uid' => array( + 'title' => _("User ID"), + 'width' => 20, + ), + ), +); + +$objects['Horde_Kolab_Server_Object_administrator'] = array( + 'label' => _("Administrator"), + 'list_label' => _("Administrators"), + 'attributes' => array( + ), +); diff --git a/koward/config/routes.php b/koward/config/routes.php new file mode 100644 index 000000000..10434784f --- /dev/null +++ b/koward/config/routes.php @@ -0,0 +1,12 @@ +connect('index', array('controller' => 'index')); +$mapper->connect('index.php', array('controller' => 'index')); + +$mapper->connect('check/:action/:id', array('controller' => 'check', 'action' => 'show')); +$mapper->connect(':controller/:action/:id', array('controller' => 'object')); + +// Local route overrides +if (file_exists(dirname(__FILE__) . '/routes.local.php')) { + include dirname(__FILE__) . '/routes.local.php'; +} diff --git a/koward/doc/QUESTIONS.txt b/koward/doc/QUESTIONS.txt new file mode 100644 index 000000000..0955803d4 --- /dev/null +++ b/koward/doc/QUESTIONS.txt @@ -0,0 +1,5 @@ +Can we have mixed CLI and html views? If we can, will these be in a library install location? + +How to add translations? + +How to install via PEAR? diff --git a/koward/lib/Exception.php b/koward/lib/Exception.php new file mode 100644 index 000000000..3498db45e --- /dev/null +++ b/koward/lib/Exception.php @@ -0,0 +1,30 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward_Server + */ + +/** + * This class provides the standard error class for the Koward application. + * + * Copyright 2009 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Kolab + * @package Koward_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward_Server + */ +class Koward_Exception extends Exception +{ +} diff --git a/koward/lib/Form/Object.php b/koward/lib/Form/Object.php new file mode 100644 index 000000000..5a4a35208 --- /dev/null +++ b/koward/lib/Form/Object.php @@ -0,0 +1,118 @@ +koward = &Koward_Koward::singleton(); + + $this->object = &$object; + + parent::Horde_Form($vars); + + if (empty($this->object)) { + $title = _("Add Object"); + $this->setButtons(_("Add")); + + foreach ($this->koward->objects as $key => $config) { + $options[$key] = $config['label']; + } + + $v = &$this->addVariable(_("Choose an object type"), 'type', 'enum', true, false, null, array($options, true)); + $action = Horde_Form_Action::factory('submit'); + $v->setAction($action); + $v->setOption('trackchange', true); + if (is_null($vars->get('formname')) && + $vars->get($v->getVarName()) != $vars->get('__old_' . $v->getVarName())) { + $this->koward->notification->push(sprintf(_("Selected object type \"%s\"."), $object_conf[$vars->get('type')]['label']), 'horde.message'); + } + } else { + $title = _("Edit Object"); + $type = get_class($this->object); + if (!$this->isSubmitted()) { + $vars->set('type', $type); + $keys = array_keys($this->koward->objects[$type]['attributes']); + $vars->set('object', $this->object->toHash($keys)); + $this->setButtons(_("Edit")); + } + } + + if (isset($params['title'])) { + $title = $params['title']; + } + + $this->setTitle($title); + + $type = $vars->get('type'); + if (isset($type)) { + $this->_addFields($this->koward->objects[$type]); + } + } + + /** + * Set up the Horde_Form fields for the attributes of this object type. + */ + function _addFields($config) + { + // Now run through and add the form variables. + $fields = isset($config['attributes']) ? $config['attributes'] : array(); + $tabs = isset($config['tabs']) ? $config['tabs'] : array('' => $fields); + + foreach ($tabs as $tab => $tab_fields) { + if (!empty($tab)) { + $this->setSection($tab, $tab); + } + foreach ($tab_fields as $key => $field) { + if (!in_array($key, array_keys($fields)) || + !isset($this->koward->attributes[$key])) { + continue; + } + + $attribute = $this->koward->attributes[$key]; + $params = isset($attribute['params']) ? $attribute['params'] : array(); + $desc = isset($attribute['desc']) ? $attribute['desc'] : null; + + $readonly = isset($attribute['readonly']) ? $attribute['readonly'] : null; + $v = &$this->addVariable($attribute['label'], 'object[' . $key . ']', $attribute['type'], $attribute['required'], $readonly, $desc, $params); + } + + if (isset($attribute['default'])) { + $v->setDefault($attribute['default']); + } + } + } + + function &execute() + { + $this->getInfo($this->_vars, $info); + if (isset($info['object'])) { + if (empty($this->object)) { + if (isset($info['type'])) { + $object = $this->koward->server->add(array_merge(array('type' => $info['type']), + $info['object'])); + $this->koward->notification->push(_("Successfully added the object."), + 'horde.message'); + return $object; + } + } else { + $this->object->save($info['object']); + $this->koward->notification->push(_("Successfully updated the object."), + 'horde.message'); + return $this->object; + } + } + } +} diff --git a/koward/lib/Koward.php b/koward/lib/Koward.php new file mode 100644 index 000000000..744eea6fa --- /dev/null +++ b/koward/lib/Koward.php @@ -0,0 +1,87 @@ + + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + * @category Kolab + * @package Koward + */ + +class Koward_Koward { + + /** + * The singleton instance. + * + * @var Koward_Koward + */ + static protected $instance = null; + + public $objectconf; + + public function __construct() + { + require_once 'Horde/Notification.php'; + require_once 'Horde/Registry.php'; + + $this->notification = Notification::singleton(); + $this->registry = Registry::singleton(); + + $result = $this->registry->pushApp('koward', false); + if ($result instanceOf PEAR_Error) { + $this->notification->push($result); + } + + $this->conf = Horde::loadConfiguration('conf.php', 'conf'); + $this->objects = Horde::loadConfiguration('objects.php', 'objects'); + $this->attributes = Horde::loadConfiguration('attributes.php', 'attributes'); + $this->server = Horde_Kolab_Server::singleton(); + } + + /** + * Get a token for protecting a form. + * + * @param string $seed TODO + * + * @return TODO + */ + static public function getRequestToken($seed) + { + $token = Horde_Token::generateId($seed); + $_SESSION['horde_form_secrets'][$token] = time(); + return $token; + } + + /** + * Check if a token for a form is valid. + * + * @param string $seed TODO + * @param string $token TODO + * + * @throws Horde_Exception + */ + static public function checkRequestToken($seed, $token) + { + if (empty($_SESSION['horde_form_secrets'][$token])) { + throw new Horde_Exception(_("We cannot verify that this request was really sent by you. It could be a malicious request. If you intended to perform this action, you can retry it now.")); + } + + if ($_SESSION['horde_form_secrets'][$token] + $GLOBALS['conf']['server']['token_lifetime'] < time()) { + throw new Horde_Exception(sprintf(_("This request cannot be completed because the link you followed or the form you submitted was only valid for %d minutes. Please try again now."), round($GLOBALS['conf']['server']['token_lifetime'] / 60))); + } + } + + public function getObject($uid) + { + return $this->server->fetch($uid); + } + + static public function singleton() + { + if (!isset(self::$instance)) { + self::$instance = new Koward_Koward(); + } + + return self::$instance; + } +} \ No newline at end of file diff --git a/koward/lib/Test.php b/koward/lib/Test.php new file mode 100644 index 000000000..62b937973 --- /dev/null +++ b/koward/lib/Test.php @@ -0,0 +1,173 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ + +/** + * Base for PHPUnit scenarios. + * + * Copyright 2009 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Kolab + * @package Koward + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ +class Koward_Test extends Horde_Kolab_Test_Storage +{ + /** + * Prepare the configuration. + * + * @return NULL + */ + public function prepareConfiguration() + { + $fh = fopen(HORDE_BASE . '/config/conf.php', 'w'); + $data = <<applications['horde'] = array( + 'fileroot' => dirname(__FILE__) . '/..', + 'webroot' => '/', + 'initial_page' => 'login.php', + 'name' => _("Horde"), + 'status' => 'active', + 'templates' => dirname(__FILE__) . '/../templates', + 'provides' => 'horde', +); + +\$this->applications['koward'] = array( + 'fileroot' => KOWARD_BASE, + 'webroot' => \$this->applications['horde']['webroot'] . '/koward', + 'name' => _("Koward"), + 'status' => 'active', + 'initial_page' => 'index.php', +); +EOD; + fwrite($fh, " + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The Autoloader allows us to omit "require/include" statements. + */ +require_once 'Horde/Autoloader.php'; + +/** + * Combine the tests for this package. + * + * Copyright 2007-2009 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Kolab + * @package Kolab_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Koward_Test_AllTests +{ + + /** + * Main entry point for running the suite. + * + * @return NULL + */ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + /** + * Collect the unit tests of this directory into a new suite. + * + * @return PHPUnit_Framework_TestSuite The test suite. + */ + public static function suite() + { + // Catch strict standards + // FIXME: This does not work yet, as we still have a number of + // static methods in basic Horde libraries that are not + // declared as such. + //error_reporting(E_ALL | E_STRICT); + + $suite = new PHPUnit_Framework_TestSuite('Kolab server test suite'); + + $basedir = dirname(__FILE__); + $baseregexp = preg_quote($basedir . DIRECTORY_SEPARATOR, '/'); + + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basedir)) as $file) { + if ($file->isFile() && preg_match('/Test.php$/', $file->getFilename())) { + $pathname = $file->getPathname(); + require $pathname; + + $class = str_replace(DIRECTORY_SEPARATOR, '_', + preg_replace("/^$baseregexp(.*)\.php/", '\\1', $pathname)); + $suite->addTestSuite('Koward_Test_' . $class); + } + } + + return $suite; + } + +} diff --git a/koward/lib/Test/Renderer.php b/koward/lib/Test/Renderer.php new file mode 100644 index 000000000..e8308aa1f --- /dev/null +++ b/koward/lib/Test/Renderer.php @@ -0,0 +1,44 @@ +templatePath = sprintf( + '%s%sTemplate%s', + + dirname(__FILE__), + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR + ); + } + + /** + * @param string $buffer + */ + public function write($buffer) + { + if ($this->out !== NULL) { + fwrite($this->out, $buffer); + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } else { + + print $buffer; + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } + } +} \ No newline at end of file diff --git a/koward/lib/Test/Server/UserTest.php b/koward/lib/Test/Server/UserTest.php new file mode 100644 index 000000000..d2f055924 --- /dev/null +++ b/koward/lib/Test/Server/UserTest.php @@ -0,0 +1,43 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ + +/** + * Test the user object. + * + * Copyright 2009 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Kolab + * @package Koward + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ +class Koward_Test_Server_UserTest extends Horde_Kolab_Test_Server { + + /** + * Test listing users if there are no users. + * + * @scenario + * + * @return NULL + */ + public function listingUsersOnEmptyServer() + { + $this->given('the current Kolab server') + ->when('listing all users') + ->then('the list is an empty array'); + } +} diff --git a/koward/lib/Test/Template/scenario.html.dist b/koward/lib/Test/Template/scenario.html.dist new file mode 100644 index 000000000..caa149aab --- /dev/null +++ b/koward/lib/Test/Template/scenario.html.dist @@ -0,0 +1,13 @@ + + +

[+] {name}

+ + + + + +{steps} +
+ + + diff --git a/koward/lib/Test/Template/scenario_header.html.dist b/koward/lib/Test/Template/scenario_header.html.dist new file mode 100644 index 000000000..7b205d1cd --- /dev/null +++ b/koward/lib/Test/Template/scenario_header.html.dist @@ -0,0 +1,6 @@ + + +

{name}

+ + + diff --git a/koward/lib/Test/Template/scenarios.html.dist b/koward/lib/Test/Template/scenarios.html.dist new file mode 100644 index 000000000..1037cfb70 --- /dev/null +++ b/koward/lib/Test/Template/scenarios.html.dist @@ -0,0 +1,54 @@ + + + + + +{scenarios} + + + +
+

[+] Summary:

+ +
diff --git a/koward/lib/Test/Template/step.html.dist b/koward/lib/Test/Template/step.html.dist new file mode 100644 index 000000000..bcdce3f40 --- /dev/null +++ b/koward/lib/Test/Template/step.html.dist @@ -0,0 +1,6 @@ + + {text} + {action} +   + + diff --git a/koward/test/AllTests.php b/koward/test/AllTests.php new file mode 100644 index 000000000..3d1f3a70c --- /dev/null +++ b/koward/test/AllTests.php @@ -0,0 +1,83 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ + +if (!defined('PHPUnit_MAIN_METHOD')) { + define('PHPUnit_MAIN_METHOD', 'Koward_AllTests::main'); +} + +/** + * Initialize testing for this application. + */ +require_once 'TestInit.php'; + +/** + * Combine the tests for this package. + * + * Copyright 2007-2009 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Kolab + * @package Koward + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ +class Koward_AllTests +{ + /** + * Main entry point for running the suite. + * + * @return NULL + */ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + /** + * Collect the unit tests of this directory into a new suite. + * + * @return PHPUnit_Framework_TestSuite The test suite. + */ + public static function suite() + { + // Catch strict standards + error_reporting(E_ALL | E_STRICT); + + // Build the suite + $suite = new PHPUnit_Framework_TestSuite('Koward'); + + $basedir = dirname(__FILE__); + $baseregexp = preg_quote($basedir . DIRECTORY_SEPARATOR, '/'); + + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basedir)) as $file) { + if ($file->isFile() && preg_match('/Test.php$/', $file->getFilename())) { + $pathname = $file->getPathname(); + require $pathname; + + $class = str_replace(DIRECTORY_SEPARATOR, '_', + preg_replace("/^$baseregexp(.*)\.php/", '\\1', $pathname)); + $suite->addTestSuite('Koward_' . $class); + } + } + + return $suite; + } + +} + +if (PHPUnit_MAIN_METHOD == 'Koward_AllTests::main') { + Koward_AllTests::main(); +} diff --git a/koward/test/KowardTest.php b/koward/test/KowardTest.php new file mode 100644 index 000000000..4b4abf5bb --- /dev/null +++ b/koward/test/KowardTest.php @@ -0,0 +1,95 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ + +/** + * Initialize testing for this application. + */ +require_once 'TestInit.php'; + +/** + * Test the user object. + * + * Copyright 2009 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Kolab + * @package Koward + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ +class Koward_KowardTest extends Koward_Test +{ + /** + * Set up testing. + * + * @return NULL + */ + protected function setUp() + { + $world = $this->prepareBasicSetup(); + + $this->koward = Koward_Koward::singleton(); + } + + /** + * Verify that the Koward object ist initialized correctly. + * + * @return NULL + */ + public function testSetup() + { + $this->assertType('Horde_Kolab_Server', $this->koward->server); + } + + /** + * Verify that we can fetch objects from the Kolab server. + * + * @return NULL + */ + public function testFetching() + { + $this->assertType('Horde_Kolab_Server_Object', $this->koward->getObject('cn=Gunnar Wrobel,dc=example,dc=org')); + } + + /** + * Verify token processing mechanisms. + * + * @return NULL + */ + public function testToken() + { + // Get the token. + $token = $this->koward->getRequestToken('test'); + // Checking it should be fine. + $this->koward->checkRequestToken('test', $token); + // Now we set the token to a value that will be considered a timeout. + $_SESSION['horde_form_secrets'][$token] = time() - 100000; + try { + $this->koward->checkRequestToken('test', $token); + $this->fail('The rquest token is still valid which was not expected.'); + } catch (Horde_Exception $e) { + $this->assertContains(_("This request cannot be completed because the link you followed or the form you submitted was only valid for"), $e->getMessage()); + } + // Now we remove the token + unset($_SESSION['horde_form_secrets'][$token]); + try { + $this->koward->checkRequestToken('test', $token); + $this->fail('The rquest token is still valid which was not expected.'); + } catch (Horde_Exception $e) { + $this->assertEquals(_("We cannot verify that this request was really sent by you. It could be a malicious request. If you intended to perform this action, you can retry it now."), $e->getMessage()); + } + } +} diff --git a/koward/test/TestInit.php b/koward/test/TestInit.php new file mode 100644 index 000000000..8091e44c9 --- /dev/null +++ b/koward/test/TestInit.php @@ -0,0 +1,25 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Koward + */ + +/** + * The Autoloader allows us to omit "require/include" statements. + */ +require_once 'Horde/Autoloader.php'; + +if (!defined('KOWARD_BASE')) { + define('KOWARD_BASE', dirname(__FILE__) . '/../'); +} + +/* Set up the application class and controller loading */ +Horde_Autoloader::addClassPattern('/^Koward_/', KOWARD_BASE . '/lib/'); +Horde_Autoloader::addClassPattern('/^Koward_/', KOWARD_BASE . '/app/controllers/'); diff --git a/koward/themes/graphics/favicon.ico b/koward/themes/graphics/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0f8fa0816309acfe30380bea80a1a40cd3859906 GIT binary patch literal 1406 zcmeH_=~vWc6vsbL%3@kllxZ7=RBlm8i(5*RUCkbSa&0fyx`fgsGUAJa>F;UCcVp1VBv-gEBqTo5u@Sz*FDGZ-gZ zlVu)uO_W(+DNAq^CUu99B#Bnf(d0%&5ikNyELn(DACIJTpeDeXo^*d|u3hDl1B6bo zC3)vYnllrqk61^shaERNn#u5XK`Qq{>dQp!Hj4iIXsTjED9z2J^UNwr_IT2+RuSVg zgHY?S7&S#m*=vzb*-@%IOWpcOG{^5EbJ<)@*jm$R=tp0zrn#|^!Rky}Rbl+P!-xqbzs@QtEn?Uhdq|>nU@F3gt-}(~r{E zRDm|yo0^;)(gFf#Kj%l+#SpYr*O0Dkq5GF3NEfzI6dg+MfJCgjD+a|HDhu-Hsw?1X z++n&p+Np{OMAv;2#hjV+wbY_1E5lHdNR!7H>Iw^~^O{J+gt16HDx~T(T8b_pDW=ns zbs9}>5}FJJ+UwV;%FCkpk1|SrI!}-GFLdRZDlu`}(Mj^XJFi+sTUzr>!7` zq1yvAEVZCJBaolxThOM{(RTg-rP(U_5>KuN^6quqo z`o0iep_7ut!A$ykoI(7!&=)H;)Rxm%dy$ z!8+B(#%9@KF>{vq_PO!m%opoU%y{VC*Tj2vLIk_qE56=*`mr~BMeO6R%dLI1VwI^u z@x$(??;EzZey|`a=a_5b_J zMV_tb%+z-k5oD;F?)ciacU9BPgAB#Na|OQCHT+AEF;G9-@g~h}TTtG{*OLudcLcXx z&Zy+c)qQf}nMVVAPL6%f8kVacd;;=q&V23P%&NLD?#6jGu3gIYJ3!9xboFyt=akR{ E0DOE