Prepare user settings api

Rework application bootstrap, move user object to its new location, implement web
request class to handle the user object.

refs #4066
This commit is contained in:
Marius Hein 2013-07-26 15:58:16 +02:00 committed by Eric Lippmann
parent 457f9b8f50
commit 8510d57cf8
14 changed files with 787 additions and 312 deletions

View File

@ -30,7 +30,8 @@ namespace Icinga\Application;
use Icinga\Application\Modules\Manager as ModuleManager; use Icinga\Application\Modules\Manager as ModuleManager;
use Icinga\Application\Platform; use Icinga\Application\Platform;
use Zend_Loader_Autoloader as ZendLoader; use Icinga\Exception\ProgrammingError;
use Zend_Loader_Autoloader;
use Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
/** /**
@ -54,21 +55,63 @@ use Icinga\Exception\ConfigurationError;
* use Icinga\Application\LegacyWeb; * use Icinga\Application\LegacyWeb;
* LegacyWeb::start()->setIcingaWebBasedir(ICINGAWEB_BASEDIR)->dispatch(); * LegacyWeb::start()->setIcingaWebBasedir(ICINGAWEB_BASEDIR)->dispatch();
* </code> * </code>
*
* @copyright Copyright (c) 2013 Icinga-Web Team <info@icinga.org>
* @author Icinga-Web Team <info@icinga.org>
* @package Icinga\Application
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
*/ */
abstract class ApplicationBootstrap abstract class ApplicationBootstrap
{ {
protected $loader; /**
protected $libdir; * Icinga auto loader
protected $config; *
protected $configDir; * @var Loader
protected $appdir; */
protected $moduleManager; private $loader;
/**
* Library directory
*
* @var string
*/
private $libDir;
/**
* Config object
*
* @var Config
*/
private $config;
/**
* Configuration directory
*
* @var string
*/
private $configDir;
/**
* Application directory
*
* @var string
*/
private $appDir;
/**
* Module manager
*
* @var ModuleManager
*/
private $moduleManager;
/**
* Flag indicates we're on cli environment
*
* @var bool
*/
protected $isCli = false; protected $isCli = false;
/**
* Flag indicates we're on web environment
*
* @var bool
*/
protected $isWeb = false; protected $isWeb = false;
/** /**
@ -78,52 +121,50 @@ abstract class ApplicationBootstrap
*/ */
protected function __construct($configDir) protected function __construct($configDir)
{ {
$this->checkPrerequisites(); $this->libDir = realpath(__DIR__. '/../..');
$this->libdir = realpath(__DIR__. '/../..'); if (!defined('ICINGA_LIBDIR')) {
define('ICINGA_LIBDIR', $this->libDir);
if (! defined('ICINGA_LIBDIR')) {
define('ICINGA_LIBDIR', $this->libdir);
} }
// TODO: Make appdir configurable for packagers // TODO: Make appdir configurable for packagers
$this->appdir = realpath($this->libdir. '/../application'); $this->appDir = realpath($this->libDir. '/../application');
if (! defined('ICINGA_APPDIR')) { if (!defined('ICINGA_APPDIR')) {
define('ICINGA_APPDIR', $this->appdir); define('ICINGA_APPDIR', $this->appDir);
} }
$this->registerAutoloader(); $this->setupAutoloader();
$this->registerZendAutoloader(); $this->setupZendAutoloader();
Benchmark::measure('Bootstrap, autoloader registered'); Benchmark::measure('Bootstrap, autoloader registered');
Icinga::setApp($this); Icinga::setApp($this);
// Unfortunately this is needed to get the Zend Plugin loader working:
set_include_path(
implode(
PATH_SEPARATOR,
array($this->libdir, get_include_path())
)
);
$this->configDir = $configDir; $this->configDir = $configDir;
require_once dirname(__FILE__) . '/functions.php'; require_once dirname(__FILE__) . '/functions.php';
} }
/**
* Bootstrap interface method for concrete bootstrap objects
*
* @return mixed
*/
abstract protected function bootstrap(); abstract protected function bootstrap();
public function moduleManager() /**
* Getter for module manager
*
* @return ModuleManager
*/
public function getModuleManager()
{ {
if ($this->moduleManager === null) {
$this->moduleManager = new ModuleManager($this, $this->configDir . '/enabledModules');
}
return $this->moduleManager; return $this->moduleManager;
} }
/** /**
* Getter for class loader * Getter for class loader
*
* @return Loader * @return Loader
*/ */
public function getLoader() public function getLoader()
@ -131,68 +172,84 @@ abstract class ApplicationBootstrap
return $this->loader; return $this->loader;
} }
protected function loadEnabledModules() /**
* Getter for configuration object
*
* @return Config
*/
public function getConfig()
{ {
$this->moduleManager()->loadEnabledModules(); return $this->config;
return $this;
} }
/**
* Flag indicates we're on cli environment
*
* @return bool
*/
public function isCli() public function isCli()
{ {
return $this->isCli; return $this->isCli;
} }
/**
* Flag indicates we're on web environment
*
* @return bool
*/
public function isWeb() public function isWeb()
{ {
return $this->isWeb; return $this->isWeb;
} }
/**
* Getter for application dir
*
* Optional append sub directory
*
* @param null|string $subdir optional subdir
* @return string
*/
public function getApplicationDir($subdir = null) public function getApplicationDir($subdir = null)
{ {
$dir = $this->appdir; $dir = $this->appDir;
if ($subdir !== null) { if ($subdir !== null) {
$dir .= '/' . ltrim($subdir, '/'); $dir .= '/' . ltrim($subdir, '/');
} }
return $dir; return $dir;
} }
public function hasModule($name) /**
{ * Starting concrete bootstrap classes
return $this->moduleManager()->hasLoaded($name); *
} * @param string $configDir
* @return ApplicationBootstrap
public function getModule($name) */
{
return $this->moduleManager()->getModule($name);
}
public function loadModule($name)
{
return $this->moduleManager()->loadModule($name);
}
public function getConfig()
{
return $this->config;
}
public static function start($configDir) public static function start($configDir)
{ {
$class = get_called_class(); $class = get_called_class();
/** @var ApplicationBootstrap $obj */
$obj = new $class($configDir); $obj = new $class($configDir);
$obj->bootstrap(); $obj->bootstrap();
return $obj; return $obj;
} }
public function registerAutoloader() /**
* Setup icinga auto loader
*
* @return self
*/
public function setupAutoloader()
{ {
require $this->libdir. '/Icinga/Exception/ProgrammingError.php'; require $this->libDir. '/Icinga/Exception/ProgrammingError.php';
require $this->libdir. '/Icinga/Application/Loader.php'; require $this->libDir. '/Icinga/Application/Loader.php';
$this->loader = new Loader(); $this->loader = new Loader();
$this->loader->registerNamespace('Icinga', $this->libdir. '/Icinga'); $this->loader->registerNamespace('Icinga', $this->libDir. '/Icinga');
$this->loader->registerNamespace('Icinga\\Form', $this->appdir. '/forms'); $this->loader->registerNamespace('Icinga\\Form', $this->appDir. '/forms');
$this->loader->register(); $this->loader->register();
return $this;
} }
/** /**
@ -200,46 +257,35 @@ abstract class ApplicationBootstrap
* *
* @return self * @return self
*/ */
protected function registerZendAutoloader() protected function setupZendAutoloader()
{ {
require_once 'Zend/Loader/Autoloader.php'; require_once 'Zend/Loader/Autoloader.php';
ZendLoader::getInstance();
\Zend_Loader_Autoloader::getInstance();
// Unfortunately this is needed to get the Zend Plugin loader working:
set_include_path(
implode(
PATH_SEPARATOR,
array($this->libDir, get_include_path())
)
);
return $this; return $this;
} }
/** /**
* Check whether we have all we need * Setup module loader and all enabled modules
*
* Pretty useless right now as a namespaces class would not work
* with PHP 5.3
* *
* @return self * @return self
*/ */
protected function checkPrerequisites() protected function setupModules()
{ {
if (version_compare(phpversion(), '5.3.0', '<') === true) { $this->moduleManager = new ModuleManager($this, $this->configDir . '/enabledModules');
die('PHP > 5.3.0 required');
}
return $this;
}
/** $this->moduleManager->loadEnabledModules();
* Check whether a given PHP extension is available
* return $this;
* @return boolean
*/
protected function hasExtension($name)
{
if (!extension_loaded($name)) {
if (! @ dl($name)) {
throw new ConfigurationError(
sprintf(
'The PHP extension %s is not available',
$name
)
);
}
}
} }
/** /**
@ -247,34 +293,19 @@ abstract class ApplicationBootstrap
* *
* @return self * @return self
*/ */
protected function loadConfig() protected function setupConfig()
{ {
Config::$configDir = $this->configDir; Config::$configDir = $this->configDir;
$this->config = Config::app(); $this->config = Config::app();
return $this; return $this;
} }
/**
* Configure cache settings
*
* TODO: Right now APC is hardcoded, make this configurable
*
* @return self
*/
protected function configureCache()
{
// TODO: Provide Zend_Cache_Frontend_File for statusdat
//$this->cache = \Zend_Cache::factory('Core', 'Apc');
return $this;
}
/** /**
* Error handling configuration * Error handling configuration
* *
* @return self * @return self
*/ */
protected function configureErrorHandling() protected function setupErrorHandling()
{ {
if ($this->config->get('global', 'environment') == 'development') { if ($this->config->get('global', 'environment') == 'development') {
error_reporting(E_ALL | E_NOTICE); error_reporting(E_ALL | E_NOTICE);
@ -286,15 +317,16 @@ abstract class ApplicationBootstrap
} }
/** /**
* Set timezone settings * Setup default timezone
* *
* @return self * @return self
*/ */
protected function setTimezone() protected function setupTimezone()
{ {
date_default_timezone_set( date_default_timezone_set(
$this->config->global->get('timezone', 'UTC') $this->config->global->get('timezone', 'UTC')
); );
return $this; return $this;
} }
} }

View File

@ -1,9 +1,40 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Application; namespace Icinga\Application;
require_once dirname(__FILE__) . '/ApplicationBootstrap.php'; // @codingStandardsIgnoreStart
require_once dirname(__FILE__). '/ApplicationBootstrap.php';
// @codingStandardsIgnoreStop
/**
* Bootstrapping on cli environment
*/
class Cli extends ApplicationBootstrap class Cli extends ApplicationBootstrap
{ {
protected $isCli = true; protected $isCli = true;
@ -11,22 +42,23 @@ class Cli extends ApplicationBootstrap
protected function bootstrap() protected function bootstrap()
{ {
$this->assertRunningOnCli(); $this->assertRunningOnCli();
return $this->loadConfig()
->configureErrorHandling() return $this->setupConfig()
->setTimezone(); ->setupErrorHandling()
->setupTimezone();
} }
/** /**
* Fail if Icinga has not been called on CLI * Fail if Icinga has not been called on CLI
* *
* @throws Exception * @throws \Exception
* @return void
*/ */
private static function assertRunningOnCli() private function assertRunningOnCli()
{ {
if (Platform::isCli()) { if (Platform::isCli()) {
return; return;
} }
throw new Exception('Icinga is not running on CLI');
throw new \Exception('Icinga is not running on CLI');
} }
} }

View File

@ -1,13 +1,37 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}}
/** /**
* Run embedded in other web applications * This file is part of Icinga 2 Web.
* *
* @package Icinga\Application * Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/ */
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Application; namespace Icinga\Application;
// @codingStandardsIgnoreStart
require_once dirname(__FILE__) . '/ApplicationBootstrap.php'; require_once dirname(__FILE__) . '/ApplicationBootstrap.php';
// @codingStandardsIgnoreStop
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
/** /**
@ -18,19 +42,20 @@ use Icinga\Exception\ProgrammingError;
* use Icinga\Application\EmbeddedWeb; * use Icinga\Application\EmbeddedWeb;
* EmbeddedWeb::start(); * EmbeddedWeb::start();
* </code> * </code>
*
* @copyright Copyright (c) 2013 Icinga-Web Team <info@icinga.org>
* @author Icinga-Web Team <info@icinga.org>
* @package Icinga\Application
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
*/ */
class EmbeddedWeb extends ApplicationBootstrap class EmbeddedWeb extends ApplicationBootstrap
{ {
/**
* Embedded bootstrap parts
*
* @see ApplicationBootstrap::bootstrap
* @return self
*/
protected function bootstrap() protected function bootstrap()
{ {
return $this->loadConfig() return $this->setupConfig()
->configureErrorHandling() ->setupErrorHandling()
->setTimezone() ->setupTimezone()
->loadEnabledModules(); ->setupModules();
} }
} }

View File

@ -1,26 +1,72 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Application; namespace Icinga\Application;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
/**
* Icinga application container
*/
class Icinga class Icinga
{ {
protected static $app; /**
* @var ApplicationBootstrap
*/
private static $app;
/**
* Getter for an application environment
*
* @return ApplicationBootstrap|Web
* @throws ProgrammingError
*/
public static function app() public static function app()
{ {
if (null === self::$app) { if (self::$app == null) {
throw new ProgrammingError('Icinga has never been started'); throw new ProgrammingError('Icinga has never been started');
} }
return self::$app; return self::$app;
} }
public static function setApp($app) /**
* Setter for an application environment
*
* @param ApplicationBootstrap $app
* @throws ProgrammingError
*/
public static function setApp(ApplicationBootstrap $app)
{ {
if (null !== self::$app) { if (self::$app !== null) {
throw new ProgrammingError('Cannot start Icinga twice'); throw new ProgrammingError('Cannot start Icinga twice');
} }
self::$app = $app; self::$app = $app;
} }
} }

View File

@ -30,6 +30,7 @@ namespace Icinga\Application\Modules;
use Icinga\Application\ApplicationBootstrap; use Icinga\Application\ApplicationBootstrap;
use Icinga\Application\Config; use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Web\Hook; use Icinga\Web\Hook;
use Zend_Controller_Router_Route as Route; use Zend_Controller_Router_Route as Route;
@ -42,58 +43,74 @@ class Module
{ {
/** /**
* Module name * Module name
*
* @var string * @var string
*/ */
private $name; private $name;
/** /**
* Base directory of module * Base directory of module
*
* @var string * @var string
*/ */
private $basedir; private $basedir;
/** /**
* Directory for styles * Directory for styles
*
* @var string * @var string
*/ */
private $cssdir; private $cssdir;
/** /**
* Library directory * Library directory
*
* @var string * @var string
*/ */
private $libdir; private $libdir;
/** /**
* Directory containing translations * Directory containing translations
*
* @var string * @var string
*/ */
private $localedir; private $localedir;
/** /**
* Directory where controllers reside * Directory where controllers reside
*
* @var string * @var string
*/ */
private $controllerdir; private $controllerdir;
/** /**
* Directory containing form implementations * Directory containing form implementations
*
* @var string * @var string
*/ */
private $formdir; private $formdir;
/** /**
* Module bootstrapping script * Module bootstrapping script
*
* @var string * @var string
*/ */
private $registerscript; private $registerscript;
/** /**
* Icinga application * Icinga application
* @var \Icinga\Application\ApplicationBootstrap *
* @var \Icinga\Application\Web
*/ */
private $app; private $app;
/**
* Creates a new module object
*
* @param ApplicationBootstrap $app
* @param string $name
* @param strinb $basedir
*/
public function __construct(ApplicationBootstrap $app, $name, $basedir) public function __construct(ApplicationBootstrap $app, $name, $basedir)
{ {
$this->app = $app; $this->app = $app;
@ -110,6 +127,7 @@ class Module
/** /**
* Register module * Register module
*
* @return bool * @return bool
*/ */
public function register() public function register()
@ -122,18 +140,26 @@ class Module
/** /**
* Test for an enabled module by name * Test for an enabled module by name
*
* @param string $name * @param string $name
* @return boolean * @return boolean
*/ */
public static function exists($name) public static function exists($name)
{ {
return Icinga::app()->moduleManager()->hasEnabled($name); return Icinga::app()->getModuleManager()->hasEnabled($name);
} }
/**
* Get module by name
*
* @param string $name
* @param bool $autoload
* @return mixed
*/
public static function get($name, $autoload = false) public static function get($name, $autoload = false)
{ {
$manager = Icinga::app()->moduleManager(); $manager = Icinga::app()->getModuleManager();
if (! $manager->hasLoaded($name)) { if (!$manager->hasLoaded($name)) {
if ($autoload === true && $manager->hasEnabled($name)) { if ($autoload === true && $manager->hasEnabled($name)) {
$manager->loadModule($name); $manager->loadModule($name);
} }
@ -144,6 +170,7 @@ class Module
/** /**
* Test if module provide css * Test if module provide css
*
* @return bool * @return bool
*/ */
public function hasCss() public function hasCss()
@ -153,6 +180,8 @@ class Module
/** /**
* Getter for module name * Getter for module name
*
* @return string
*/ */
public function getName() public function getName()
{ {
@ -161,6 +190,7 @@ class Module
/** /**
* Getter for css file name * Getter for css file name
*
* @return string * @return string
*/ */
public function getCssFilename() public function getCssFilename()
@ -179,6 +209,7 @@ class Module
/** /**
* Getter for library directory * Getter for library directory
*
* @return string * @return string
*/ */
public function getLibDir() public function getLibDir()
@ -188,6 +219,7 @@ class Module
/** /**
* Getter for configuration directory * Getter for configuration directory
*
* @return string * @return string
*/ */
public function getConfigDir() public function getConfigDir()
@ -197,6 +229,7 @@ class Module
/** /**
* Getter for form directory * Getter for form directory
*
* @return string * @return string
*/ */
public function getFormDir() public function getFormDir()
@ -206,7 +239,8 @@ class Module
/** /**
* Getter for module config object * Getter for module config object
* @param null|string $file *
* @param null|string $file
* @return Config * @return Config
*/ */
public function getConfig($file = null) public function getConfig($file = null)
@ -218,7 +252,8 @@ class Module
/** /**
* Register new namespaces on the autoloader * Register new namespaces on the autoloader
* @return Module *
* @return self
*/ */
protected function registerAutoloader() protected function registerAutoloader()
{ {
@ -237,7 +272,8 @@ class Module
/** /**
* Bind text domain for i18n * Bind text domain for i18n
* @return Module *
* @return self
*/ */
protected function registerLocales() protected function registerLocales()
{ {
@ -252,7 +288,7 @@ class Module
* *
* Add controller directory to mvc * Add controller directory to mvc
* *
* @return Module * @return self
*/ */
protected function registerWebIntegration() protected function registerWebIntegration()
{ {
@ -261,7 +297,7 @@ class Module
} }
if (file_exists($this->controllerdir) && is_dir($this->controllerdir)) { if (file_exists($this->controllerdir) && is_dir($this->controllerdir)) {
$this->app->frontController()->addControllerDirectory( $this->app->getfrontController()->addControllerDirectory(
$this->controllerdir, $this->controllerdir,
$this->name $this->name
); );
@ -275,14 +311,15 @@ class Module
/** /**
* Register menu entries * Register menu entries
* @return Module *
* @return self
*/ */
protected function registerMenuEntries() protected function registerMenuEntries()
{ {
$cfg = $this->app $cfg = $this->app
->getConfig() ->getConfig()
->module($this->name, 'menu'); ->module($this->name, 'menu');
$view = $this->app->getView(); $view = $this->app->getViewRenderer();
if ($cfg) { if ($cfg) {
$view->view->navigation = $cfg->merge($view->view->navigation); $view->view->navigation = $cfg->merge($view->view->navigation);
} }
@ -291,11 +328,12 @@ class Module
/** /**
* Register routes for web access * Register routes for web access
* @return Module *
* @return self
*/ */
protected function registerRoutes() protected function registerRoutes()
{ {
$this->app->frontController()->getRouter()->addRoute( $this->app->getFrontController()->getRouter()->addRoute(
$this->name . '_jsprovider', $this->name . '_jsprovider',
new Route( new Route(
'js/' . $this->name . '/:file', 'js/' . $this->name . '/:file',
@ -306,7 +344,7 @@ class Module
) )
) )
); );
$this->app->frontController()->getRouter()->addRoute( $this->app->getFrontController()->getRouter()->addRoute(
$this->name . '_img', $this->name . '_img',
new Route( new Route(
'img/' . $this->name . '/:file', 'img/' . $this->name . '/:file',
@ -322,7 +360,8 @@ class Module
/** /**
* Run module bootstrap script * Run module bootstrap script
* @return Module *
* @return self
*/ */
protected function runRegisterScript() protected function runRegisterScript()
{ {
@ -335,10 +374,11 @@ class Module
/** /**
* Register hook * Register hook
*
* @param string $name * @param string $name
* @param string $class * @param string $class
* @param string $key * @param string $key
* @return Module * @return self
*/ */
protected function registerHook($name, $key, $class) protected function registerHook($name, $key, $class)
{ {

View File

@ -2,24 +2,24 @@
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
/** /**
* This file is part of Icinga 2 Web. * This file is part of Icinga 2 Web.
* *
* Icinga 2 Web - Head for multiple monitoring backends. * Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team * Copyright (C) 2013 Icinga Development Team
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* @copyright 2013 Icinga Development Team <info@icinga.org> * @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org> * @author Icinga Development Team <info@icinga.org>
@ -28,14 +28,18 @@
namespace Icinga\Application; namespace Icinga\Application;
use Icinga\Authentication\Manager; use Icinga\Authentication\Manager as AuthenticationManager;
use Zend_Controller_Front as FrontController; use Icinga\Exception\ProgrammingError;
use Zend_Layout as Layout; use Icinga\User\Preferences;
use Zend_Paginator as Paginator; use Icinga\Web\Request;
use Zend_View_Helper_PaginationControl as PaginationControl; use Zend_Controller_Front;
use Zend_Controller_Action_HelperBroker as ActionHelper; use Zend_Layout;
use Zend_Controller_Router_Route as Route; use Zend_Paginator;
use Icinga\Web\View as IcingaView; use Zend_View_Helper_PaginationControl;
use Zend_Controller_Action_HelperBroker;
use Zend_Controller_Router_Route;
use Zend_Controller_Action_Helper_ViewRenderer;
use Icinga\Web\View;
/** /**
* Use this if you want to make use of Icinga funtionality in other web projects * Use this if you want to make use of Icinga funtionality in other web projects
@ -45,77 +49,114 @@ use Icinga\Web\View as IcingaView;
* use Icinga\Application\EmbeddedWeb; * use Icinga\Application\EmbeddedWeb;
* EmbeddedWeb::start(); * EmbeddedWeb::start();
* </code> * </code>
*
* @copyright Copyright (c) 2013 Icinga-Web Team <info@icinga.org>
* @author Icinga-Web Team <info@icinga.org>
* @package Icinga\Application
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
*/ */
class Web extends ApplicationBootstrap class Web extends ApplicationBootstrap
{ {
protected $view; /**
protected $frontController; * View object
*
* @var View
*/
private $viewRenderer;
/**
* Zend front controller instance
*
* @var Zend_Controller_Front
*/
private $frontController;
/**
* Request object
*
* @var Request
*/
private $request;
/**
* Identify web bootstrap
*
* @var bool
*/
protected $isWeb = true; protected $isWeb = true;
/**
* Initialize all together
*
* @return self
*/
protected function bootstrap() protected function bootstrap()
{ {
return $this->loadConfig() return $this->setupConfig()
->configureErrorHandling() ->setupErrorHandling()
->setTimezone() ->setupTimezone()
->configureCache() ->setupRequest()
->prepareZendMvc() ->setupZendMvc()
->loadTranslations() ->setupTranslation()
->loadEnabledModules() ->setupModules()
->setupSpecialRoutes() ->setupRoute()
->configurePagination(); ->setupPagination();
} }
protected function setupSpecialRoutes() /**
* Prepare routing
*
* @return self
*/
private function setupRoute()
{ {
// TODO: Find a better solution // TODO: Find a better solution
$this->frontController->getRouter()->addRoute( $this->frontController->getRouter()->addRoute(
'module_overview', 'module_overview',
new Route( new Zend_Controller_Router_Route(
'js/modules/list.js', 'js/modules/list.js',
array( array(
'controller' => 'static', 'controller' => 'static',
'action' => 'modulelist', 'action' => 'modulelist',
) )
) )
); );
$this->frontController->getRouter()->addRoute( $this->frontController->getRouter()->addRoute(
'module_javascript', 'module_javascript',
new Route( new Zend_Controller_Router_Route(
'js/modules/:module_name/:file', 'js/modules/:module_name/:file',
array( array(
'controller' => 'static', 'controller' => 'static',
'action' => 'javascript' 'action' => 'javascript'
) )
) )
); );
return $this; return $this;
} }
public function frontController() /**
* Getter for frontController
*
* @return Zend_Controller_Front
*/
public function getFrontController()
{ {
// TODO: ProgrammingError if null
return $this->frontController; return $this->frontController;
} }
public function getView() /**
* Getter for view
*
* @return View
*/
public function getViewRenderer()
{ {
// TODO: ProgrammingError if null return $this->viewRenderer;
return $this->view;
} }
public function dispatch() /**
{ * Load translations
$this->dispatchFrontController(); *
} * @return self
*/
private function setupTranslation()
protected function loadTranslations()
{ {
// AuthManager::getInstance()->getSession()->language; // AuthManager::getInstance()->getSession()->language;
$locale = null; $locale = null;
@ -124,16 +165,17 @@ class Web extends ApplicationBootstrap
} }
putenv('LC_ALL=' . $locale . '.UTF-8'); putenv('LC_ALL=' . $locale . '.UTF-8');
setlocale(LC_ALL, $locale . '.UTF-8'); setlocale(LC_ALL, $locale . '.UTF-8');
bindtextdomain('icinga', ICINGA_APPDIR . '/locale'); bindtextdomain('icinga', $this->getApplicationDir() . '/locale');
textdomain('icinga'); textdomain('icinga');
return $this; return $this;
} }
protected function dispatchFrontController() /**
* Dispatch public interface
*/
public function dispatch()
{ {
// AuthManager::getInstance()->getSession();
$this->frontController->dispatch(); $this->frontController->dispatch();
return $this;
} }
/** /**
@ -141,25 +183,62 @@ class Web extends ApplicationBootstrap
* *
* @return self * @return self
*/ */
protected function prepareZendMvc() private function setupZendMvc()
{ {
// TODO: Replace Zend_Application: // TODO: Replace Zend_Application:
Layout::startMvc( Zend_Layout::startMvc(
array( array(
'layout' => 'layout', 'layout' => 'layout',
'layoutPath' => $this->appdir . '/layouts/scripts' 'layoutPath' => $this->getApplicationDir('/layouts/scripts')
) )
); );
return $this->prepareFrontController() $this->setupFrontController();
->prepareView(); $this->setupViewRenderer();
return $this;
} }
protected function prepareFrontController() /**
* Injects dependencies into request
*
* @return self
*/
private function setupRequest()
{ {
$this->frontController = FrontController::getInstance(); $this->request = new Request();
$this->frontController->setControllerDirectory($this->appdir . '/controllers'); $authenticationManager = AuthenticationManager::getInstance(
null,
array(
'writeSession' => true
)
);
if ($authenticationManager->isAuthenticated() === true) {
$user = $authenticationManager->getUser();
$preferences = new Preferences();
$user->setPreferences($preferences);
$this->request->setUser($user);
}
return $this;
}
/**
* Instantiate front controller
*
* @return self
*/
private function setupFrontController()
{
$this->frontController = Zend_Controller_Front::getInstance();
$this->frontController->setRequest($this->request);
$this->frontController->setControllerDirectory($this->getApplicationDir('/controllers'));
$this->frontController->setParams( $this->frontController->setParams(
array( array(
@ -170,43 +249,52 @@ class Web extends ApplicationBootstrap
return $this; return $this;
} }
protected function prepareView() /**
* Register helper paths and views for renderer
*
* @return self
*/
private function setupViewRenderer()
{ {
$view = ActionHelper::getStaticHelper('viewRenderer'); /** @var \Zend_Controller_Action_Helper_ViewRenderer $view */
$view->setView(new IcingaView()); $view = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$view->setView(new View());
$view->view->addHelperPath($this->appdir . '/views/helpers'); $view->view->addHelperPath($this->getApplicationDir('/views/helpers'));
// TODO: find out how to avoid this additional helper path: // TODO: find out how to avoid this additional helper path:
$view->view->addHelperPath($this->appdir . '/views/helpers/layout'); $view->view->addHelperPath($this->getApplicationDir('/views/helpers/layout'));
$view->view->setEncoding('UTF-8'); $view->view->setEncoding('UTF-8');
$view->view->headTitle()->prepend( $view->view->headTitle()->prepend(
$this->config->{'global'}->get('project', 'Icinga') $this->getConfig()->{'global'}->get('project', 'Icinga')
); );
$view->view->headTitle()->setSeparator(' :: ');
$view->view->navigation = $this->config->app('menu');
$this->view = $view; $view->view->headTitle()->setSeparator(' :: ');
$view->view->navigation = $this->getConfig()->app('menu');
$this->viewRenderer = $view;
return $this; return $this;
} }
/** /**
* Configure pagination settings * Configure pagination settings
*
* @return self * @return self
*/ */
protected function configurePagination() private function setupPagination()
{ {
Paginator::addScrollingStylePrefixPath( Zend_Paginator::addScrollingStylePrefixPath(
'Icinga_Web_Paginator_ScrollingStyle', 'Icinga_Web_Paginator_ScrollingStyle',
'Icinga/Web/Paginator/ScrollingStyle' 'Icinga/Web/Paginator/ScrollingStyle'
); );
Paginator::setDefaultScrollingStyle('SlidingWithBorder'); Zend_Paginator::setDefaultScrollingStyle('SlidingWithBorder');
PaginationControl::setDefaultViewPartial( Zend_View_Helper_PaginationControl::setDefaultViewPartial(
array('mixedPagination.phtml', 'default') array('mixedPagination.phtml', 'default')
); );
return $this; return $this;
} }
} }

View File

@ -28,7 +28,7 @@
namespace Icinga\Authentication\Backend; namespace Icinga\Authentication\Backend;
use Icinga\Authentication\User as User; use Icinga\User;
use Icinga\Authentication\UserBackend; use Icinga\Authentication\UserBackend;
use Icinga\Authentication\Credentials; use Icinga\Authentication\Credentials;
use Icinga\Protocol\Ldap; use Icinga\Protocol\Ldap;
@ -94,10 +94,16 @@ class LdapUserBackend implements UserBackend
protected function selectUsername($username) protected function selectUsername($username)
{ {
return $this->connection->select() return $this->connection->select()
->from(IcingaConfig::app('authentication')->users->user_class, ->from(
array(IcingaConfig::app('authentication')->users->user_name_attribute)) IcingaConfig::app('authentication')->users->user_class,
->where(IcingaConfig::app('authentication')->users->user_name_attribute, array(
$this->stripAsterisks($username)); IcingaConfig::app('authentication')->users->user_name_attribute
)
)
->where(
IcingaConfig::app('authentication')->users->user_name_attribute,
$this->stripAsterisks($username)
);
} }
/** /**

View File

@ -2,58 +2,115 @@
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
/** /**
* This file is part of Icinga 2 Web. * This file is part of Icinga 2 Web.
* *
* Icinga 2 Web - Head for multiple monitoring backends. * Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team * Copyright (C) 2013 Icinga Development Team
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *
* @copyright 2013 Icinga Development Team <info@icinga.org> * @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org> * @author Icinga Development Team <info@icinga.org>
*/ */
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Authentication; namespace Icinga;
use Icinga\User\Preferences;
use InvalidArgumentException;
/** /**
* This class represents an authorized user and can be used * This class represents an authorized user
* to retrieve authorization information (@TODO: Not implemented yet) or *
* to retrieve user information * You can retrieve authorization information (@TODO: Not implemented yet) or
* to retrieve user information
* *
*/ */
class User class User
{ {
public $username = "";
public $firstname = "";
public $lastname = "";
public $email = "";
public $domain = "";
public $additionalInformation = array();
public $permissions = array();
public $groups = array();
/** /**
* Creates a user object given the provided information * Username
* *
* @param String $username * @var string
* @param String $firstname */
* @param String $lastname private $username;
* @param String $email
**/ /**
* Firstname
*
* @var string
*/
private $firstname;
/**
* Lastname
*
* @var string
*/
private $lastname;
/**
* Users email address
*
* @var string
*/
private $email;
/**
* Domain
*
* @var string
*/
private $domain;
/**
* More information about user
*
* @var array
*/
private $additionalInformation = array();
/**
* Set of permissions
*
* @var array
*/
private $permissions = array();
/**
* Groups for this user
*
* @var array
*/
private $groups = array();
/**
* Preferences object
*
* @var Preferences
*/
private $preferences;
/**
* Creates a user object given the provided information
*
* @param string $username
* @param string $firstname
* @param string $lastname
* @param string $email
*/
public function __construct($username, $firstname = null, $lastname = null, $email = null) public function __construct($username, $firstname = null, $lastname = null, $email = null)
{ {
$this->setUsername($username); $this->setUsername($username);
@ -72,143 +129,186 @@ class User
} }
/** /**
* Returns all groups this user belongs to * Setter for preferences
* *
* @return Array * @param Preferences $preferences
**/ */
public function setPreferences(Preferences $preferences)
{
$this->preferences = $preferences;
}
/**
* Getter for preferences
*
* @return Preferences
*/
public function getPreferences()
{
return $this->preferences;
}
/**
* Returns all groups this user belongs to
*
* @return array
*/
public function getGroups() public function getGroups()
{ {
return $this->groups; return $this->groups;
} }
/** /**
* Sets the groups this user belongs to * Sets the groups this user belongs to
* */
* @return Array
**/
public function setGroups(array $groups) public function setGroups(array $groups)
{ {
$this->groups = $groups; $this->groups = $groups;
} }
/** /**
* Returns true if the user is a member of this group * Returns true if the user is a member of this group
* *
* @return Boolean * @param string $group
**/ * @return boolean
public function isMemberOf(Group $group) */
public function isMemberOf($group)
{ {
return in_array($group, $this->groups); return in_array($group, $this->groups);
} }
/** /**
* Returns permission information for this user * Returns permission information for this user
* *
* @return Array * @return Array
**/ */
public function getPermissions() public function getPermissions()
{ {
return $this->permissions; return $this->permissions;
} }
/** /**
* @return String * Getter for username
**/ *
* @return string
*/
public function getUsername() public function getUsername()
{ {
return $this->username; return $this->username;
} }
/** /**
* @param String $name * Setter for username
**/ *
* @param string $name
*/
public function setUsername($name) public function setUsername($name)
{ {
$this->username = $name; $this->username = $name;
} }
/** /**
* @return String * Getter for firstname
**/ *
* @return string
*/
public function getFirstname() public function getFirstname()
{ {
return $this->firstname; return $this->firstname;
} }
/*+ /**
* @param String $name * Setter for firstname
**/ *
* @param string $name
*/
public function setFirstname($name) public function setFirstname($name)
{ {
$this->firstname = $name; $this->firstname = $name;
} }
/** /**
* @return String * Getter for lastname
**/ *
* @return string
*/
public function getLastname() public function getLastname()
{ {
return $this->lastname; return $this->lastname;
} }
/** /**
* @param String $name * Setter for lastname
**/ *
* @param string $name
*/
public function setLastname($name) public function setLastname($name)
{ {
$this->lastname = $name; $this->lastname = $name;
} }
/** /**
* @return String * Getter for email
**/ *
* @return string
*/
public function getEmail() public function getEmail()
{ {
return $this->email; return $this->email;
} }
/** /**
* @param String $mail * Setter for mail
* *
* @throws \InvalidArgumentException When an invalid mail is provided * @param string $mail
**/ * @throws InvalidArgumentException When an invalid mail is provided
*/
public function setEmail($mail) public function setEmail($mail)
{ {
if (filter_var($mail, FILTER_VALIDATE_EMAIL)) { if (filter_var($mail, FILTER_VALIDATE_EMAIL)) {
$this->mail = $mail; $this->mail = $mail;
} else { } else {
throw new \InvalidArgumentException("Invalid mail given for user $this->username: $mail"); throw new InvalidArgumentException("Invalid mail given for user $this->username: $mail");
} }
} }
/** /**
* @param String $domain * Setter for domain
**/ *
* @param string $domain
*/
public function setDomain($domain) public function setDomain($domain)
{ {
$this->domain = $domain; $this->domain = $domain;
} }
/** /**
* @return String * Getter for domain
**/ *
* @return string
*/
public function getDomain() public function getDomain()
{ {
return $this->domain; return $this->domain;
} }
/** /**
* @param String $key * Sets additional information about user
* @param String $value *
**/ * @param string $key
* @param string $value
*/
public function setAdditional($key, $value) public function setAdditional($key, $value)
{ {
$this->additionalInformation[$key] = $value; $this->additionalInformation[$key] = $value;
} }
/** /**
* @return mixed * Getter for additional information
**/ *
* @param string $key
* @return mixed|null
*/
public function getAdditional($key) public function getAdditional($key)
{ {
if (isset($this->additionalInformation[$key])) { if (isset($this->additionalInformation[$key])) {

View File

@ -0,0 +1,36 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\User;
/**
* Handling retrieve and persist of user preferences
*/
class Preferences
{
}

View File

@ -0,0 +1,71 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web;
use Icinga\Exception\ProgrammingError;
use Zend_Controller_Request_Http;
use Icinga\User;
/**
* Request to handle special attributes
*/
class Request extends Zend_Controller_Request_Http
{
/**
* User object
*
* @var User
*/
private $user;
/**
* Setter for user
*
* @param User $user
*/
public function setUser(User $user)
{
$this->user = $user;
}
/**
* Getter for user
*
* @throws ProgrammingError
* @return User
*/
public function getUser()
{
if (!$this->user instanceof User) {
throw new ProgrammingError('User not previously initialized');
}
return $this->user;
}
}

View File

@ -15,7 +15,7 @@ class Url
public function __construct($url, $params = null, $request = null) public function __construct($url, $params = null, $request = null)
{ {
if ($request === null) { if ($request === null) {
$this->request = Icinga::app()->frontController()->getRequest(); $this->request = Icinga::app()->getFrontController()->getRequest();
} else { } else {
// Tests only // Tests only
$this->request = $request; $this->request = $request;
@ -158,4 +158,3 @@ class Url
return $base . $url; return $base . $url;
} }
} }

View File

View File

@ -4,13 +4,13 @@
namespace Tests\Icinga\Authentication; namespace Tests\Icinga\Authentication;
require_once("../../library/Icinga/Authentication/Credentials.php"); require_once __DIR__. '/../../../../../library/Icinga/Authentication/Credentials.php';
require_once("../../library/Icinga/Authentication/UserBackend.php"); require_once __DIR__. '/../../../../../library/Icinga/Authentication/UserBackend.php';
require_once("../../library/Icinga/Authentication/User.php"); require_once __DIR__. '/../../../../../library/Icinga/User.php';
use Icinga\Authentication\Credentials as Credentials; use Icinga\Authentication\Credentials as Credentials;
use Icinga\Authentication\UserBackend as UserBackend; use Icinga\Authentication\UserBackend as UserBackend;
use Icinga\Authentication\User as User; use Icinga\User;
/** /**
* Simple backend mock that takes an config object * Simple backend mock that takes an config object

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Tests\Icinga\Authentication; namespace Tests\Icinga;
/** /**
* *
* Test class for User * Test class for User