Merge branch 'master' into feature/display-documentation-4820
This commit is contained in:
commit
25a73ea3a1
|
@ -63,8 +63,6 @@ class AuthenticationController extends ActionController
|
|||
$this->view->form = new LoginForm();
|
||||
$this->view->form->setRequest($this->_request);
|
||||
$this->view->title = $this->translate('Icingaweb Login');
|
||||
$user = new User('');
|
||||
$password = '';
|
||||
|
||||
try {
|
||||
$redirectUrl = Url::fromPath($this->_request->getParam('redirect', 'dashboard'));
|
||||
|
@ -95,9 +93,10 @@ class AuthenticationController extends ActionController
|
|||
|
||||
|
||||
if ($this->getRequest()->isGet()) {
|
||||
$user = new User('');
|
||||
foreach ($chain as $backend) {
|
||||
if ($backend instanceof AutoLoginBackend) {
|
||||
$authenticated = $backend->authenticate($user, $password);
|
||||
$authenticated = $backend->authenticate($user);
|
||||
if ($authenticated === true) {
|
||||
$auth->setAuthenticated($user);
|
||||
$this->redirectNow($redirectUrl);
|
||||
|
|
|
@ -179,9 +179,12 @@ class LdapBackendForm extends BaseBackendForm
|
|||
$backendConfig->user_class,
|
||||
$backendConfig->user_name_attribute
|
||||
);
|
||||
$testConn->assertAuthenticationPossible();
|
||||
/*
|
||||
if ($testConn->count() === 0) {
|
||||
throw new Exception('No Users Found On Directory Server');
|
||||
}
|
||||
*/
|
||||
} catch (Exception $exc) {
|
||||
$this->addErrorMessage(
|
||||
t('Connection Validation Failed: ' . $exc->getMessage())
|
||||
|
|
|
@ -10,17 +10,16 @@ if (array_key_exists('_dev', $_GET)) {
|
|||
$cssfile = 'css/icinga.min.css';
|
||||
}
|
||||
|
||||
$ie8jsfile = 'js/icinga.ie8.js';
|
||||
|
||||
$isIframe = isset($_GET['_render']) && $_GET['_render'] === 'iframe';
|
||||
$iframeClass = $isIframe ? ' iframe' : '';
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<!--[if lt IE 7]>
|
||||
<html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
|
||||
<!--[if IE 7]>
|
||||
<html class="no-js lt-ie9 lt-ie8"> <![endif]-->
|
||||
<!--[if IE 8]>
|
||||
<html class="no-js lt-ie9"> <![endif]-->
|
||||
<html class="no-js ie8<?= $iframeClass ?>"> <![endif]-->
|
||||
<!--[if gt IE 8]><!-->
|
||||
<html class="no-js<?= $isIframe ? ' iframe' : '' ?>"> <!--<![endif]-->
|
||||
<html class="no-js<?= $iframeClass ?>"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
|
||||
|
@ -50,7 +49,12 @@ $isIframe = isset($_GET['_render']) && $_GET['_render'] === 'iframe';
|
|||
<div id="layout" class="default-layout">
|
||||
<?= $this->render('body.phtml') ?>
|
||||
</div>
|
||||
<!--[if IE 8]>
|
||||
<script type="text/javascript" src="<?= $this->href($ie8jsfile) ?>"></script>
|
||||
<![endif]-->
|
||||
<!--[if gt IE 8]><!-->
|
||||
<script type="text/javascript" src="<?= $this->href($jsfile) ?>"></script>
|
||||
<!--<![endif]-->
|
||||
<script type="text/javascript">
|
||||
var icinga = new Icinga({
|
||||
baseUrl: '<?= $this->href('/') ?>'
|
||||
|
|
|
@ -14,7 +14,7 @@ timeFormat = "g:i A"
|
|||
[logging]
|
||||
enable = true
|
||||
; Writing to a Stream
|
||||
type = "stream"
|
||||
type = "file"
|
||||
; Write data to the following file
|
||||
target = "@icingaweb_log_path@/icingaweb.log"
|
||||
; Write data to a PHP stream
|
||||
|
@ -22,8 +22,8 @@ target = "@icingaweb_log_path@/icingaweb.log"
|
|||
|
||||
; Writing to the System Log
|
||||
;type = "syslog"
|
||||
; Prefix all syslog messages generated with the string "Icinga Web"
|
||||
;application = "Icinga Web"
|
||||
; Prefix all syslog messages generated with the string "icingaweb"
|
||||
;application = "icingaweb"
|
||||
;facility = "LOG_USER"
|
||||
|
||||
level = 1
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
namespace Icinga\Application;
|
||||
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
use Zend_Config;
|
||||
use Icinga\Application\Modules\Manager as ModuleManager;
|
||||
|
@ -484,7 +483,7 @@ abstract class ApplicationBootstrap
|
|||
|
||||
$localeDir = $this->getApplicationDir('locale');
|
||||
if (file_exists($localeDir) && is_dir($localeDir)) {
|
||||
Translator::registerDomain('icinga', $localeDir);
|
||||
Translator::registerDomain(Translator::DEFAULT_DOMAIN, $localeDir);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -32,7 +32,7 @@ use \Icinga\Util\Translator;
|
|||
if (extension_loaded('gettext')) {
|
||||
function t($messageId)
|
||||
{
|
||||
return Translator::translate($messageId, 'icinga');
|
||||
return Translator::translate($messageId, Translator::DEFAULT_DOMAIN);
|
||||
}
|
||||
|
||||
function mt($domain, $messageId)
|
||||
|
|
|
@ -47,6 +47,7 @@ $special = array(
|
|||
'css/icinga.css',
|
||||
'css/icinga.min.css',
|
||||
'js/icinga.dev.js',
|
||||
'js/icinga.ie8.js',
|
||||
'js/icinga.min.js'
|
||||
);
|
||||
|
||||
|
@ -72,6 +73,10 @@ if (in_array($path, $special)) {
|
|||
JavaScript::sendMinified();
|
||||
break;
|
||||
|
||||
case 'js/icinga.ie8.js':
|
||||
JavaScript::sendForIe8();
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
namespace Icinga\Authentication\Backend;
|
||||
|
||||
use Zend_Config;
|
||||
use Icinga\Authentication\UserBackend;
|
||||
use Icinga\User;
|
||||
use \Zend_Config;
|
||||
|
||||
/**
|
||||
* Test login with external authentication mechanism, e.g. Apache
|
||||
|
@ -31,13 +31,11 @@ class AutoLoginBackend extends UserBackend
|
|||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.1.0)<br/>
|
||||
* Count elements of an object
|
||||
* @link http://php.net/manual/en/countable.count.php
|
||||
* @return int The custom count as an integer.
|
||||
* </p>
|
||||
* <p>
|
||||
* The return value is cast to an integer.
|
||||
* Count the available users
|
||||
*
|
||||
* Autologin backends will always return 1
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
|
@ -53,22 +51,18 @@ class AutoLoginBackend extends UserBackend
|
|||
*/
|
||||
public function hasUser(User $user)
|
||||
{
|
||||
if (isset($_SERVER['PHP_AUTH_USER'])
|
||||
&& isset($_SERVER['AUTH_TYPE'])
|
||||
&& in_array($_SERVER['AUTH_TYPE'], array('Basic', 'Digest')) === true
|
||||
) {
|
||||
$username = filter_var(
|
||||
$_SERVER['PHP_AUTH_USER'],
|
||||
FILTER_SANITIZE_STRING,
|
||||
FILTER_FLAG_ENCODE_HIGH|FILTER_FLAG_ENCODE_LOW
|
||||
);
|
||||
|
||||
if ($username !== false) {
|
||||
if ($this->stripUsernameRegexp !== null) {
|
||||
$username = preg_replace($this->stripUsernameRegexp, '', $username);
|
||||
if (isset($_SERVER['REMOTE_USER'])) {
|
||||
$username = $_SERVER['REMOTE_USER'];
|
||||
if ($this->stripUsernameRegexp !== null) {
|
||||
$stripped = preg_replace($this->stripUsernameRegexp, '', $username);
|
||||
if ($stripped !== false) {
|
||||
// TODO(el): PHP issues a warning when PHP cannot compile the regular expression. Should we log an
|
||||
// additional message in that case?
|
||||
$username = $stripped;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
$user->setUsername($username);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -77,12 +71,12 @@ class AutoLoginBackend extends UserBackend
|
|||
/**
|
||||
* Authenticate
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $password
|
||||
* @param User $user
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate(User $user, $password)
|
||||
public function authenticate(User $user, $password = null)
|
||||
{
|
||||
return $this->hasUser($user);
|
||||
}
|
||||
|
|
|
@ -75,12 +75,46 @@ class LdapUserBackend extends UserBackend
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Probe the backend to test if authentication is possible
|
||||
*
|
||||
* Try to bind to the backend and query all available users to check if:
|
||||
* <ul>
|
||||
* <li>User connection credentials are correct and the bind is possible</li>
|
||||
* <li>At least one user exists</li>
|
||||
* <li>The specified userClass has the property specified by userNameAttribute</li>
|
||||
* </ul>
|
||||
*
|
||||
* @throws AuthenticationException When authentication is not possible
|
||||
*/
|
||||
public function assertAuthenticationPossible()
|
||||
{
|
||||
$q = $this->conn->select()->from($this->userClass);
|
||||
$result = $q->fetchRow();
|
||||
if (!isset($result)) {
|
||||
throw new AuthenticationException(
|
||||
sprintf('No objects with objectClass="%s" in DN="%s" found.',
|
||||
$this->userClass,
|
||||
$this->conn->getDN()
|
||||
));
|
||||
}
|
||||
|
||||
if (!isset($result->{$this->userNameAttribute})) {
|
||||
throw new AuthenticationException(
|
||||
sprintf('UserNameAttribute "%s" not existing in objectClass="%s"',
|
||||
$this->userNameAttribute,
|
||||
$this->userClass
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given user exists
|
||||
*
|
||||
* @param User $user
|
||||
*
|
||||
* @return bool
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public function hasUser(User $user)
|
||||
{
|
||||
|
@ -93,18 +127,38 @@ class LdapUserBackend extends UserBackend
|
|||
*
|
||||
* @param User $user
|
||||
* @param string $password
|
||||
* @param boolean $healthCheck Perform additional health checks to generate more useful
|
||||
* exceptions in case of a configuration or backend error
|
||||
*
|
||||
* @return bool|null
|
||||
* @throws AuthenticationException
|
||||
* @return bool True when the authentication was successful, false when the username or password was invalid
|
||||
* @throws AuthenticationException When an error occurred during authentication and authentication is not possible
|
||||
*/
|
||||
public function authenticate(User $user, $password)
|
||||
public function authenticate(User $user, $password, $healthCheck = true)
|
||||
{
|
||||
if ($healthCheck) {
|
||||
try {
|
||||
$this->assertAuthenticationPossible();
|
||||
} catch (AuthenticationException $e) {
|
||||
// Authentication not possible
|
||||
throw new AuthenticationException(
|
||||
sprintf(
|
||||
'Authentication against backend "%s" not possible: ',
|
||||
$this->getName()
|
||||
),
|
||||
0,
|
||||
$e
|
||||
);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return $this->conn->testCredentials(
|
||||
$this->conn->fetchDN($this->createQuery($user->getUsername())),
|
||||
$password
|
||||
);
|
||||
$userDn = $this->conn->fetchDN($this->createQuery($user->getUsername()));
|
||||
if (!$userDn) {
|
||||
// User does not exist
|
||||
return false;
|
||||
}
|
||||
return $this->conn->testCredentials($userDn, $password);
|
||||
} catch (Exception $e) {
|
||||
// Error during authentication of this specific user
|
||||
throw new AuthenticationException(
|
||||
sprintf(
|
||||
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
||||
|
@ -124,6 +178,7 @@ class LdapUserBackend extends UserBackend
|
|||
*/
|
||||
public function count()
|
||||
{
|
||||
|
||||
return $this->conn->count(
|
||||
$this->conn->select()->from(
|
||||
$this->userClass,
|
||||
|
|
|
@ -85,7 +85,14 @@ abstract class UserBackend implements Countable
|
|||
}
|
||||
return new $backendConfig->class($backendConfig);
|
||||
}
|
||||
if ($name === 'autologin') {
|
||||
if (($backendType = $backendConfig->backend) === null) {
|
||||
throw new ConfigurationError(
|
||||
'Authentication configuration for backend "' . $name
|
||||
. '" is missing the backend directive'
|
||||
);
|
||||
}
|
||||
$backendType = strtolower($backendType);
|
||||
if ($backendType === 'autologin') {
|
||||
$backend = new AutoLoginBackend($backendConfig);
|
||||
$backend->setName($name);
|
||||
return $backend;
|
||||
|
@ -96,12 +103,6 @@ abstract class UserBackend implements Countable
|
|||
. '" is missing the resource directive'
|
||||
);
|
||||
}
|
||||
if (($backendType = $backendConfig->backend) === null) {
|
||||
throw new ConfigurationError(
|
||||
'Authentication configuration for backend "' . $name
|
||||
. '" is missing the backend directive'
|
||||
);
|
||||
}
|
||||
try {
|
||||
$resourceConfig = ResourceFactory::getResourceConfig($backendConfig->resource);
|
||||
} catch (ProgrammingError $e) {
|
||||
|
@ -110,7 +111,7 @@ abstract class UserBackend implements Countable
|
|||
);
|
||||
}
|
||||
$resource = ResourceFactory::createResource($resourceConfig);
|
||||
switch (strtolower($backendType)) {
|
||||
switch ($backendType) {
|
||||
case 'db':
|
||||
$backend = new DbUserBackend($resource);
|
||||
break;
|
||||
|
|
|
@ -1,21 +1,58 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Cli;
|
||||
|
||||
/**
|
||||
* Params
|
||||
*
|
||||
* A class to ease commandline-option and -argument handling.
|
||||
*/
|
||||
class Params
|
||||
{
|
||||
/**
|
||||
* The name and path of the executable
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $program;
|
||||
|
||||
/**
|
||||
* The arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $standalone = array();
|
||||
|
||||
/**
|
||||
* The options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $params = array();
|
||||
|
||||
/**
|
||||
* Parse the given commandline and create a new Params object
|
||||
*
|
||||
* @param array $argv The commandline
|
||||
*/
|
||||
public function __construct($argv)
|
||||
{
|
||||
$noOptionFlag = false;
|
||||
$this->program = array_shift($argv);
|
||||
for ($i = 0; $i < count($argv); $i++) {
|
||||
if (substr($argv[$i], 0, 2) === '--') {
|
||||
if ($argv[$i] === '--') {
|
||||
$noOptionFlag = true;
|
||||
} elseif (!$noOptionFlag && substr($argv[$i], 0, 2) === '--') {
|
||||
$key = substr($argv[$i], 2);
|
||||
if (! isset($argv[$i + 1]) || substr($argv[$i + 1], 0, 2) === '--') {
|
||||
$this->params[$key] = true;
|
||||
} elseif (array_key_exists($key, $this->params)) {
|
||||
if (!is_array($this->params[$key])) {
|
||||
$this->params[$key] = array($this->params[$key]);
|
||||
}
|
||||
$this->params[$key][] = $argv[++$i];
|
||||
} else {
|
||||
$this->params[$key] = $argv[++$i];
|
||||
}
|
||||
|
@ -25,6 +62,14 @@ class Params
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for an argument by position
|
||||
*
|
||||
* @param int $pos The position of the argument
|
||||
* @param mixed $default The default value to return
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getStandalone($pos = 0, $default = null)
|
||||
{
|
||||
if (isset($this->standalone[$pos])) {
|
||||
|
@ -33,26 +78,64 @@ class Params
|
|||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count and return the number of arguments and options
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->standalone) + count($this->params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllStandalone()
|
||||
{
|
||||
return $this->standalone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Params::get()
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given option exists
|
||||
*
|
||||
* @param string $key The option name to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return array_key_exists($key, $this->params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the given option
|
||||
*
|
||||
* @param string $key The option name
|
||||
* @param mixed $default The default value to return
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if ($this->has($key)) {
|
||||
|
@ -61,12 +144,27 @@ class Params
|
|||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value for the given option
|
||||
*
|
||||
* @param string $key The option name
|
||||
* @param mixed $value The value to set
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->params[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single option or multiple options
|
||||
*
|
||||
* @param string|array $keys The option or options to remove
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function remove($keys = array())
|
||||
{
|
||||
if (! is_array($keys)) {
|
||||
|
@ -80,12 +178,30 @@ class Params
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of this object with the given options being removed
|
||||
*
|
||||
* @param string|array $keys The option or options to remove
|
||||
*
|
||||
* @return Params
|
||||
*/
|
||||
public function without($keys = array())
|
||||
{
|
||||
$params = clone($this);
|
||||
return $params->remove($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and return the value of the given option
|
||||
*
|
||||
* Called multiple times for an option with multiple values returns
|
||||
* them one by one in case the default is not an array.
|
||||
*
|
||||
* @param string $key The option name
|
||||
* @param mixed $default The default value to return
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function shift($key = null, $default = null)
|
||||
{
|
||||
if ($key === null) {
|
||||
|
@ -95,16 +211,37 @@ class Params
|
|||
return $default;
|
||||
}
|
||||
$result = $this->get($key, $default);
|
||||
$this->remove($key);
|
||||
if (is_array($result) && !is_array($default)) {
|
||||
$result = array_shift($result) || $default;
|
||||
if ($result === $default) {
|
||||
$this->remove($key);
|
||||
}
|
||||
} else {
|
||||
$this->remove($key);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the given value onto the argument stack
|
||||
*
|
||||
* @param mixed $key The argument
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function unshift($key)
|
||||
{
|
||||
array_unshift($this->standalone, $key);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given commandline
|
||||
*
|
||||
* @param array $argv The commandline to parse
|
||||
*
|
||||
* @return Params
|
||||
*/
|
||||
public static function parse($argv = null)
|
||||
{
|
||||
if ($argv === null) {
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga Web 2.
|
||||
*
|
||||
* Icinga Web 2 - 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\Protocol;
|
||||
|
||||
/**
|
||||
* Discover dns records using regular or reverse lookup
|
||||
*/
|
||||
class Dns {
|
||||
|
||||
/**
|
||||
* Get all ldap records for the given domain
|
||||
*
|
||||
* @param String $query The domain to query
|
||||
*
|
||||
* @return array An array of entries
|
||||
*/
|
||||
public static function ldapRecords($query)
|
||||
{
|
||||
$ldaps_records = dns_get_record('_ldaps._tcp.' . $query);
|
||||
$ldap_records = dns_get_record('_ldap._tcp.' . $query);
|
||||
return array_merge($ldaps_records, $ldap_records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all ldap records for the given domain
|
||||
*
|
||||
* @param String $query The domain to query
|
||||
* @param int $type The type of DNS-entry to fetch, see http://www.php.net/manual/de/function.dns-get-record.php
|
||||
* for available types
|
||||
*
|
||||
* @return array|Boolean An array of entries
|
||||
*/
|
||||
public static function records($query, $type = DNS_ANY)
|
||||
{
|
||||
return dns_get_record($query, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse lookup all hostname on the given ip address
|
||||
*
|
||||
* @param $ipAddress
|
||||
* @param int $type
|
||||
*
|
||||
* @return array|Boolean
|
||||
*/
|
||||
public static function ptr($ipAddress, $type = DNS_ANY)
|
||||
{
|
||||
$host = gethostbyaddr($ipAddress);
|
||||
if ($host === false || $host === $ipAddress) {
|
||||
// malformed input or no host found
|
||||
return false;
|
||||
}
|
||||
return self::records($host, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IPv4 address of the given hostname.
|
||||
*
|
||||
* @param $hostname The hostname to resolve
|
||||
*
|
||||
* @return String|Boolean The IPv4 address of the given hostname, or false when no entry exists.
|
||||
*/
|
||||
public static function ipv4($hostname)
|
||||
{
|
||||
$records = dns_get_record($hostname, DNS_A);
|
||||
if ($records !== false && sizeof($records) > 0) {
|
||||
return $records[0]['ip'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IPv6 address of the given hostname.
|
||||
*
|
||||
* @param $hostname The hostname to resolve
|
||||
*
|
||||
* @return String|Boolean The IPv6 address of the given hostname, or false when no entry exists.
|
||||
*/
|
||||
public static function ipv6($hostname)
|
||||
{
|
||||
$records = dns_get_record($hostname, DNS_AAAA);
|
||||
if ($records !== false && sizeof($records) > 0) {
|
||||
return $records[0]['ip'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -63,6 +63,7 @@ class Connection
|
|||
protected $bind_pw;
|
||||
protected $root_dn;
|
||||
protected $count;
|
||||
|
||||
protected $ldap_extension = array(
|
||||
'1.3.6.1.4.1.1466.20037' => 'STARTTLS',
|
||||
// '1.3.6.1.4.1.4203.1.11.1' => '11.1', // PASSWORD_MODIFY
|
||||
|
@ -109,6 +110,8 @@ class Connection
|
|||
protected $supports_v3 = false;
|
||||
protected $supports_tls = false;
|
||||
|
||||
protected $capabilities;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -204,16 +207,19 @@ class Connection
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the distinguished name of the first result of the given query
|
||||
*
|
||||
* @param $query
|
||||
* @param array $fields
|
||||
*
|
||||
* @return bool|String Returns the distinguished name, or false when the given query yields no results
|
||||
*/
|
||||
public function fetchDN($query, $fields = array())
|
||||
{
|
||||
$rows = $this->fetchAll($query, $fields);
|
||||
if (count($rows) !== 1) {
|
||||
throw new \Exception(
|
||||
sprintf(
|
||||
'Cannot fetch single DN for %s',
|
||||
$query
|
||||
)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return key($rows);
|
||||
}
|
||||
|
@ -353,12 +359,6 @@ class Connection
|
|||
return $dir;
|
||||
}
|
||||
|
||||
protected function discoverServerlistForDomain($domain)
|
||||
{
|
||||
$ldaps_records = dns_get_record('_ldaps._tcp.' . $domain, DNS_SRV);
|
||||
$ldap_records = dns_get_record('_ldap._tcp.' . $domain, DNS_SRV);
|
||||
}
|
||||
|
||||
protected function prepareNewConnection()
|
||||
{
|
||||
$use_tls = false;
|
||||
|
@ -371,6 +371,7 @@ class Connection
|
|||
|
||||
$ds = ldap_connect($this->hostname, $this->port);
|
||||
$cap = $this->discoverCapabilities($ds);
|
||||
$this->capabilities = $cap;
|
||||
|
||||
if ($use_tls) {
|
||||
if ($cap->starttls) {
|
||||
|
@ -405,7 +406,6 @@ class Connection
|
|||
|
||||
// TODO: remove this -> FORCING v3 for now
|
||||
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
|
||||
Logger::warning('No LDAPv3 support detected');
|
||||
}
|
||||
|
||||
|
@ -435,6 +435,116 @@ class Connection
|
|||
}
|
||||
}
|
||||
|
||||
protected function hasCapabilityStarTSL($cap)
|
||||
{
|
||||
$cap = $this->getExtensionCapabilities($cap);
|
||||
return isset($cap['1.3.6.1.4.1.1466.20037']);
|
||||
}
|
||||
|
||||
protected function hasCapabilityLdapV3($cap)
|
||||
{
|
||||
if ((is_string($cap->supportedLDAPVersion)
|
||||
&& (int) $cap->supportedLDAPVersion === 3)
|
||||
|| (is_array($cap->supportedLDAPVersion)
|
||||
&& in_array(3, $cap->supportedLDAPVersion)
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getExtensionCapabilities($cap)
|
||||
{
|
||||
$extensions = array();
|
||||
if (isset($cap->supportedExtension)) {
|
||||
foreach ($cap->supportedExtension as $oid) {
|
||||
if (array_key_exists($oid, $this->ldap_extension)) {
|
||||
if ($this->ldap_extension[$oid] === 'STARTTLS') {
|
||||
$extensions['1.3.6.1.4.1.1466.20037'] = $this->ldap_extension['1.3.6.1.4.1.1466.20037'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
protected function getMsCapabilities($cap)
|
||||
{
|
||||
$ms = array();
|
||||
foreach ($this->ms_capability as $name) {
|
||||
$ms[$this->convName($name)] = false;
|
||||
}
|
||||
|
||||
if (isset($cap->supportedCapabilities)) {
|
||||
foreach ($cap->supportedCapabilities as $oid) {
|
||||
if (array_key_exists($oid, $this->ms_capability)) {
|
||||
$ms[$this->convName($this->ms_capability[$oid])] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (object)$ms;
|
||||
}
|
||||
|
||||
private function convName($name)
|
||||
{
|
||||
$parts = explode('_', $name);
|
||||
foreach ($parts as $i => $part) {
|
||||
$parts[$i] = ucfirst(strtolower($part));
|
||||
}
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the capabilities of this ldap server
|
||||
*
|
||||
* @return stdClass An object, providing the flags 'ldapv3' and 'starttls' to indicate LdapV3 and StartTLS
|
||||
* support and an additional property 'msCapabilities', containing all supported active directory capabilities.
|
||||
*/
|
||||
public function getCapabilities()
|
||||
{
|
||||
return $this->capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default naming context of this ldap connection
|
||||
*
|
||||
* @return String|null the default naming context, or null when no contexts are available
|
||||
*/
|
||||
public function getDefaultNamingContext()
|
||||
{
|
||||
$cap = $this->capabilities;
|
||||
if (isset($cap->defaultNamingContext)) {
|
||||
return $cap->defaultNamingContext;
|
||||
}
|
||||
$namingContexts = $this->namingContexts($cap);
|
||||
return empty($namingContexts) ? null : $namingContexts[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the namingContexts for this Ldap-Connection
|
||||
*
|
||||
* @return array the available naming contexts
|
||||
*/
|
||||
public function namingContexts()
|
||||
{
|
||||
$cap = $this->capabilities;
|
||||
if (!isset($cap->namingContexts)) {
|
||||
return array();
|
||||
}
|
||||
if (!is_array($cap->namingContexts)) {
|
||||
return array($cap->namingContexts);
|
||||
}
|
||||
return $cap->namingContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover the capabilities of the given ldap-server
|
||||
*
|
||||
* @param $ds The link identifier of the current ldap connection
|
||||
*
|
||||
* @return bool|object The capabilities or false if the server has none
|
||||
* @throws Exception When the capability query fails
|
||||
*/
|
||||
protected function discoverCapabilities($ds)
|
||||
{
|
||||
$query = $this->select()->from(
|
||||
|
@ -477,69 +587,49 @@ class Connection
|
|||
$cap = (object) array(
|
||||
'ldapv3' => false,
|
||||
'starttls' => false,
|
||||
'msCapabilities' => array()
|
||||
);
|
||||
|
||||
if ($entry === false) {
|
||||
// TODO: Is it OK to have no capabilities?
|
||||
return $cap;
|
||||
return false;
|
||||
}
|
||||
$ldapAttributes = ldap_get_attributes($ds, $entry);
|
||||
$result = $this->cleanupAttributes(
|
||||
$ldapAttributes
|
||||
);
|
||||
$result = $this->cleanupAttributes($ldapAttributes);
|
||||
$cap->ldapv3 = $this->hasCapabilityLdapV3($result);
|
||||
$cap->starttls = $this->hasCapabilityStarTSL($result);
|
||||
$cap->msCapabilities = $this->getMsCapabilities($result);
|
||||
$cap->namingContexts = $result->namingContexts;
|
||||
/*
|
||||
if (isset($result->dnsHostName)) {
|
||||
ldap_set_option($ds, LDAP_OPT_HOST_NAME, $result->dnsHostName);
|
||||
}
|
||||
*/
|
||||
|
||||
if ((is_string($result->supportedLDAPVersion)
|
||||
&& (int) $result->supportedLDAPVersion === 3)
|
||||
|| (is_array($result->supportedLDAPVersion)
|
||||
&& in_array(3, $result->supportedLDAPVersion)
|
||||
)) {
|
||||
$cap->ldapv3 = true;
|
||||
}
|
||||
|
||||
if (isset($result->supportedCapabilities)) {
|
||||
foreach ($result->supportedCapabilities as $oid) {
|
||||
if (array_key_exists($oid, $this->ms_capability)) {
|
||||
// echo $this->ms_capability[$oid] . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($result->supportedExtension)) {
|
||||
foreach ($result->supportedExtension as $oid) {
|
||||
if (array_key_exists($oid, $this->ldap_extension)) {
|
||||
if ($this->ldap_extension[$oid] === 'STARTTLS') {
|
||||
$cap->starttls = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cap;
|
||||
}
|
||||
|
||||
public function connect()
|
||||
public function connect($anonymous = false)
|
||||
{
|
||||
if ($this->ds !== null) {
|
||||
return;
|
||||
}
|
||||
$this->ds = $this->prepareNewConnection();
|
||||
|
||||
$r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw);
|
||||
|
||||
if (! $r) {
|
||||
throw new \Exception(
|
||||
sprintf(
|
||||
'LDAP connection to %s:%s (%s / %s) failed: %s',
|
||||
$this->hostname,
|
||||
$this->port,
|
||||
$this->bind_dn,
|
||||
'***' /* $this->bind_pw */,
|
||||
ldap_error($this->ds)
|
||||
)
|
||||
);
|
||||
if (!$anonymous) {
|
||||
$r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw);
|
||||
if (! $r) {
|
||||
throw new \Exception(
|
||||
sprintf(
|
||||
'LDAP connection to %s:%s (%s / %s) failed: %s',
|
||||
$this->hostname,
|
||||
$this->port,
|
||||
$this->bind_dn,
|
||||
'***' /* $this->bind_pw */,
|
||||
ldap_error($this->ds)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,15 +62,9 @@ class Translator
|
|||
* @param string $domain The primary domain to use
|
||||
*
|
||||
* @return string The translated string
|
||||
*
|
||||
* @throws Exception In case the given domain is unknown
|
||||
*/
|
||||
public static function translate($text, $domain)
|
||||
{
|
||||
if ($domain !== self::DEFAULT_DOMAIN && !array_key_exists($domain, self::$knownDomains)) {
|
||||
throw new Exception("Cannot translate string '$text' with unknown domain '$domain'");
|
||||
}
|
||||
|
||||
$res = dgettext($domain, $text);
|
||||
if ($res === $text && $domain !== self::DEFAULT_DOMAIN) {
|
||||
return dgettext(self::DEFAULT_DOMAIN, $text);
|
||||
|
|
|
@ -301,7 +301,7 @@ class ActionController extends Zend_Controller_Action
|
|||
public function translate($text)
|
||||
{
|
||||
$module = $this->getRequest()->getModuleName();
|
||||
$domain = $module === 'default' ? 'icinga' : $module;
|
||||
$domain = $module === 'default' ? Translator::DEFAULT_DOMAIN : $module;
|
||||
return Translator::translate($text, $domain);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,15 @@ class JavaScript
|
|||
);
|
||||
|
||||
protected static $vendorFiles = array(
|
||||
// 'js/vendor/jquery-1.11.0',
|
||||
'js/vendor/jquery-2.1.0',
|
||||
'js/vendor/jquery.sparkline'
|
||||
);
|
||||
|
||||
protected static $ie8VendorFiles = array(
|
||||
'js/vendor/jquery-1.11.0',
|
||||
'js/vendor/jquery.sparkline'
|
||||
);
|
||||
|
||||
public static function listModuleFiles()
|
||||
{
|
||||
$list = array();
|
||||
|
@ -43,6 +47,12 @@ class JavaScript
|
|||
return self::send(true);
|
||||
}
|
||||
|
||||
public static function sendForIe8()
|
||||
{
|
||||
self::$vendorFiles = self::$ie8VendorFiles;
|
||||
return self::send();
|
||||
}
|
||||
|
||||
public static function send($minified = false)
|
||||
{
|
||||
header('Content-Type: application/javascript');
|
||||
|
|
|
@ -50,10 +50,14 @@ class InlinePie extends AbstractWidget
|
|||
* @var string
|
||||
*/
|
||||
private $template =<<<'EOD'
|
||||
<span class="sparkline" sparkTitle="{title}" sparkWidth="{width}" sparkHeight="{height}" style="{style}"
|
||||
sparkSliceColors="[{colors}]" values="{data}" sparkType="pie"></span>
|
||||
<noscript>
|
||||
<img class="inlinepie"
|
||||
title="{title}" src="{url}" style="width: {width}px; height: {height}px; {style}"
|
||||
data-icinga-colors="{colors}" data-icinga-values="{data}"
|
||||
/>
|
||||
</noscript>
|
||||
EOD;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Test\Clicommands;
|
||||
|
||||
use Icinga\Cli\Command;
|
||||
|
||||
/**
|
||||
* PHP unit- & style-tests
|
||||
*/
|
||||
class PhpCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Default arguments and options for PHP_CodeSniffer
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $phpcsDefaultParams = array(
|
||||
'-p',
|
||||
'--standard=PSR2',
|
||||
'--extensions=php',
|
||||
'--encoding=utf-8'
|
||||
);
|
||||
|
||||
/**
|
||||
* Run all unit-test suites
|
||||
*
|
||||
* This command runs the unit- and regression-tests of icingaweb and installed modules.
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
* icingacli test php unit [options]
|
||||
*
|
||||
* OPTIONS
|
||||
*
|
||||
* --verbose Be more verbose.
|
||||
* --build Enable reporting.
|
||||
* --include Pattern to use for including files/test cases.
|
||||
*
|
||||
* EXAMPLES
|
||||
*
|
||||
* icingacli test php unit --verbose
|
||||
* icingacli test php unit --build
|
||||
* icingacli test php unit --include *SpecialTest
|
||||
*/
|
||||
public function unitAction()
|
||||
{
|
||||
$build = $this->params->shift('build');
|
||||
$include = $this->params->shift('include');
|
||||
|
||||
$phpUnit = exec('which phpunit');
|
||||
if (!file_exists($phpUnit)) {
|
||||
$this->fail('PHPUnit not found. Please install PHPUnit to be able to run the unit-test suites.');
|
||||
}
|
||||
|
||||
$options = array();
|
||||
if ($this->isVerbose) {
|
||||
$options[] = '--verbose';
|
||||
}
|
||||
if ($build) {
|
||||
$reportPath = $this->setupAndReturnReportDirectory();
|
||||
echo $reportPath;
|
||||
$options[] = '--log-junit';
|
||||
$options[] = $reportPath . '/phpunit_results.xml';
|
||||
$options[] = '--coverage-html';
|
||||
$options[] = $reportPath . '/php_html_coverage';
|
||||
}
|
||||
if ($include !== null) {
|
||||
$options[] = '--filter';
|
||||
$options[] = $include;
|
||||
}
|
||||
|
||||
chdir(realpath(__DIR__ . '/../..'));
|
||||
passthru($phpUnit . ' ' . join(' ', array_merge($options, $this->params->getAllStandalone())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run code-style checks
|
||||
*
|
||||
* This command checks whether icingaweb and installed modules match the PSR-2 coding standard.
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
* icingacli test php style [options]
|
||||
*
|
||||
* OPTIONS
|
||||
*
|
||||
* --verbose Be more verbose.
|
||||
* --build Enable reporting.
|
||||
* --include Include only specific files. (Can be supplied multiple times.)
|
||||
* --exclude Pattern to use for excluding files. (Can be supplied multiple times.)
|
||||
*
|
||||
* EXAMPLES
|
||||
*
|
||||
* icingacli test php style --verbose
|
||||
* icingacli test php style --build
|
||||
* icingacli test php style --include path/to/your/file
|
||||
* icingacli test php style --exclude *someFile* --exclude someOtherFile*
|
||||
*/
|
||||
public function styleAction()
|
||||
{
|
||||
$build = $this->params->shift('build');
|
||||
$include = (array) $this->params->shift('include', array());
|
||||
$exclude = (array) $this->params->shift('exclude', array());
|
||||
|
||||
$phpcs = exec('which phpcs');
|
||||
if (!file_exists($phpcs)) {
|
||||
$this->fail(
|
||||
'PHP_CodeSniffer not found. Please install PHP_CodeSniffer to be able to run code style tests.'
|
||||
);
|
||||
}
|
||||
|
||||
$options = array();
|
||||
if ($this->isVerbose) {
|
||||
$options[] = '-v';
|
||||
}
|
||||
if ($build) {
|
||||
$options[] = '--report-checkstyle=' . $this->setupAndReturnReportDirectory();
|
||||
}
|
||||
if (!empty($exclude)) {
|
||||
$options[] = '--ignore=' . join(',', $exclude);
|
||||
}
|
||||
$arguments = array_filter(array_map(function ($p) { return realpath($p); }, $include));
|
||||
if (empty($arguments)) {
|
||||
$arguments = array(
|
||||
realpath(__DIR__ . '/../../../../application'),
|
||||
realpath(__DIR__ . '/../../../../library/Icinga')
|
||||
);
|
||||
}
|
||||
|
||||
chdir(realpath(__DIR__ . '/../..'));
|
||||
passthru(
|
||||
$phpcs . ' ' . join(
|
||||
' ',
|
||||
array_merge(
|
||||
$options,
|
||||
$this->phpcsDefaultParams,
|
||||
$arguments,
|
||||
$this->params->getAllStandalone()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the directory where to put report files and return its path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function setupAndReturnReportDirectory()
|
||||
{
|
||||
$path = realpath(__DIR__ . '/../../../..') . '/build/log';
|
||||
if (!file_exists($path) && !@mkdir($path, 0755, true)) {
|
||||
$this->fail("Could not create directory: $path");
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
}
|
|
@ -1,25 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit bootstrap="bootstrap.php">
|
||||
<phpunit bootstrap="../../test/php/bootstrap.php">
|
||||
<testsuites>
|
||||
<!--
|
||||
Unit testing
|
||||
-->
|
||||
<testsuite name="unit">
|
||||
<directory>application/</directory>
|
||||
<directory>bin/</directory>
|
||||
<directory>library/</directory>
|
||||
<directory>../../test/php/application/</directory>
|
||||
<directory>../../test/php/library/</directory>
|
||||
|
||||
<!-- Module tests are independent from core tests -->
|
||||
<directory>../../modules/*/test/php</directory>
|
||||
<exclude>../../modules/*/test/php/regression</exclude>
|
||||
<directory>../*/test/php</directory>
|
||||
<exclude>../*/test/php/regression</exclude>
|
||||
</testsuite>
|
||||
|
||||
<!--
|
||||
Regression testing
|
||||
-->
|
||||
<testsuite name="regression">
|
||||
<directory>regression/</directory>
|
||||
<directory>../../modules/*/test/regression</directory>
|
||||
<directory>../../test/php/regression/</directory>
|
||||
<directory>../*/test/php/regression</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
|
@ -127,15 +127,12 @@ tr.state.handled td.state, tr.state.ok td.state, tr.state.up td.state, tr.state.
|
|||
color: black;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tr[href].active {
|
||||
background-color: #ddd;
|
||||
color: black;
|
||||
}
|
||||
|
||||
tr.state[href]:hover, tr.state[href].active td.state {
|
||||
|
||||
}
|
||||
|
||||
tr.state.ok td.state, tr.state.up td.state {
|
||||
border-left-color: @colorOk;
|
||||
}
|
||||
|
@ -195,12 +192,12 @@ tr.state.handled td.state {
|
|||
|
||||
/* HOVER colors */
|
||||
|
||||
|
||||
tr.state[href]:hover, tr.state[href]:hover td.state {
|
||||
tr[href]:hover, tr.state[href]:hover td.state {
|
||||
color: white;
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
tr.state.ok:hover {
|
||||
tr.state.ok[href]:hover, tr.state.up[href]:hover {
|
||||
background-color: @colorOk;
|
||||
}
|
||||
|
||||
|
@ -248,6 +245,11 @@ tr.state.unreachable[href]:hover {
|
|||
tr.state.unreachable.handled[href]:hover {
|
||||
background-color: @colorUnreachableHandled;
|
||||
}
|
||||
|
||||
tr.state[href]:hover td.state {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
|
||||
/* END of HOVER colors */
|
||||
|
||||
/* END of special tables and states */
|
||||
|
|
|
@ -2,6 +2,12 @@ ul.pagination {
|
|||
font-size: 0.68em;
|
||||
padding: 0;
|
||||
display: inline;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#layout.twocols u.pagination {
|
||||
|
|
|
@ -69,10 +69,6 @@
|
|||
|
||||
$('input.autofocus', el).focus();
|
||||
|
||||
$('img.inlinepie', el).each(function() {
|
||||
icinga.ui.initializeSparklines($(this));
|
||||
});
|
||||
|
||||
// replace all sparklines
|
||||
$('span.sparkline', el).sparkline('html', { enableTagOptions: true });
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@
|
|||
if (this.processRedirectHeader(req)) return;
|
||||
|
||||
// div helps getting an XML tree
|
||||
var $resp = $('<div>' + icinga.ui.removeImageSourceFromSparklines(req.responseText) + '</div>');
|
||||
var $resp = $('<div>' + req.responseText + '</div>');
|
||||
var active = false;
|
||||
var rendered = false;
|
||||
var classes;
|
||||
|
@ -409,11 +409,6 @@
|
|||
|
||||
this.icinga.ui.initializeTriStates($resp);
|
||||
|
||||
// Replace images with sparklines.
|
||||
$resp.find('img.inlinepie').each(function(){
|
||||
self.icinga.ui.initializeSparklines($(this));
|
||||
});
|
||||
|
||||
/* Should we try to fiddle with responses containing full HTML? */
|
||||
/*
|
||||
if ($('body', $resp).length) {
|
||||
|
@ -617,7 +612,7 @@
|
|||
$container.scrollTop(scrollPos);
|
||||
}
|
||||
if (origFocus) {
|
||||
origFocus.focus();
|
||||
$(origFocus).focus();
|
||||
}
|
||||
|
||||
// TODO: this.icinga.events.refreshContainer(container);
|
||||
|
|
|
@ -631,48 +631,6 @@
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Search and replace all inlinepies with html for sparklines.
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
initializeSparklines: function($container) {
|
||||
|
||||
// replace all remaining images with sparklines
|
||||
var title = $container.attr('title'),
|
||||
values = $container.data('icinga-values'),
|
||||
colors = $container.data('icinga-colors'),
|
||||
width = $container.css('width'),
|
||||
height = $container.css('height');
|
||||
if (!values) {
|
||||
return;
|
||||
}
|
||||
$container.replaceWith(
|
||||
'<span sparkTitle="' + title +
|
||||
'" sparkWidth="' + width +
|
||||
'" sparkHeight="' + height +
|
||||
'" sparkType="pie" sparkSliceColors="[' +
|
||||
colors + ']" values="' +
|
||||
values + '" class="sparkline"></span>'
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Find all svg charts and removes src attributes for sparklines
|
||||
*
|
||||
* @param {string} text
|
||||
* @returns {string}
|
||||
*/
|
||||
removeImageSourceFromSparklines: function(text) {
|
||||
var match, sourceMatch;
|
||||
var re = new RegExp(/(src=".+chart.php[^"]+")/g);
|
||||
var reSource = new RegExp(/src="([^"]+)"/);
|
||||
while ((match = re.exec(text))) {
|
||||
text = text.replace(match[0], '');
|
||||
}
|
||||
return text;
|
||||
},
|
||||
|
||||
initializeControls: function (parent) {
|
||||
|
||||
var self = this;
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from pipes import quote
|
||||
from optparse import OptionParser, BadOptionError, AmbiguousOptionError
|
||||
|
||||
|
||||
APPLICATION = 'phpcs'
|
||||
DEFAULT_ARGS = ['-p', '--standard=PSR2', '--extensions=php',
|
||||
'--encoding=utf-8']
|
||||
|
||||
VAGRANT_SCRIPT = '/vagrant/test/php/checkswag'
|
||||
REPORT_DIRECTORY = '../../build/log'
|
||||
|
||||
|
||||
class PassThroughOptionParser(OptionParser):
|
||||
"""
|
||||
An unknown option pass-through implementation of OptionParser.
|
||||
|
||||
When unknown arguments are encountered, bundle with largs and try again,
|
||||
until rargs is depleted.
|
||||
|
||||
sys.exit(status) will still be called if a known argument is passed
|
||||
incorrectly (e.g. missing arguments or bad argument types, etc.)
|
||||
|
||||
Borrowed from: http://stackoverflow.com/a/9307174
|
||||
"""
|
||||
def _process_args(self, largs, rargs, values):
|
||||
while rargs:
|
||||
try:
|
||||
OptionParser._process_args(self, largs, rargs, values)
|
||||
except (BadOptionError, AmbiguousOptionError), error:
|
||||
largs.append(error.opt_str)
|
||||
|
||||
|
||||
def execute_command(command, return_output=False, shell=False):
|
||||
prog = subprocess.Popen(command, shell=shell,
|
||||
stdout=subprocess.PIPE
|
||||
if return_output
|
||||
else None)
|
||||
return prog.wait() if not return_output else \
|
||||
prog.communicate()[0]
|
||||
|
||||
|
||||
def get_report_directory():
|
||||
path = os.path.abspath(REPORT_DIRECTORY)
|
||||
|
||||
try:
|
||||
os.makedirs(REPORT_DIRECTORY)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def get_script_directory():
|
||||
return os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
|
||||
def parse_commandline():
|
||||
parser = PassThroughOptionParser(usage='%prog [options] [additional arguments'
|
||||
' for {0}]'.format(APPLICATION))
|
||||
parser.add_option('-b', '--build', action='store_true',
|
||||
help='Enable reporting.')
|
||||
parser.add_option('-v', '--verbose', action='store_true',
|
||||
help='Be more verbose.')
|
||||
parser.add_option('-i', '--include', metavar='PATTERN', action='append',
|
||||
help='Include only specific files/test cases.'
|
||||
' (Can be supplied multiple times.)')
|
||||
parser.add_option('-e', '--exclude', metavar='PATTERN', action='append',
|
||||
help='Exclude specific files/test cases. '
|
||||
'(Can be supplied multiple times.)')
|
||||
parser.add_option('-V', '--vagrant', action='store_true',
|
||||
help='Run in vagrant VM')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
options, arguments = parse_commandline()
|
||||
|
||||
if options.vagrant and os.environ['USER'] != 'vagrant':
|
||||
# Check if vagrant is installed
|
||||
vagrant_path = execute_command('which vagrant', True, True).strip()
|
||||
if not vagrant_path:
|
||||
print 'ERROR: vagrant not found!'
|
||||
return 2
|
||||
|
||||
# Call the script in the Vagrant VM with the same parameters
|
||||
commandline = ' '.join(quote(p) for p in sys.argv[1:])
|
||||
return execute_command('vagrant ssh -c "{0} {1}"'
|
||||
''.format(VAGRANT_SCRIPT, commandline),
|
||||
shell=True)
|
||||
else:
|
||||
# Environment preparation and verification
|
||||
os.chdir(get_script_directory())
|
||||
application_path = execute_command('which {0}'.format(APPLICATION),
|
||||
True, True).strip()
|
||||
if not application_path:
|
||||
print 'ERROR: {0} not found!'.format(APPLICATION)
|
||||
return 2
|
||||
|
||||
# Commandline preparation
|
||||
command_options = []
|
||||
if options.verbose:
|
||||
command_options.append('-v')
|
||||
if options.build:
|
||||
result_path = os.path.join(get_report_directory(),
|
||||
'phpcs_results.xml')
|
||||
command_options.append('--report-checkstyle=' + result_path)
|
||||
if options.exclude:
|
||||
command_options.append('--ignore=' + ','.join(options.exclude))
|
||||
if options.include:
|
||||
arguments.extend(options.include)
|
||||
else:
|
||||
arguments.extend(['../../application', '../../bin',
|
||||
'../../library/Icinga'])
|
||||
|
||||
# Application invocation..
|
||||
execute_command([application_path] + DEFAULT_ARGS +
|
||||
command_options + arguments)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Tests\Icinga\Regression;
|
||||
|
||||
use Icinga\Test\BaseTestCase;
|
||||
use Icinga\Util\Translator;
|
||||
|
||||
/**
|
||||
* Regression-Test for bug #6432
|
||||
*
|
||||
* Translating strings must not throw an exception even if the given domain is not valid.
|
||||
*
|
||||
* @see https://dev.icinga.org/issues/6432
|
||||
*/
|
||||
class Bug6432Test extends BaseTestCase
|
||||
{
|
||||
public function testWhetherTranslateReturnsTheInputStringInCaseTheGivenDomainIsNotValid()
|
||||
{
|
||||
$this->assertEquals('test', Translator::translate('test', 'invalid_domain'));
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from pipes import quote
|
||||
from fnmatch import fnmatch
|
||||
from optparse import OptionParser, BadOptionError, AmbiguousOptionError
|
||||
|
||||
|
||||
APPLICATION = 'phpunit'
|
||||
DEFAULT_ARGS = []
|
||||
|
||||
VAGRANT_SCRIPT = '/vagrant/test/php/runtests'
|
||||
REPORT_DIRECTORY = '../../build/log'
|
||||
|
||||
|
||||
class PassThroughOptionParser(OptionParser):
|
||||
"""
|
||||
An unknown option pass-through implementation of OptionParser.
|
||||
|
||||
When unknown arguments are encountered, bundle with largs and try again,
|
||||
until rargs is depleted.
|
||||
|
||||
sys.exit(status) will still be called if a known argument is passed
|
||||
incorrectly (e.g. missing arguments or bad argument types, etc.)
|
||||
|
||||
Borrowed from: http://stackoverflow.com/a/9307174
|
||||
"""
|
||||
def _process_args(self, largs, rargs, values):
|
||||
while rargs:
|
||||
try:
|
||||
OptionParser._process_args(self, largs, rargs, values)
|
||||
except (BadOptionError, AmbiguousOptionError), error:
|
||||
largs.append(error.opt_str)
|
||||
|
||||
|
||||
def execute_command(command, return_output=False, shell=False):
|
||||
prog = subprocess.Popen(command, shell=shell,
|
||||
stdout=subprocess.PIPE
|
||||
if return_output
|
||||
else None)
|
||||
return prog.wait() if not return_output else \
|
||||
prog.communicate()[0]
|
||||
|
||||
|
||||
def get_report_directory():
|
||||
path = os.path.abspath(REPORT_DIRECTORY)
|
||||
|
||||
try:
|
||||
os.makedirs(REPORT_DIRECTORY)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def get_script_directory():
|
||||
return os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
|
||||
def parse_commandline():
|
||||
parser = PassThroughOptionParser(usage='%prog [options] [additional arguments'
|
||||
' for {0}]'.format(APPLICATION))
|
||||
parser.add_option('-b', '--build', action='store_true',
|
||||
help='Enable reporting.')
|
||||
parser.add_option('-v', '--verbose', action='store_true',
|
||||
help='Be more verbose.')
|
||||
parser.add_option('-i', '--include', metavar='PATTERN',
|
||||
help='Include only specific files/test cases.')
|
||||
parser.add_option('-V', '--vagrant', action='store_true',
|
||||
help='Run in vagrant VM')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
options, arguments = parse_commandline()
|
||||
|
||||
if options.vagrant and os.environ['USER'] != 'vagrant':
|
||||
# Check if vagrant is installed
|
||||
vagrant_path = execute_command('which vagrant', True, True).strip()
|
||||
if not vagrant_path:
|
||||
print 'ERROR: vagrant not found!'
|
||||
return 2
|
||||
|
||||
# Call the script in the Vagrant VM with the same parameters
|
||||
commandline = ' '.join(quote(p) for p in sys.argv[1:])
|
||||
return execute_command('vagrant ssh -c "{0} {1}"'
|
||||
''.format(VAGRANT_SCRIPT, commandline),
|
||||
shell=True)
|
||||
else:
|
||||
# Environment preparation and verification
|
||||
os.chdir(get_script_directory())
|
||||
application_path = execute_command('which {0}'.format(APPLICATION),
|
||||
True, True).strip()
|
||||
if not application_path:
|
||||
print 'ERROR: {0} not found!'.format(APPLICATION)
|
||||
return 2
|
||||
if not os.path.isfile('./bin/extcmd_test'):
|
||||
execute_command('make', shell=True)
|
||||
|
||||
# Commandline preparation
|
||||
command_options = []
|
||||
if options.verbose:
|
||||
command_options.append('--verbose')
|
||||
if options.build:
|
||||
report_directory = get_report_directory()
|
||||
command_options.append('--log-junit')
|
||||
command_options.append(os.path.join(report_directory,
|
||||
'phpunit_results.xml'))
|
||||
command_options.append('--coverage-html')
|
||||
command_options.append(os.path.join(report_directory,
|
||||
'php_html_coverage'))
|
||||
if options.include:
|
||||
command_options.append('--filter')
|
||||
command_options.append(options.include)
|
||||
|
||||
# Application invocation..
|
||||
execute_command([application_path] + DEFAULT_ARGS +
|
||||
command_options + arguments)
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
Loading…
Reference in New Issue