Merge remote-tracking branch 'origin/master' into feature/livestatus-playground-4787

This commit is contained in:
Thomas Gelf 2014-11-16 10:12:34 +01:00
commit e89d4642e3
2680 changed files with 414920 additions and 122251 deletions

4
.gitattributes vendored
View File

@ -1 +1,5 @@
# Exclude files related to git when generating an archive
.git* export-ignore
# Normalize puppet manifests' line endings to LF on checkin and prevent conversion to CRLF when the files are checked out
.vagrant-puppet/* eol=lf

46
.gitignore vendored
View File

@ -1,46 +1,12 @@
# Exclude all hidden files
.*
# But not .gitignore, .gitattributes, .vagrant-puppet, .htaccess and .gitkeep
!.gitignore
!.gitattributes
!.vagrant-puppet
!public/.htaccess
!packages/rhel/usr/share/icingaweb/public/.htaccess
!public/.htaccess.in
!.gitkeep
build/
# Except those related to git and vagrant
!.git*
!.vagrant-puppet/*
development/
# Exclude application log files
var/log/*
# ./configure output
config.log
autom4te.cache
autoscan*
config.status
Makefile
# cmd tester
modules/test/bin/extcmd_test
# misc test output
test/php/library/Icinga/Protocol/Statusdat/.cache
# Generated API documentation
doc/api
# Enabled modules
config/enabledModules/
# User preferences
config/preferences/*.ini
# Application logfiles
var/log/*.log
# Packaging
# Exclude symlink you need for packaging
/debian
*.tar.gz
*.komodoproject

View File

@ -1 +0,0 @@
* -crlf

View File

@ -601,27 +601,15 @@ exec { 'create-pgsql-icingaweb-db':
require => Service['postgresql']
}
exec { 'populate-icingaweb-mysql-db-accounts':
exec { 'populate-icingaweb-mysql-db-tables':
unless => 'mysql -uicingaweb -picingaweb icingaweb -e "SELECT * FROM account;" &> /dev/null',
command => 'mysql -uicingaweb -picingaweb icingaweb < /vagrant/etc/schema/accounts.mysql.sql',
command => 'mysql -uicingaweb -picingaweb icingaweb < /vagrant/etc/schema/mysql.sql',
require => [ Exec['create-mysql-icingaweb-db'] ]
}
exec { 'populate-icingweba-pgsql-db-accounts':
exec { 'populate-icingweba-pgsql-db-tables':
unless => 'psql -U icingaweb -d icingaweb -c "SELECT * FROM account;" &> /dev/null',
command => 'sudo -u postgres psql -U icingaweb -d icingaweb -f /vagrant/etc/schema/accounts.pgsql.sql',
require => [ Exec['create-pgsql-icingaweb-db'] ]
}
exec { 'populate-icingaweb-mysql-db-preferences':
unless => 'mysql -uicingaweb -picingaweb icingaweb -e "SELECT * FROM preference;" &> /dev/null',
command => 'mysql -uicingaweb -picingaweb icingaweb < /vagrant/etc/schema/preferences.mysql.sql',
require => [ Exec['create-mysql-icingaweb-db'] ]
}
exec { 'populate-icingweba-pgsql-db-preferences':
unless => 'psql -U icingaweb -d icingaweb -c "SELECT * FROM preference;" &> /dev/null',
command => 'sudo -u postgres psql -U icingaweb -d icingaweb -f /vagrant/etc/schema/preferences.pgsql.sql',
command => 'sudo -u postgres psql -U icingaweb -d icingaweb -f /vagrant/etc/schema/pgsql.sql',
require => [ Exec['create-pgsql-icingaweb-db'] ]
}

View File

@ -1,158 +0,0 @@
SHELL=/bin/sh
PACKAGE_TARNAME=@PACKAGE_TARNAME@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
HTTPD_CONFIG_PATH=@httpd_config_path@
ICINGAWEB_CONFIG_PATH=@icingaweb_config_path@
ICINGAWEB_LOG_PATH=@icingaweb_log_path@
INSTALL=@INSTALL@
INSTALL_OPTS=@INSTALL_OPTS@
INSTALL_OPTS_WEB=@INSTALL_OPTS_WEB@
default:
@echo "IcingaWeb make targets: "
@printf "%b" " -install:\t\t\tInstall the application and overwrite configs\n"
@printf "%b" " -update:\t\t\tInstall the application without touching the configs\n"
@printf "%b" " -install-apache-config:\tInstall the apache configuration\n"
#
# Installs the whole application w\o httpd configurations
#
install: install-config install-basic ensure-writable-folders install-cli
#
# Install icingacli bin
#
install-cli:
$(INSTALL) -m 755 -d $(INSTALL_OPTS) $(bindir)
$(INSTALL) -m 755 $(INSTALL_OPTS) "./bin/icingacli" $(bindir)/icingacli;
#
# Installs the whole application w\o configuration
#
install-basic: install-static-files install-runtime-dirs ensure-writable-folders
#
# Updates only the application
#
update: install-application
#
# Removes files created by ./configure
#
clean:
if [ -f ./Makefile ];then \
rm ./Makefile; \
fi; \
if [ -f ./etc/apache/icingaweb.conf ];then \
rm ./etc/apache/icingaweb.conf; \
fi;
#
# Installs/copies all static files (executables, scripts, html, etc)
#
install-static-files: install-application copy-web-files-public copy-web-files-modules
#
# Installs all configuration files
#
install-config:
$(INSTALL) -m 755 $(INSTALL_OPTS_WEB) -d $(DESTDIR)$(ICINGAWEB_CONFIG_PATH)
@dirs=`cd ./config ; find . -mindepth 1 -type d `;\
for dir in $$dirs; do \
$(INSTALL) -m 755 $(INSTALL_OPTS_WEB) -d $(DESTDIR)$(ICINGAWEB_CONFIG_PATH)/"$$dir"; \
done;
@files=`cd ./config ; find . -mindepth 1 -type f \
-and ! -name ".*" -and ! -name "*.in"`; \
for file in $$files; do \
$(INSTALL) -m 644 $(INSTALL_OPTS_WEB) "./config/$$file" $(DESTDIR)$(ICINGAWEB_CONFIG_PATH)/"$$file"; \
done
#
# Installs runtime directories like the application cache
#
install-runtime-dirs:
$(INSTALL) -m 755 $(INSTALL_OPTS_WEB) -d $(DESTDIR)$(prefix)/application/cache
#
# Copies the tests into the installation directory
#
install-tests: copy-folder-tests
#
# Install configurations for apache2
#
install-apache-config:
$(INSTALL) -m 755 -d $(INSTALL_OPTS) $(DESTDIR)$(HTTPD_CONFIG_PATH)
$(INSTALL) -m 644 $(INSTALL_OPTS) "./etc/apache/icingaweb.conf" $(DESTDIR)$(HTTPD_CONFIG_PATH)/icingaweb.conf;
#
# Installs the php files to the prefix
#
install-application: copy-web-files-application copy-web-files-library install-cli
#
# Rule for copying folders and containing files (arbitary types), hidden files are excluded
#
copy-folder-%:
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(prefix)/$*
@dirs=`find ./$* -mindepth 1 -type d `;\
for dir in $$dirs; do \
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(prefix)/"$$dir"; \
done;
@files=`find ./$* -mindepth 1 -type f \
-and ! -name ".*"`; \
for file in $$files; do \
$(INSTALL) -m 644 $(INSTALL_OPTS) "$$file" $(DESTDIR)$(prefix)/"$$file"; \
done
ensure-writable-folders:
$(INSTALL) -m 775 $(INSTALL_OPTS_WEB) -d $(DESTDIR)$(prefix)/var/
$(INSTALL) -m 775 $(INSTALL_OPTS_WEB) -d $(DESTDIR)$(ICINGAWEB_LOG_PATH)
chmod -R 775 $(DESTDIR)$(ICINGAWEB_CONFIG_PATH)
#
# Rule for copying only php, *html, js and ini files. Hidden files are ignored
#
copy-web-files-%:
$(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(prefix)/$*
@dirs=`find ./$* -mindepth 1 -type d `;\
for dir in $$dirs; do \
$(INSTALL) -m 755 $(INSTALL_OPTS_WEB) -d $(DESTDIR)$(prefix)/"$$dir"; \
done;
@files=`find ./$* -mindepth 1 -type f \
-name "*.php" -or -name "*.ini" -or -name "*.*html" \
-or -name "*.js" -or -name "*.css" -or -name "*.less" \
-or -name "*.otf" -or -name "*.ttf" -or -name "*.otf" \
-or -name "*.svg" -or -name "*.woff" -or -name "*.png" \
-and ! -name ".*"`; \
for file in $$files; do \
$(INSTALL) -m 644 $(INSTALL_OPTS_WEB) "$$file" $(DESTDIR)$(prefix)/"$$file"; \
done
#
# Create release or snapshot tarball
#
# TODO: Use git-archive
# create-tarball:
# @./bin/make-tarball --prefix $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)/
#
# create-tarball-nightly:
# ./bin/make-tarball --prefix $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-`date +%Y%m%d`-`git rev-parse --short HEAD`/

84
aclocal.m4 vendored
View File

@ -1,84 +0,0 @@
AC_DEFUN([AC_USER_GUESS],[
$2=$3
for x in $1; do
AC_MSG_CHECKING([if user $x exists])
AS_IF([ $GREP -q "^$x:" /etc/passwd ],
[ AC_MSG_RESULT([found]); $2=$x ; break],
[ AC_MSG_RESULT([not found]) ])
done
])
AC_DEFUN([AC_CHECK_PHP_MODULE],[
for x in $1;do
AC_MSG_CHECKING([if php has $x module])
AS_IF([ php -m | $GREP -iq "^$x$" ],
[ AC_MSG_RESULT([found]) ],
[ AC_MSG_ERROR([not found])])
done
])
AC_DEFUN([AC_CHECK_PHP_VERSION],[
AC_MSG_CHECKING([if php has at least version $1.$2.$3])
AS_IF([ test $1 -le `php -r 'echo PHP_MAJOR_VERSION;'` && \
test $2 -le `php -r 'echo PHP_MINOR_VERSION;'` && \
test $3 -le `php -r 'echo PHP_RELEASE_VERSION;'`],
[ AC_MSG_RESULT([PHP version is correct])],
[ AC_MSG_ERROR([You need at least PHP version $1.$2.$3])])
])
AC_DEFUN([AC_CHECK_PHP_INCLUDE],[
AC_MSG_CHECKING([if PHP runtime dependency '$2' is available])
AS_IF([ php -r 'require "$1";' ],
[ AC_MSG_RESULT([PHP runtime dependency fulfilled])],
[ AC_MSG_ERROR([PHP runtime dependency '$2' is missing])])
])
AC_DEFUN([AC_GROUP_GUESS],[
$2=$3
for x in $1; do
AC_MSG_CHECKING([if group $x exists])
AS_IF([ $GREP -q "^$x:" /etc/group ],
[ AC_MSG_RESULT([found]); $2=$x ; break],
[ AC_MSG_RESULT([not found]) ])
done
])
AC_DEFUN([AC_CHECK_BIN], [
AC_PATH_PROG([$1],[$2],[not found])
AS_IF([ test "XX${$1}" == "XXnot found" ],
[ AC_MSG_WARN([binary $2 not found in PATH]) ])
test "XX${$1}" == "XXnot found" && $1=""
])
AC_DEFUN([AC_PATH_GUESS], [
$2=$3
for x in $1; do
AC_MSG_CHECKING([if path $x exists])
AS_IF([test -d $x],
[AC_MSG_RESULT([found]); $2=$x; break],
[AC_MSG_RESULT([not found])]
)
done
])
# ICINGA_CHECK_DBTYPE(DBTYPE, ARGUMENT_NAME)
# ------------------------------------------
AC_DEFUN([ICINGA_CHECK_DBTYPE], [
AC_MSG_CHECKING([Testing database type for $2])
AS_IF(echo "$1" | $GREP -q "^\(my\|pg\)sql$",
AC_MSG_RESULT([OK ($1)]),
AC_MSG_ERROR([$1])
)
])
# ICINGA_CHECK_BACKENDTYPE(BACKENDTYPE, ARGUMENT_NAME)
# ------------------------------------------
AC_DEFUN([ICINGA_CHECK_BACKENDTYPE], [
AC_MSG_CHECKING([Testing backend type for $2])
AS_IF(echo "$1" | $GREP -q "^\(ido\|statusdat\|livestatus\)$",
AC_MSG_RESULT([OK ($1)]),
AC_MSG_ERROR([$1])
)
])

View File

@ -4,6 +4,7 @@
namespace Icinga\Clicommands;
use Icinga\Application\Icinga;
use Icinga\Cli\Command;
use Icinga\Exception\IcingaException;
@ -30,7 +31,7 @@ class WebCommand extends Command
// throw new IcingaException('Socket is required');
}
if ($basedir === null) {
$basedir = dirname(ICINGAWEB_APPDIR) . '/public';
$basedir = Icinga::app()->getBaseDir('public');
if (! file_exists($basedir) || ! is_dir($basedir)) {
throw new IcingaException('Basedir is required');
}
@ -46,7 +47,7 @@ class WebCommand extends Command
readlink('/proc/self/exe'),
$socket,
$basedir,
ICINGA_LIBDIR . '/Icinga/Application/webrouter.php'
Icinga::app()->getLibraryDir('/Icinga/Application/webrouter.php')
);
// TODO: Store webserver log, switch uid, log index.php includes, pid file

View File

@ -6,7 +6,7 @@
use Icinga\Authentication\Backend\AutoLoginBackend;
use Icinga\Web\Controller\ActionController;
use Icinga\Form\Authentication\LoginForm;
use Icinga\Forms\Authentication\LoginForm;
use Icinga\Authentication\AuthChain;
use Icinga\Application\Config;
use Icinga\Application\Logger;
@ -33,6 +33,17 @@ class AuthenticationController extends ActionController
*/
public function loginAction()
{
if (@file_exists(Config::$configDir . '/setup.token')) {
try {
$config = Config::app()->toArray();
if (empty($config)) {
$this->redirectNow(Url::fromPath('setup'));
}
} catch (NotReadableError $e) {
// Gets thrown in case of insufficient permission only
}
}
$auth = $this->Auth();
$this->view->form = $form = new LoginForm();
$this->view->title = $this->translate('Icingaweb Login');
@ -53,7 +64,7 @@ class AuthenticationController extends ActionController
$config = Config::app('authentication');
} catch (NotReadableError $e) {
throw new ConfigurationError(
$this->translate('Could not read your authentiction.ini, no authentication methods are available.'),
$this->translate('Could not read your authentication.ini, no authentication methods are available.'),
0,
$e
);
@ -93,30 +104,30 @@ class AuthenticationController extends ActionController
}
}
if ($backendsTried === 0) {
throw new ConfigurationError(
$this->view->form->addError(
$this->translate(
'No authentication methods available. Did you create'
. ' authentication.ini when installing Icinga Web 2?'
. ' authentication.ini when setting up Icinga Web 2?'
)
);
}
if ($backendsTried === $backendsWithError) {
throw new ConfigurationError(
} else if ($backendsTried === $backendsWithError) {
$this->view->form->addError(
$this->translate(
'All configured authentication methods failed.'
. ' Please check the system log or Icinga Web 2 log for more information.'
)
);
}
if ($backendsWithError) {
$this->view->form->getElement('username')->addError(
} elseif ($backendsWithError) {
$this->view->form->addError(
$this->translate(
'Please note that not all authentication methods were available.'
. ' Check the system log or Icinga Web 2 log for more information.'
)
);
}
$this->view->form->getElement('password')->addError($this->translate('Incorrect username or password'));
if ($backendsTried > 0 && $backendsTried !== $backendsWithError) {
$this->view->form->getElement('password')->addError($this->translate('Incorrect username or password'));
}
} elseif ($request->isGet()) {
$user = new User('');
foreach ($chain as $backend) {
@ -134,6 +145,8 @@ class AuthenticationController extends ActionController
} catch (Exception $e) {
$this->view->errorInfo = $e->getMessage();
}
$this->view->configMissing = is_dir(Config::$configDir) === false;
}
/**

View File

@ -8,11 +8,11 @@ use Icinga\Application\Modules\Module;
use Icinga\Web\Widget;
use Icinga\Application\Icinga;
use Icinga\Application\Config;
use Icinga\Form\Config\GeneralConfigForm;
use Icinga\Form\Config\AuthenticationBackendReorderForm;
use Icinga\Form\Config\AuthenticationBackendConfigForm;
use Icinga\Form\Config\ResourceConfigForm;
use Icinga\Form\ConfirmRemovalForm;
use Icinga\Forms\Config\GeneralConfigForm;
use Icinga\Forms\Config\AuthenticationBackendReorderForm;
use Icinga\Forms\Config\AuthenticationBackendConfigForm;
use Icinga\Forms\Config\ResourceConfigForm;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Data\ResourceFactory;
@ -99,7 +99,7 @@ class ConfigController extends ActionController
Notification::success(sprintf($this->translate('Module "%s" enabled'), $module));
$this->rerenderLayout()->reloadCss()->redirectNow('config/modules');
} catch (Exception $e) {
$this->view->exceptionMesssage = $e->getMessage();
$this->view->exceptionMessage = $e->getMessage();
$this->view->moduleName = $module;
$this->view->action = 'enable';
$this->render('module-configuration-error');

View File

@ -8,7 +8,7 @@ use Icinga\Exception\ConfigurationError;
use Icinga\Exception\IcingaException;
use Icinga\Exception\NotReadableError;
use Icinga\File\Ini\IniWriter;
use Icinga\Form\Dashboard\AddUrlForm;
use Icinga\Forms\Dashboard\AddUrlForm;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Url;
use Icinga\Web\Widget\Dashboard;

View File

@ -6,7 +6,7 @@ use Icinga\Web\Controller\BasePreferenceController;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tab;
use Icinga\Application\Config;
use Icinga\Form\PreferenceForm;
use Icinga\Forms\PreferenceForm;
use Icinga\Exception\ConfigurationError;
use Icinga\User\Preferences\PreferencesStore;
@ -25,9 +25,9 @@ class PreferenceController extends BasePreferenceController
public static function createProvidedTabs()
{
return array(
'general' => new Tab(
'preferences' => new Tab(
array(
'title' => 'General settings',
'title' => t('Preferences'),
'url' => Url::fromPath('/preference')
)
)
@ -51,6 +51,6 @@ class PreferenceController extends BasePreferenceController
$form->handleRequest();
$this->view->form = $form;
$this->getTabs()->activate('general');
$this->getTabs()->activate('preferences');
}
}

View File

@ -0,0 +1,39 @@
Font license info
## Font Awesome
Copyright (C) 2012 by Dave Gandy
Author: Dave Gandy
License: SIL ()
Homepage: http://fortawesome.github.com/Font-Awesome/
## Iconic
Copyright (C) 2012 by P.J. Onori
Author: P.J. Onori
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://somerandomdude.com/work/iconic/
## MFG Labs
Copyright (C) 2012 by Daniel Bruce
Author: MFG Labs
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://www.mfglabs.com/
## Entypo
Copyright (C) 2012 by Daniel Bruce
Author: Daniel Bruce
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://www.entypo.com

View File

@ -0,0 +1,75 @@
This webfont is generated by http://fontello.com open source project.
================================================================================
Please, note, that you should obey original font licences, used to make this
webfont pack. Details available in LICENSE.txt file.
- Usually, it's enough to publish content of LICENSE.txt file somewhere on your
site in "About" section.
- If your project is open-source, usually, it will be ok to make LICENSE.txt
file publically available in your repository.
- Fonts, used in Fontello, don't require to make clickable links on your site.
But any kind of additional authors crediting is welcome.
================================================================================
Comments on archive content
---------------------------
- /font/* - fonts in different formats
- /css/* - different kinds of css, for all situations. Should be ok with
twitter bootstrap. Also, you can skip <i> style and assign icon classes
directly to text elements, if you don't mind about IE7.
- demo.html - demo file, to show your webfont content
- LICENSE.txt - license info about source fonts, used to build your one.
- config.json - keeps your settings. You can import it back to fontello anytime,
to continue your work
Why so many CSS files ?
-----------------------
Because we like to fit all your needs :)
- basic file, <your_font_name>.css - is usually enougth, in contains @font-face
and character codes definition
- *-ie7.css - if you need IE7 support, but still don't wish to put char codes
directly into html
- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
rules, but still wish to benefit of css generation. That can be very
convenient for automated assets build systems. When you need to update font -
no needs to manually edit files, just override old version with archive
content. See fontello source codes for example.
- *-embedded.css - basic css file, but with embedded WOFF font, to avoid
CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
We strongly recommend to resolve this issue by `Access-Control-Allow-Origin`
server headers. But if you ok with dirty hack - this file is for you. Note,
that data url moved to separate @font-face to avoid problems with <IE9, when
string is too long.
- animate.css - use it to get ideas about spinner rotation animation.
Attention for server setup
--------------------------
You MUST setup server to reply with proper `mime-types` for font files. In other
case, some browsers will fail to show fonts.
Usually, `apache` already has necessary settings, but `nginx` and other
webservers should be tuned. Here is list of mime types for our file extentions:
- `application/vnd.ms-fontobject` - eot
- `application/x-font-woff` - woff
- `application/x-font-ttf` - ttf
- `image/svg+xml` - svg

View File

@ -0,0 +1,640 @@
{
"name": "ifont",
"css_prefix_text": "icon-",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "9dd9e835aebe1060ba7190ad2b2ed951",
"css": "search",
"code": 59484,
"src": "fontawesome"
},
{
"uid": "8b80d36d4ef43889db10bc1f0dc9a862",
"css": "user",
"code": 59393,
"src": "fontawesome"
},
{
"uid": "31972e4e9d080eaa796290349ae6c1fd",
"css": "users",
"code": 59394,
"src": "fontawesome"
},
{
"uid": "b1887b423d2fd15c345e090320c91ca0",
"css": "dashboard",
"code": 59392,
"src": "fontawesome"
},
{
"uid": "ce3cf091d6ebd004dd0b52d24074e6e3",
"css": "help",
"code": 59483,
"src": "fontawesome"
},
{
"uid": "3d4ea8a78dc34efe891f3a0f3d961274",
"css": "info",
"code": 59482,
"src": "fontawesome"
},
{
"uid": "d7271d490b71df4311e32cdacae8b331",
"css": "home",
"code": 59481,
"src": "fontawesome"
},
{
"uid": "c1f1975c885aa9f3dad7810c53b82074",
"css": "lock",
"code": 59480,
"src": "fontawesome"
},
{
"uid": "657ab647f6248a6b57a5b893beaf35a9",
"css": "lock-open",
"code": 59479,
"src": "fontawesome"
},
{
"uid": "05376be04a27d5a46e855a233d6e8508",
"css": "lock-open-alt",
"code": 59478,
"src": "fontawesome"
},
{
"uid": "c5fd349cbd3d23e4ade333789c29c729",
"css": "eye",
"code": 59475,
"src": "fontawesome"
},
{
"uid": "7fd683b2c518ceb9e5fa6757f2276faa",
"css": "eye-off",
"code": 59491,
"src": "fontawesome"
},
{
"uid": "3db5347bd219f3bce6025780f5d9ef45",
"css": "tag",
"code": 59476,
"src": "fontawesome"
},
{
"uid": "a3f89e106175a5c5c4e9738870b12e55",
"css": "tags",
"code": 59477,
"src": "fontawesome"
},
{
"uid": "acf41aa4018e58d49525665469e35665",
"css": "thumbs-up",
"code": 59495,
"src": "fontawesome"
},
{
"uid": "7533e68038fc6d520ede7a7ffa0a2f64",
"css": "thumbs-down",
"code": 59496,
"src": "fontawesome"
},
{
"uid": "9a76bc135eac17d2c8b8ad4a5774fc87",
"css": "download",
"code": 59400,
"src": "fontawesome"
},
{
"uid": "eeec3208c90b7b48e804919d0d2d4a41",
"css": "upload",
"code": 59401,
"src": "fontawesome"
},
{
"uid": "c6be5a58ee4e63a5ec399c2b0d15cf2c",
"css": "reply",
"code": 59473,
"src": "fontawesome"
},
{
"uid": "1b5597a3bacaeca6600e88ae36d02e0a",
"css": "reply-all",
"code": 59474,
"src": "fontawesome"
},
{
"uid": "3d39c828009c04ddb6764c0b04cd2439",
"css": "forward",
"code": 59472,
"src": "fontawesome"
},
{
"uid": "41087bc74d4b20b55059c60a33bf4008",
"css": "edit",
"code": 59471,
"src": "fontawesome"
},
{
"uid": "7277ded7695b2a307a5f9d50097bb64c",
"css": "print",
"code": 59470,
"src": "fontawesome"
},
{
"uid": "85528017f1e6053b2253785c31047f44",
"css": "comment",
"code": 59464,
"src": "fontawesome"
},
{
"uid": "dcedf50ab1ede3283d7a6c70e2fe32f3",
"css": "chat",
"code": 59465,
"src": "fontawesome"
},
{
"uid": "9c1376672bb4f1ed616fdd78a23667e9",
"css": "comment-empty",
"code": 59463,
"src": "fontawesome"
},
{
"uid": "31951fbb9820ed0690f675b3d495c8da",
"css": "chat-empty",
"code": 59466,
"src": "fontawesome"
},
{
"uid": "cd21cbfb28ad4d903cede582157f65dc",
"css": "bell",
"code": 59467,
"src": "fontawesome"
},
{
"uid": "671f29fa10dda08074a4c6a341bb4f39",
"css": "bell-alt",
"code": 59468,
"src": "fontawesome"
},
{
"uid": "563683020e0bf9f22f3f055a69b5c57a",
"css": "bell-off",
"code": 59488,
"src": "fontawesome"
},
{
"uid": "8a074400a056c59d389f2d0517281bd5",
"css": "bell-off-empty",
"code": 59489,
"src": "fontawesome"
},
{
"uid": "00391fac5d419345ffcccd95b6f76263",
"css": "attention-alt",
"code": 59469,
"src": "fontawesome"
},
{
"uid": "f48ae54adfb27d8ada53d0fd9e34ee10",
"css": "trash",
"code": 59462,
"src": "fontawesome"
},
{
"uid": "5408be43f7c42bccee419c6be53fdef5",
"css": "doc-text",
"code": 59461,
"src": "fontawesome"
},
{
"uid": "9daa1fdf0838118518a7e22715e83abc",
"css": "file-pdf",
"code": 59458,
"src": "fontawesome"
},
{
"uid": "310ffd629da85142bc8669f010556f2d",
"css": "file-word",
"code": 59459,
"src": "fontawesome"
},
{
"uid": "f761c3bbe16ba2d332914ecb28e7a042",
"css": "file-excel",
"code": 59460,
"src": "fontawesome"
},
{
"uid": "9f7e588c66cfd6891f6f507cf6f6596b",
"css": "phone",
"code": 59457,
"src": "fontawesome"
},
{
"uid": "e99461abfef3923546da8d745372c995",
"css": "conf",
"code": 59456,
"src": "fontawesome"
},
{
"uid": "98687378abd1faf8f6af97c254eb6cd6",
"css": "conf-alt",
"code": 59455,
"src": "fontawesome"
},
{
"uid": "5bb103cd29de77e0e06a52638527b575",
"css": "wrench",
"code": 59453,
"src": "fontawesome"
},
{
"uid": "21b42d3c3e6be44c3cc3d73042faa216",
"css": "sliders",
"code": 59454,
"src": "fontawesome"
},
{
"uid": "531bc468eecbb8867d822f1c11f1e039",
"css": "calendar",
"code": 59452,
"src": "fontawesome"
},
{
"uid": "ead4c82d04d7758db0f076584893a8c1",
"css": "calendar-empty",
"code": 59451,
"src": "fontawesome"
},
{
"uid": "3a00327e61b997b58518bd43ed83c3df",
"css": "endtime",
"code": 59449,
"src": "fontawesome"
},
{
"uid": "0d20938846444af8deb1920dc85a29fb",
"css": "starttime",
"code": 59450,
"src": "fontawesome"
},
{
"uid": "19c50c52858a81de58f9db488aba77bc",
"css": "mic",
"code": 59448,
"src": "fontawesome"
},
{
"uid": "43c629249e2cca7e73cd4ef410c9551f",
"css": "mute",
"code": 59447,
"src": "fontawesome"
},
{
"uid": "e44601720c64e6bb6a2d5cba6b0c588c",
"css": "volume-off",
"code": 59446,
"src": "fontawesome"
},
{
"uid": "fee6e00f36e8ca8ef3e4a62caa213bf6",
"css": "volume-down",
"code": 59445,
"src": "fontawesome"
},
{
"uid": "76857a03fbaa6857fe063b6c25aa98ed",
"css": "volume-up",
"code": 59444,
"src": "fontawesome"
},
{
"uid": "598a5f2bcf3521d1615de8e1881ccd17",
"css": "clock",
"code": 59443,
"src": "fontawesome"
},
{
"uid": "5278ef7773e948d56c4d442c8c8c98cf",
"css": "lightbulb",
"code": 59442,
"src": "fontawesome"
},
{
"uid": "98d9c83c1ee7c2c25af784b518c522c5",
"css": "block",
"code": 59440,
"src": "fontawesome"
},
{
"uid": "e594fc6e5870b4ab7e49f52571d52577",
"css": "resize-full",
"code": 59434,
"src": "fontawesome"
},
{
"uid": "b013f6403e5ab0326614e68d1850fd6b",
"css": "resize-full-alt",
"code": 59433,
"src": "fontawesome"
},
{
"uid": "3c24ee33c9487bbf18796ca6dffa1905",
"css": "resize-small",
"code": 59435,
"src": "fontawesome"
},
{
"uid": "d3b3f17bc3eb7cd809a07bbd4d178bee",
"css": "resize-vertical",
"code": 59438,
"src": "fontawesome"
},
{
"uid": "3c73d058e4589b65a8d959c0fc8f153d",
"css": "resize-horizontal",
"code": 59437,
"src": "fontawesome"
},
{
"uid": "6605ee6441bf499ffa3c63d3c7409471",
"css": "move",
"code": 59436,
"src": "fontawesome"
},
{
"uid": "0b2b66e526028a6972d51a6f10281b4b",
"css": "zoom-in",
"code": 59439,
"src": "fontawesome"
},
{
"uid": "d25d10efa900f529ad1d275657cfd30e",
"css": "zoom-out",
"code": 59441,
"src": "fontawesome"
},
{
"uid": "2d6150442079cbda7df64522dc24f482",
"css": "down-dir",
"code": 59421,
"src": "fontawesome"
},
{
"uid": "80cd1022bd9ea151d554bec1fa05f2de",
"css": "up-dir",
"code": 59422,
"src": "fontawesome"
},
{
"uid": "9dc654095085167524602c9acc0c5570",
"css": "left-dir",
"code": 59423,
"src": "fontawesome"
},
{
"uid": "fb1c799ffe5bf8fb7f8bcb647c8fe9e6",
"css": "right-dir",
"code": 59424,
"src": "fontawesome"
},
{
"uid": "ccddff8e8670dcd130e3cb55fdfc2fd0",
"css": "down-open",
"code": 59425,
"src": "fontawesome"
},
{
"uid": "d870630ff8f81e6de3958ecaeac532f2",
"css": "left-open",
"code": 59428,
"src": "fontawesome"
},
{
"uid": "399ef63b1e23ab1b761dfbb5591fa4da",
"css": "right-open",
"code": 59426,
"src": "fontawesome"
},
{
"uid": "fe6697b391355dec12f3d86d6d490397",
"css": "up-open",
"code": 59427,
"src": "fontawesome"
},
{
"uid": "1c4068ed75209e21af36017df8871802",
"css": "down-big",
"code": 59432,
"src": "fontawesome"
},
{
"uid": "555ef8c86832e686fef85f7af2eb7cde",
"css": "left-big",
"code": 59431,
"src": "fontawesome"
},
{
"uid": "ad6b3fbb5324abe71a9c0b6609cbb9f1",
"css": "right-big",
"code": 59430,
"src": "fontawesome"
},
{
"uid": "95376bf082bfec6ce06ea1cda7bd7ead",
"css": "up-big",
"code": 59429,
"src": "fontawesome"
},
{
"uid": "d407a4707f719b042ed2ad28d2619d7e",
"css": "service",
"code": 59420,
"src": "fontawesome"
},
{
"uid": "500fc1f109021e4b1de4deda2f7ed399",
"css": "host",
"code": 59494,
"src": "fontawesome"
},
{
"uid": "197375a3cea8cb90b02d06e4ddf1433d",
"css": "globe",
"code": 59417,
"src": "fontawesome"
},
{
"uid": "2c413e78faf1d6631fd7b094d14c2253",
"css": "cloud",
"code": 59418,
"src": "fontawesome"
},
{
"uid": "3212f42c65d41ed91cb435d0490e29ed",
"css": "flash",
"code": 59419,
"src": "fontawesome"
},
{
"uid": "8772331a9fec983cdb5d72902a6f9e0e",
"css": "scissors",
"code": 59416,
"src": "fontawesome"
},
{
"uid": "b429436ec5a518c78479d44ef18dbd60",
"css": "paste",
"code": 59415,
"src": "fontawesome"
},
{
"uid": "8b9e6a8dd8f67f7c003ed8e7e5ee0857",
"css": "off",
"code": 59413,
"src": "fontawesome"
},
{
"uid": "9755f76110ae4d12ac5f9466c9152031",
"css": "book",
"code": 59414,
"src": "fontawesome"
},
{
"uid": "ea2d9a8c51ca42b38ef0d2a07f16d9a7",
"css": "chart-line",
"code": 59487,
"src": "fontawesome"
},
{
"uid": "3e674995cacc2b09692c096ea7eb6165",
"css": "megaphone",
"code": 59409,
"src": "fontawesome"
},
{
"uid": "7432077e6a2d6aa19984ca821bb6bbda",
"css": "bug",
"code": 59410,
"src": "fontawesome"
},
{
"uid": "9396b2d8849e0213a0f11c5fd7fcc522",
"css": "tasks",
"code": 59411,
"src": "fontawesome"
},
{
"uid": "4109c474ff99cad28fd5a2c38af2ec6f",
"css": "filter",
"code": 59412,
"src": "fontawesome"
},
{
"uid": "3ed68ae14e9cde775121954242a412b2",
"css": "sort-name-up",
"code": 59407,
"src": "fontawesome"
},
{
"uid": "6586267200a42008a9fc0a1bf7ac06c7",
"css": "sort-name-down",
"code": 59408,
"src": "fontawesome"
},
{
"uid": "0bda4bc779d4c32623dec2e43bd67ee8",
"css": "gauge",
"code": 59405,
"src": "fontawesome"
},
{
"uid": "6fe95ffc3c807e62647d4f814a96e0d7",
"css": "sitemap",
"code": 59406,
"src": "fontawesome"
},
{
"uid": "af95ef0ddda80a78828c62d386506433",
"css": "cubes",
"code": 59403,
"src": "fontawesome"
},
{
"uid": "347c38a8b96a509270fdcabc951e7571",
"css": "database",
"code": 59404,
"src": "fontawesome"
},
{
"uid": "a14be0c7e0689076e2bdde97f8e309f9",
"css": "plug",
"code": 59490,
"src": "fontawesome"
},
{
"uid": "e7cb72a17f3b21e3576f35c3f0a7639b",
"css": "git",
"code": 59402,
"src": "fontawesome"
},
{
"uid": "465bb89b6f204234e5787c326b4ae54c",
"css": "rewind",
"code": 59486,
"src": "entypo"
},
{
"uid": "bb46b15cb78cc4cc05d3d715d522ac4d",
"css": "cw",
"code": 59493,
"src": "entypo"
},
{
"uid": "3bd18d47a12b8709e9f4fe9ead4f7518",
"css": "reschedule",
"code": 59492,
"src": "entypo"
},
{
"uid": "b90d80c250a9bbdd6cd3fe00e6351710",
"css": "ok",
"code": 59395,
"src": "iconic"
},
{
"uid": "11e664deed5b2587456a4f9c01d720b6",
"css": "cancel",
"code": 59396,
"src": "iconic"
},
{
"uid": "dbd39eb5a1d67beb54cfcb535e840e0f",
"css": "plus",
"code": 59397,
"src": "iconic"
},
{
"uid": "9559f17a471856ef50ed266e726cfa25",
"css": "minus",
"code": 59398,
"src": "iconic"
},
{
"uid": "13ea1e82d38c7ed614d9ee85e9c42053",
"css": "folder-empty",
"code": 59399,
"src": "iconic"
},
{
"uid": "9c3b8d8a6d477da4d3e65b92e4e9c290",
"css": "flapping",
"code": 59485,
"src": "mfglabs"
}
]
}

View File

@ -0,0 +1,85 @@
/*
Animation example, for spinners
*/
.animate-spin {
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
display: inline-block;
}
@-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-webkit-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-o-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-ms-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

View File

@ -0,0 +1,106 @@
.icon-dashboard:before { content: '\e800'; } /* '' */
.icon-user:before { content: '\e801'; } /* '' */
.icon-users:before { content: '\e802'; } /* '' */
.icon-ok:before { content: '\e803'; } /* '' */
.icon-cancel:before { content: '\e804'; } /* '' */
.icon-plus:before { content: '\e805'; } /* '' */
.icon-minus:before { content: '\e806'; } /* '' */
.icon-folder-empty:before { content: '\e807'; } /* '' */
.icon-download:before { content: '\e808'; } /* '' */
.icon-upload:before { content: '\e809'; } /* '' */
.icon-git:before { content: '\e80a'; } /* '' */
.icon-cubes:before { content: '\e80b'; } /* '' */
.icon-database:before { content: '\e80c'; } /* '' */
.icon-gauge:before { content: '\e80d'; } /* '' */
.icon-sitemap:before { content: '\e80e'; } /* '' */
.icon-sort-name-up:before { content: '\e80f'; } /* '' */
.icon-sort-name-down:before { content: '\e810'; } /* '' */
.icon-megaphone:before { content: '\e811'; } /* '' */
.icon-bug:before { content: '\e812'; } /* '' */
.icon-tasks:before { content: '\e813'; } /* '' */
.icon-filter:before { content: '\e814'; } /* '' */
.icon-off:before { content: '\e815'; } /* '' */
.icon-book:before { content: '\e816'; } /* '' */
.icon-paste:before { content: '\e817'; } /* '' */
.icon-scissors:before { content: '\e818'; } /* '' */
.icon-globe:before { content: '\e819'; } /* '' */
.icon-cloud:before { content: '\e81a'; } /* '' */
.icon-flash:before { content: '\e81b'; } /* '' */
.icon-service:before { content: '\e81c'; } /* '' */
.icon-down-dir:before { content: '\e81d'; } /* '' */
.icon-up-dir:before { content: '\e81e'; } /* '' */
.icon-left-dir:before { content: '\e81f'; } /* '' */
.icon-right-dir:before { content: '\e820'; } /* '' */
.icon-down-open:before { content: '\e821'; } /* '' */
.icon-right-open:before { content: '\e822'; } /* '' */
.icon-up-open:before { content: '\e823'; } /* '' */
.icon-left-open:before { content: '\e824'; } /* '' */
.icon-up-big:before { content: '\e825'; } /* '' */
.icon-right-big:before { content: '\e826'; } /* '' */
.icon-left-big:before { content: '\e827'; } /* '' */
.icon-down-big:before { content: '\e828'; } /* '' */
.icon-resize-full-alt:before { content: '\e829'; } /* '' */
.icon-resize-full:before { content: '\e82a'; } /* '' */
.icon-resize-small:before { content: '\e82b'; } /* '' */
.icon-move:before { content: '\e82c'; } /* '' */
.icon-resize-horizontal:before { content: '\e82d'; } /* '' */
.icon-resize-vertical:before { content: '\e82e'; } /* '' */
.icon-zoom-in:before { content: '\e82f'; } /* '' */
.icon-block:before { content: '\e830'; } /* '' */
.icon-zoom-out:before { content: '\e831'; } /* '' */
.icon-lightbulb:before { content: '\e832'; } /* '' */
.icon-clock:before { content: '\e833'; } /* '' */
.icon-volume-up:before { content: '\e834'; } /* '' */
.icon-volume-down:before { content: '\e835'; } /* '' */
.icon-volume-off:before { content: '\e836'; } /* '' */
.icon-mute:before { content: '\e837'; } /* '' */
.icon-mic:before { content: '\e838'; } /* '' */
.icon-endtime:before { content: '\e839'; } /* '' */
.icon-starttime:before { content: '\e83a'; } /* '' */
.icon-calendar-empty:before { content: '\e83b'; } /* '' */
.icon-calendar:before { content: '\e83c'; } /* '' */
.icon-wrench:before { content: '\e83d'; } /* '' */
.icon-sliders:before { content: '\e83e'; } /* '' */
.icon-conf-alt:before { content: '\e83f'; } /* '' */
.icon-conf:before { content: '\e840'; } /* '' */
.icon-phone:before { content: '\e841'; } /* '' */
.icon-file-pdf:before { content: '\e842'; } /* '' */
.icon-file-word:before { content: '\e843'; } /* '' */
.icon-file-excel:before { content: '\e844'; } /* '' */
.icon-doc-text:before { content: '\e845'; } /* '' */
.icon-trash:before { content: '\e846'; } /* '' */
.icon-comment-empty:before { content: '\e847'; } /* '' */
.icon-comment:before { content: '\e848'; } /* '' */
.icon-chat:before { content: '\e849'; } /* '' */
.icon-chat-empty:before { content: '\e84a'; } /* '' */
.icon-bell:before { content: '\e84b'; } /* '' */
.icon-bell-alt:before { content: '\e84c'; } /* '' */
.icon-attention-alt:before { content: '\e84d'; } /* '' */
.icon-print:before { content: '\e84e'; } /* '' */
.icon-edit:before { content: '\e84f'; } /* '' */
.icon-forward:before { content: '\e850'; } /* '' */
.icon-reply:before { content: '\e851'; } /* '' */
.icon-reply-all:before { content: '\e852'; } /* '' */
.icon-eye:before { content: '\e853'; } /* '' */
.icon-tag:before { content: '\e854'; } /* '' */
.icon-tags:before { content: '\e855'; } /* '' */
.icon-lock-open-alt:before { content: '\e856'; } /* '' */
.icon-lock-open:before { content: '\e857'; } /* '' */
.icon-lock:before { content: '\e858'; } /* '' */
.icon-home:before { content: '\e859'; } /* '' */
.icon-info:before { content: '\e85a'; } /* '' */
.icon-help:before { content: '\e85b'; } /* '' */
.icon-search:before { content: '\e85c'; } /* '' */
.icon-flapping:before { content: '\e85d'; } /* '' */
.icon-rewind:before { content: '\e85e'; } /* '' */
.icon-chart-line:before { content: '\e85f'; } /* '' */
.icon-bell-off:before { content: '\e860'; } /* '' */
.icon-bell-off-empty:before { content: '\e861'; } /* '' */
.icon-plug:before { content: '\e862'; } /* '' */
.icon-eye-off:before { content: '\e863'; } /* '' */
.icon-reschedule:before { content: '\e864'; } /* '' */
.icon-cw:before { content: '\e865'; } /* '' */
.icon-host:before { content: '\e866'; } /* '' */
.icon-thumbs-up:before { content: '\e867'; } /* '' */
.icon-thumbs-down:before { content: '\e868'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,106 @@
.icon-dashboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-user { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
.icon-users { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-ok { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
.icon-minus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }
.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe808;&nbsp;'); }
.icon-upload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe809;&nbsp;'); }
.icon-git { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80a;&nbsp;'); }
.icon-cubes { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80b;&nbsp;'); }
.icon-database { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80c;&nbsp;'); }
.icon-gauge { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80d;&nbsp;'); }
.icon-sitemap { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80e;&nbsp;'); }
.icon-sort-name-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80f;&nbsp;'); }
.icon-sort-name-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe810;&nbsp;'); }
.icon-megaphone { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe811;&nbsp;'); }
.icon-bug { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
.icon-tasks { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
.icon-filter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe814;&nbsp;'); }
.icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe815;&nbsp;'); }
.icon-book { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe816;&nbsp;'); }
.icon-paste { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe817;&nbsp;'); }
.icon-scissors { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe818;&nbsp;'); }
.icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe819;&nbsp;'); }
.icon-cloud { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81a;&nbsp;'); }
.icon-flash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81b;&nbsp;'); }
.icon-service { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81c;&nbsp;'); }
.icon-down-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81d;&nbsp;'); }
.icon-up-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81e;&nbsp;'); }
.icon-left-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81f;&nbsp;'); }
.icon-right-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe820;&nbsp;'); }
.icon-down-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe821;&nbsp;'); }
.icon-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe822;&nbsp;'); }
.icon-up-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe823;&nbsp;'); }
.icon-left-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe824;&nbsp;'); }
.icon-up-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe825;&nbsp;'); }
.icon-right-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe826;&nbsp;'); }
.icon-left-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe827;&nbsp;'); }
.icon-down-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe828;&nbsp;'); }
.icon-resize-full-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe829;&nbsp;'); }
.icon-resize-full { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82a;&nbsp;'); }
.icon-resize-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82b;&nbsp;'); }
.icon-move { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82c;&nbsp;'); }
.icon-resize-horizontal { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82d;&nbsp;'); }
.icon-resize-vertical { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82e;&nbsp;'); }
.icon-zoom-in { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82f;&nbsp;'); }
.icon-block { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe830;&nbsp;'); }
.icon-zoom-out { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe831;&nbsp;'); }
.icon-lightbulb { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe832;&nbsp;'); }
.icon-clock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe833;&nbsp;'); }
.icon-volume-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe834;&nbsp;'); }
.icon-volume-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe835;&nbsp;'); }
.icon-volume-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe836;&nbsp;'); }
.icon-mute { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe837;&nbsp;'); }
.icon-mic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe838;&nbsp;'); }
.icon-endtime { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe839;&nbsp;'); }
.icon-starttime { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83a;&nbsp;'); }
.icon-calendar-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83b;&nbsp;'); }
.icon-calendar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83c;&nbsp;'); }
.icon-wrench { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83d;&nbsp;'); }
.icon-sliders { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83e;&nbsp;'); }
.icon-conf-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83f;&nbsp;'); }
.icon-conf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe840;&nbsp;'); }
.icon-phone { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe841;&nbsp;'); }
.icon-file-pdf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe842;&nbsp;'); }
.icon-file-word { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe843;&nbsp;'); }
.icon-file-excel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe844;&nbsp;'); }
.icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe845;&nbsp;'); }
.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe846;&nbsp;'); }
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe847;&nbsp;'); }
.icon-comment { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe848;&nbsp;'); }
.icon-chat { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe849;&nbsp;'); }
.icon-chat-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84a;&nbsp;'); }
.icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84b;&nbsp;'); }
.icon-bell-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84c;&nbsp;'); }
.icon-attention-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84d;&nbsp;'); }
.icon-print { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84e;&nbsp;'); }
.icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84f;&nbsp;'); }
.icon-forward { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe850;&nbsp;'); }
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe851;&nbsp;'); }
.icon-reply-all { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe852;&nbsp;'); }
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe853;&nbsp;'); }
.icon-tag { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe854;&nbsp;'); }
.icon-tags { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe855;&nbsp;'); }
.icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe856;&nbsp;'); }
.icon-lock-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe857;&nbsp;'); }
.icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe858;&nbsp;'); }
.icon-home { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe859;&nbsp;'); }
.icon-info { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85a;&nbsp;'); }
.icon-help { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85b;&nbsp;'); }
.icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85c;&nbsp;'); }
.icon-flapping { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85d;&nbsp;'); }
.icon-rewind { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85e;&nbsp;'); }
.icon-chart-line { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85f;&nbsp;'); }
.icon-bell-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe860;&nbsp;'); }
.icon-bell-off-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe861;&nbsp;'); }
.icon-plug { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe862;&nbsp;'); }
.icon-eye-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe863;&nbsp;'); }
.icon-reschedule { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe864;&nbsp;'); }
.icon-cw { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe865;&nbsp;'); }
.icon-host { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe866;&nbsp;'); }
.icon-thumbs-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe867;&nbsp;'); }
.icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe868;&nbsp;'); }

View File

@ -0,0 +1,117 @@
[class^="icon-"], [class*=" icon-"] {
font-family: 'ifont';
font-style: normal;
font-weight: normal;
/* fix buttons height */
line-height: 1em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
}
.icon-dashboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-user { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
.icon-users { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-ok { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
.icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
.icon-minus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
.icon-folder-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }
.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe808;&nbsp;'); }
.icon-upload { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe809;&nbsp;'); }
.icon-git { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80a;&nbsp;'); }
.icon-cubes { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80b;&nbsp;'); }
.icon-database { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80c;&nbsp;'); }
.icon-gauge { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80d;&nbsp;'); }
.icon-sitemap { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80e;&nbsp;'); }
.icon-sort-name-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80f;&nbsp;'); }
.icon-sort-name-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe810;&nbsp;'); }
.icon-megaphone { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe811;&nbsp;'); }
.icon-bug { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
.icon-tasks { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
.icon-filter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe814;&nbsp;'); }
.icon-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe815;&nbsp;'); }
.icon-book { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe816;&nbsp;'); }
.icon-paste { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe817;&nbsp;'); }
.icon-scissors { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe818;&nbsp;'); }
.icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe819;&nbsp;'); }
.icon-cloud { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81a;&nbsp;'); }
.icon-flash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81b;&nbsp;'); }
.icon-service { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81c;&nbsp;'); }
.icon-down-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81d;&nbsp;'); }
.icon-up-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81e;&nbsp;'); }
.icon-left-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe81f;&nbsp;'); }
.icon-right-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe820;&nbsp;'); }
.icon-down-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe821;&nbsp;'); }
.icon-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe822;&nbsp;'); }
.icon-up-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe823;&nbsp;'); }
.icon-left-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe824;&nbsp;'); }
.icon-up-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe825;&nbsp;'); }
.icon-right-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe826;&nbsp;'); }
.icon-left-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe827;&nbsp;'); }
.icon-down-big { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe828;&nbsp;'); }
.icon-resize-full-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe829;&nbsp;'); }
.icon-resize-full { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82a;&nbsp;'); }
.icon-resize-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82b;&nbsp;'); }
.icon-move { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82c;&nbsp;'); }
.icon-resize-horizontal { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82d;&nbsp;'); }
.icon-resize-vertical { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82e;&nbsp;'); }
.icon-zoom-in { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe82f;&nbsp;'); }
.icon-block { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe830;&nbsp;'); }
.icon-zoom-out { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe831;&nbsp;'); }
.icon-lightbulb { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe832;&nbsp;'); }
.icon-clock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe833;&nbsp;'); }
.icon-volume-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe834;&nbsp;'); }
.icon-volume-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe835;&nbsp;'); }
.icon-volume-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe836;&nbsp;'); }
.icon-mute { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe837;&nbsp;'); }
.icon-mic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe838;&nbsp;'); }
.icon-endtime { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe839;&nbsp;'); }
.icon-starttime { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83a;&nbsp;'); }
.icon-calendar-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83b;&nbsp;'); }
.icon-calendar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83c;&nbsp;'); }
.icon-wrench { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83d;&nbsp;'); }
.icon-sliders { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83e;&nbsp;'); }
.icon-conf-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe83f;&nbsp;'); }
.icon-conf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe840;&nbsp;'); }
.icon-phone { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe841;&nbsp;'); }
.icon-file-pdf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe842;&nbsp;'); }
.icon-file-word { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe843;&nbsp;'); }
.icon-file-excel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe844;&nbsp;'); }
.icon-doc-text { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe845;&nbsp;'); }
.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe846;&nbsp;'); }
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe847;&nbsp;'); }
.icon-comment { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe848;&nbsp;'); }
.icon-chat { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe849;&nbsp;'); }
.icon-chat-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84a;&nbsp;'); }
.icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84b;&nbsp;'); }
.icon-bell-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84c;&nbsp;'); }
.icon-attention-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84d;&nbsp;'); }
.icon-print { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84e;&nbsp;'); }
.icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe84f;&nbsp;'); }
.icon-forward { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe850;&nbsp;'); }
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe851;&nbsp;'); }
.icon-reply-all { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe852;&nbsp;'); }
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe853;&nbsp;'); }
.icon-tag { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe854;&nbsp;'); }
.icon-tags { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe855;&nbsp;'); }
.icon-lock-open-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe856;&nbsp;'); }
.icon-lock-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe857;&nbsp;'); }
.icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe858;&nbsp;'); }
.icon-home { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe859;&nbsp;'); }
.icon-info { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85a;&nbsp;'); }
.icon-help { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85b;&nbsp;'); }
.icon-search { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85c;&nbsp;'); }
.icon-flapping { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85d;&nbsp;'); }
.icon-rewind { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85e;&nbsp;'); }
.icon-chart-line { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe85f;&nbsp;'); }
.icon-bell-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe860;&nbsp;'); }
.icon-bell-off-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe861;&nbsp;'); }
.icon-plug { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe862;&nbsp;'); }
.icon-eye-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe863;&nbsp;'); }
.icon-reschedule { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe864;&nbsp;'); }
.icon-cw { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe865;&nbsp;'); }
.icon-host { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe866;&nbsp;'); }
.icon-thumbs-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe867;&nbsp;'); }
.icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe868;&nbsp;'); }

View File

@ -0,0 +1,157 @@
@font-face {
font-family: 'ifont';
src: url('../font/ifont.eot?81676749');
src: url('../font/ifont.eot?81676749#iefix') format('embedded-opentype'),
url('../font/ifont.woff?81676749') format('woff'),
url('../font/ifont.ttf?81676749') format('truetype'),
url('../font/ifont.svg?81676749#ifont') format('svg');
font-weight: normal;
font-style: normal;
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'ifont';
src: url('../font/ifont.svg?81676749#ifont') format('svg');
}
}
*/
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "ifont";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: .2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
}
.icon-dashboard:before { content: '\e800'; } /* '' */
.icon-user:before { content: '\e801'; } /* '' */
.icon-users:before { content: '\e802'; } /* '' */
.icon-ok:before { content: '\e803'; } /* '' */
.icon-cancel:before { content: '\e804'; } /* '' */
.icon-plus:before { content: '\e805'; } /* '' */
.icon-minus:before { content: '\e806'; } /* '' */
.icon-folder-empty:before { content: '\e807'; } /* '' */
.icon-download:before { content: '\e808'; } /* '' */
.icon-upload:before { content: '\e809'; } /* '' */
.icon-git:before { content: '\e80a'; } /* '' */
.icon-cubes:before { content: '\e80b'; } /* '' */
.icon-database:before { content: '\e80c'; } /* '' */
.icon-gauge:before { content: '\e80d'; } /* '' */
.icon-sitemap:before { content: '\e80e'; } /* '' */
.icon-sort-name-up:before { content: '\e80f'; } /* '' */
.icon-sort-name-down:before { content: '\e810'; } /* '' */
.icon-megaphone:before { content: '\e811'; } /* '' */
.icon-bug:before { content: '\e812'; } /* '' */
.icon-tasks:before { content: '\e813'; } /* '' */
.icon-filter:before { content: '\e814'; } /* '' */
.icon-off:before { content: '\e815'; } /* '' */
.icon-book:before { content: '\e816'; } /* '' */
.icon-paste:before { content: '\e817'; } /* '' */
.icon-scissors:before { content: '\e818'; } /* '' */
.icon-globe:before { content: '\e819'; } /* '' */
.icon-cloud:before { content: '\e81a'; } /* '' */
.icon-flash:before { content: '\e81b'; } /* '' */
.icon-service:before { content: '\e81c'; } /* '' */
.icon-down-dir:before { content: '\e81d'; } /* '' */
.icon-up-dir:before { content: '\e81e'; } /* '' */
.icon-left-dir:before { content: '\e81f'; } /* '' */
.icon-right-dir:before { content: '\e820'; } /* '' */
.icon-down-open:before { content: '\e821'; } /* '' */
.icon-right-open:before { content: '\e822'; } /* '' */
.icon-up-open:before { content: '\e823'; } /* '' */
.icon-left-open:before { content: '\e824'; } /* '' */
.icon-up-big:before { content: '\e825'; } /* '' */
.icon-right-big:before { content: '\e826'; } /* '' */
.icon-left-big:before { content: '\e827'; } /* '' */
.icon-down-big:before { content: '\e828'; } /* '' */
.icon-resize-full-alt:before { content: '\e829'; } /* '' */
.icon-resize-full:before { content: '\e82a'; } /* '' */
.icon-resize-small:before { content: '\e82b'; } /* '' */
.icon-move:before { content: '\e82c'; } /* '' */
.icon-resize-horizontal:before { content: '\e82d'; } /* '' */
.icon-resize-vertical:before { content: '\e82e'; } /* '' */
.icon-zoom-in:before { content: '\e82f'; } /* '' */
.icon-block:before { content: '\e830'; } /* '' */
.icon-zoom-out:before { content: '\e831'; } /* '' */
.icon-lightbulb:before { content: '\e832'; } /* '' */
.icon-clock:before { content: '\e833'; } /* '' */
.icon-volume-up:before { content: '\e834'; } /* '' */
.icon-volume-down:before { content: '\e835'; } /* '' */
.icon-volume-off:before { content: '\e836'; } /* '' */
.icon-mute:before { content: '\e837'; } /* '' */
.icon-mic:before { content: '\e838'; } /* '' */
.icon-endtime:before { content: '\e839'; } /* '' */
.icon-starttime:before { content: '\e83a'; } /* '' */
.icon-calendar-empty:before { content: '\e83b'; } /* '' */
.icon-calendar:before { content: '\e83c'; } /* '' */
.icon-wrench:before { content: '\e83d'; } /* '' */
.icon-sliders:before { content: '\e83e'; } /* '' */
.icon-conf-alt:before { content: '\e83f'; } /* '' */
.icon-conf:before { content: '\e840'; } /* '' */
.icon-phone:before { content: '\e841'; } /* '' */
.icon-file-pdf:before { content: '\e842'; } /* '' */
.icon-file-word:before { content: '\e843'; } /* '' */
.icon-file-excel:before { content: '\e844'; } /* '' */
.icon-doc-text:before { content: '\e845'; } /* '' */
.icon-trash:before { content: '\e846'; } /* '' */
.icon-comment-empty:before { content: '\e847'; } /* '' */
.icon-comment:before { content: '\e848'; } /* '' */
.icon-chat:before { content: '\e849'; } /* '' */
.icon-chat-empty:before { content: '\e84a'; } /* '' */
.icon-bell:before { content: '\e84b'; } /* '' */
.icon-bell-alt:before { content: '\e84c'; } /* '' */
.icon-attention-alt:before { content: '\e84d'; } /* '' */
.icon-print:before { content: '\e84e'; } /* '' */
.icon-edit:before { content: '\e84f'; } /* '' */
.icon-forward:before { content: '\e850'; } /* '' */
.icon-reply:before { content: '\e851'; } /* '' */
.icon-reply-all:before { content: '\e852'; } /* '' */
.icon-eye:before { content: '\e853'; } /* '' */
.icon-tag:before { content: '\e854'; } /* '' */
.icon-tags:before { content: '\e855'; } /* '' */
.icon-lock-open-alt:before { content: '\e856'; } /* '' */
.icon-lock-open:before { content: '\e857'; } /* '' */
.icon-lock:before { content: '\e858'; } /* '' */
.icon-home:before { content: '\e859'; } /* '' */
.icon-info:before { content: '\e85a'; } /* '' */
.icon-help:before { content: '\e85b'; } /* '' */
.icon-search:before { content: '\e85c'; } /* '' */
.icon-flapping:before { content: '\e85d'; } /* '' */
.icon-rewind:before { content: '\e85e'; } /* '' */
.icon-chart-line:before { content: '\e85f'; } /* '' */
.icon-bell-off:before { content: '\e860'; } /* '' */
.icon-bell-off-empty:before { content: '\e861'; } /* '' */
.icon-plug:before { content: '\e862'; } /* '' */
.icon-eye-off:before { content: '\e863'; } /* '' */
.icon-reschedule:before { content: '\e864'; } /* '' */
.icon-cw:before { content: '\e865'; } /* '' */
.icon-host:before { content: '\e866'; } /* '' */
.icon-thumbs-up:before { content: '\e867'; } /* '' */
.icon-thumbs-down:before { content: '\e868'; } /* '' */

View File

@ -0,0 +1,419 @@
<!DOCTYPE html>
<html>
<head><!--[if lt IE 9]><script language="javascript" type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<meta charset="UTF-8"><style>/*
* Bootstrap v2.2.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
.clearfix {
*zoom: 1;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
line-height: 0;
}
.clearfix:after {
clear: both;
}
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
a:focus {
outline: thin dotted #333;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
a:hover,
a:active {
outline: 0;
}
button,
input,
select,
textarea {
margin: 0;
font-size: 100%;
vertical-align: middle;
}
button,
input {
*overflow: visible;
line-height: normal;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
padding: 0;
border: 0;
}
body {
margin: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 20px;
color: #333;
background-color: #fff;
}
a {
color: #08c;
text-decoration: none;
}
a:hover {
color: #005580;
text-decoration: underline;
}
.row {
margin-left: -20px;
*zoom: 1;
}
.row:before,
.row:after {
display: table;
content: "";
line-height: 0;
}
.row:after {
clear: both;
}
[class*="span"] {
float: left;
min-height: 1px;
margin-left: 20px;
}
.container,
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 940px;
}
.span12 {
width: 940px;
}
.span11 {
width: 860px;
}
.span10 {
width: 780px;
}
.span9 {
width: 700px;
}
.span8 {
width: 620px;
}
.span7 {
width: 540px;
}
.span6 {
width: 460px;
}
.span5 {
width: 380px;
}
.span4 {
width: 300px;
}
.span3 {
width: 220px;
}
.span2 {
width: 140px;
}
.span1 {
width: 60px;
}
[class*="span"].pull-right,
.row-fluid [class*="span"].pull-right {
float: right;
}
.container {
margin-right: auto;
margin-left: auto;
*zoom: 1;
}
.container:before,
.container:after {
display: table;
content: "";
line-height: 0;
}
.container:after {
clear: both;
}
p {
margin: 0 0 10px;
}
.lead {
margin-bottom: 20px;
font-size: 21px;
font-weight: 200;
line-height: 30px;
}
small {
font-size: 85%;
}
h1 {
margin: 10px 0;
font-family: inherit;
font-weight: bold;
line-height: 20px;
color: inherit;
text-rendering: optimizelegibility;
}
h1 small {
font-weight: normal;
line-height: 1;
color: #999;
}
h1 {
line-height: 40px;
}
h1 {
font-size: 38.5px;
}
h1 small {
font-size: 24.5px;
}
body {
margin-top: 90px;
}
.header {
position: fixed;
top: 0;
left: 50%;
margin-left: -480px;
background-color: #fff;
border-bottom: 1px solid #ddd;
padding-top: 10px;
z-index: 10;
}
.footer {
color: #ddd;
font-size: 12px;
text-align: center;
margin-top: 20px;
}
.footer a {
color: #ccc;
text-decoration: underline;
}
.the-icons {
font-size: 14px;
line-height: 24px;
}
.switch {
position: absolute;
right: 0;
bottom: 10px;
color: #666;
}
.switch input {
margin-right: 0.3em;
}
.codesOn .i-name {
display: none;
}
.codesOn .i-code {
display: inline;
}
.i-code {
display: none;
}
</style>
<link rel="stylesheet" href="css/ifont.css">
<link rel="stylesheet" href="css/animation.css"><!--[if IE 7]><link rel="stylesheet" href="css/ifont-ie7.css"><![endif]-->
<script>
function toggleCodes(on) {
var obj = document.getElementById('icons');
if (on) {
obj.className += ' codesOn';
} else {
obj.className = obj.className.replace(' codesOn', '');
}
}
</script>
</head>
<body>
<div class="container header">
<h1>
ifont
<small>font demo</small>
</h1>
<label class="switch">
<input type="checkbox" onclick="toggleCodes(this.checked)">show codes
</label>
</div>
<div id="icons" class="container">
<div class="row">
<div title="Code: 0xe800" class="the-icons span3"><i class="icon-dashboard"></i> <span class="i-name">icon-dashboard</span><span class="i-code">0xe800</span></div>
<div title="Code: 0xe801" class="the-icons span3"><i class="icon-user"></i> <span class="i-name">icon-user</span><span class="i-code">0xe801</span></div>
<div title="Code: 0xe802" class="the-icons span3"><i class="icon-users"></i> <span class="i-name">icon-users</span><span class="i-code">0xe802</span></div>
<div title="Code: 0xe803" class="the-icons span3"><i class="icon-ok"></i> <span class="i-name">icon-ok</span><span class="i-code">0xe803</span></div>
</div>
<div class="row">
<div title="Code: 0xe804" class="the-icons span3"><i class="icon-cancel"></i> <span class="i-name">icon-cancel</span><span class="i-code">0xe804</span></div>
<div title="Code: 0xe805" class="the-icons span3"><i class="icon-plus"></i> <span class="i-name">icon-plus</span><span class="i-code">0xe805</span></div>
<div title="Code: 0xe806" class="the-icons span3"><i class="icon-minus"></i> <span class="i-name">icon-minus</span><span class="i-code">0xe806</span></div>
<div title="Code: 0xe807" class="the-icons span3"><i class="icon-folder-empty"></i> <span class="i-name">icon-folder-empty</span><span class="i-code">0xe807</span></div>
</div>
<div class="row">
<div title="Code: 0xe808" class="the-icons span3"><i class="icon-download"></i> <span class="i-name">icon-download</span><span class="i-code">0xe808</span></div>
<div title="Code: 0xe809" class="the-icons span3"><i class="icon-upload"></i> <span class="i-name">icon-upload</span><span class="i-code">0xe809</span></div>
<div title="Code: 0xe80a" class="the-icons span3"><i class="icon-git"></i> <span class="i-name">icon-git</span><span class="i-code">0xe80a</span></div>
<div title="Code: 0xe80b" class="the-icons span3"><i class="icon-cubes"></i> <span class="i-name">icon-cubes</span><span class="i-code">0xe80b</span></div>
</div>
<div class="row">
<div title="Code: 0xe80c" class="the-icons span3"><i class="icon-database"></i> <span class="i-name">icon-database</span><span class="i-code">0xe80c</span></div>
<div title="Code: 0xe80d" class="the-icons span3"><i class="icon-gauge"></i> <span class="i-name">icon-gauge</span><span class="i-code">0xe80d</span></div>
<div title="Code: 0xe80e" class="the-icons span3"><i class="icon-sitemap"></i> <span class="i-name">icon-sitemap</span><span class="i-code">0xe80e</span></div>
<div title="Code: 0xe80f" class="the-icons span3"><i class="icon-sort-name-up"></i> <span class="i-name">icon-sort-name-up</span><span class="i-code">0xe80f</span></div>
</div>
<div class="row">
<div title="Code: 0xe810" class="the-icons span3"><i class="icon-sort-name-down"></i> <span class="i-name">icon-sort-name-down</span><span class="i-code">0xe810</span></div>
<div title="Code: 0xe811" class="the-icons span3"><i class="icon-megaphone"></i> <span class="i-name">icon-megaphone</span><span class="i-code">0xe811</span></div>
<div title="Code: 0xe812" class="the-icons span3"><i class="icon-bug"></i> <span class="i-name">icon-bug</span><span class="i-code">0xe812</span></div>
<div title="Code: 0xe813" class="the-icons span3"><i class="icon-tasks"></i> <span class="i-name">icon-tasks</span><span class="i-code">0xe813</span></div>
</div>
<div class="row">
<div title="Code: 0xe814" class="the-icons span3"><i class="icon-filter"></i> <span class="i-name">icon-filter</span><span class="i-code">0xe814</span></div>
<div title="Code: 0xe815" class="the-icons span3"><i class="icon-off"></i> <span class="i-name">icon-off</span><span class="i-code">0xe815</span></div>
<div title="Code: 0xe816" class="the-icons span3"><i class="icon-book"></i> <span class="i-name">icon-book</span><span class="i-code">0xe816</span></div>
<div title="Code: 0xe817" class="the-icons span3"><i class="icon-paste"></i> <span class="i-name">icon-paste</span><span class="i-code">0xe817</span></div>
</div>
<div class="row">
<div title="Code: 0xe818" class="the-icons span3"><i class="icon-scissors"></i> <span class="i-name">icon-scissors</span><span class="i-code">0xe818</span></div>
<div title="Code: 0xe819" class="the-icons span3"><i class="icon-globe"></i> <span class="i-name">icon-globe</span><span class="i-code">0xe819</span></div>
<div title="Code: 0xe81a" class="the-icons span3"><i class="icon-cloud"></i> <span class="i-name">icon-cloud</span><span class="i-code">0xe81a</span></div>
<div title="Code: 0xe81b" class="the-icons span3"><i class="icon-flash"></i> <span class="i-name">icon-flash</span><span class="i-code">0xe81b</span></div>
</div>
<div class="row">
<div title="Code: 0xe81c" class="the-icons span3"><i class="icon-service"></i> <span class="i-name">icon-service</span><span class="i-code">0xe81c</span></div>
<div title="Code: 0xe81d" class="the-icons span3"><i class="icon-down-dir"></i> <span class="i-name">icon-down-dir</span><span class="i-code">0xe81d</span></div>
<div title="Code: 0xe81e" class="the-icons span3"><i class="icon-up-dir"></i> <span class="i-name">icon-up-dir</span><span class="i-code">0xe81e</span></div>
<div title="Code: 0xe81f" class="the-icons span3"><i class="icon-left-dir"></i> <span class="i-name">icon-left-dir</span><span class="i-code">0xe81f</span></div>
</div>
<div class="row">
<div title="Code: 0xe820" class="the-icons span3"><i class="icon-right-dir"></i> <span class="i-name">icon-right-dir</span><span class="i-code">0xe820</span></div>
<div title="Code: 0xe821" class="the-icons span3"><i class="icon-down-open"></i> <span class="i-name">icon-down-open</span><span class="i-code">0xe821</span></div>
<div title="Code: 0xe822" class="the-icons span3"><i class="icon-right-open"></i> <span class="i-name">icon-right-open</span><span class="i-code">0xe822</span></div>
<div title="Code: 0xe823" class="the-icons span3"><i class="icon-up-open"></i> <span class="i-name">icon-up-open</span><span class="i-code">0xe823</span></div>
</div>
<div class="row">
<div title="Code: 0xe824" class="the-icons span3"><i class="icon-left-open"></i> <span class="i-name">icon-left-open</span><span class="i-code">0xe824</span></div>
<div title="Code: 0xe825" class="the-icons span3"><i class="icon-up-big"></i> <span class="i-name">icon-up-big</span><span class="i-code">0xe825</span></div>
<div title="Code: 0xe826" class="the-icons span3"><i class="icon-right-big"></i> <span class="i-name">icon-right-big</span><span class="i-code">0xe826</span></div>
<div title="Code: 0xe827" class="the-icons span3"><i class="icon-left-big"></i> <span class="i-name">icon-left-big</span><span class="i-code">0xe827</span></div>
</div>
<div class="row">
<div title="Code: 0xe828" class="the-icons span3"><i class="icon-down-big"></i> <span class="i-name">icon-down-big</span><span class="i-code">0xe828</span></div>
<div title="Code: 0xe829" class="the-icons span3"><i class="icon-resize-full-alt"></i> <span class="i-name">icon-resize-full-alt</span><span class="i-code">0xe829</span></div>
<div title="Code: 0xe82a" class="the-icons span3"><i class="icon-resize-full"></i> <span class="i-name">icon-resize-full</span><span class="i-code">0xe82a</span></div>
<div title="Code: 0xe82b" class="the-icons span3"><i class="icon-resize-small"></i> <span class="i-name">icon-resize-small</span><span class="i-code">0xe82b</span></div>
</div>
<div class="row">
<div title="Code: 0xe82c" class="the-icons span3"><i class="icon-move"></i> <span class="i-name">icon-move</span><span class="i-code">0xe82c</span></div>
<div title="Code: 0xe82d" class="the-icons span3"><i class="icon-resize-horizontal"></i> <span class="i-name">icon-resize-horizontal</span><span class="i-code">0xe82d</span></div>
<div title="Code: 0xe82e" class="the-icons span3"><i class="icon-resize-vertical"></i> <span class="i-name">icon-resize-vertical</span><span class="i-code">0xe82e</span></div>
<div title="Code: 0xe82f" class="the-icons span3"><i class="icon-zoom-in"></i> <span class="i-name">icon-zoom-in</span><span class="i-code">0xe82f</span></div>
</div>
<div class="row">
<div title="Code: 0xe830" class="the-icons span3"><i class="icon-block"></i> <span class="i-name">icon-block</span><span class="i-code">0xe830</span></div>
<div title="Code: 0xe831" class="the-icons span3"><i class="icon-zoom-out"></i> <span class="i-name">icon-zoom-out</span><span class="i-code">0xe831</span></div>
<div title="Code: 0xe832" class="the-icons span3"><i class="icon-lightbulb"></i> <span class="i-name">icon-lightbulb</span><span class="i-code">0xe832</span></div>
<div title="Code: 0xe833" class="the-icons span3"><i class="icon-clock"></i> <span class="i-name">icon-clock</span><span class="i-code">0xe833</span></div>
</div>
<div class="row">
<div title="Code: 0xe834" class="the-icons span3"><i class="icon-volume-up"></i> <span class="i-name">icon-volume-up</span><span class="i-code">0xe834</span></div>
<div title="Code: 0xe835" class="the-icons span3"><i class="icon-volume-down"></i> <span class="i-name">icon-volume-down</span><span class="i-code">0xe835</span></div>
<div title="Code: 0xe836" class="the-icons span3"><i class="icon-volume-off"></i> <span class="i-name">icon-volume-off</span><span class="i-code">0xe836</span></div>
<div title="Code: 0xe837" class="the-icons span3"><i class="icon-mute"></i> <span class="i-name">icon-mute</span><span class="i-code">0xe837</span></div>
</div>
<div class="row">
<div title="Code: 0xe838" class="the-icons span3"><i class="icon-mic"></i> <span class="i-name">icon-mic</span><span class="i-code">0xe838</span></div>
<div title="Code: 0xe839" class="the-icons span3"><i class="icon-endtime"></i> <span class="i-name">icon-endtime</span><span class="i-code">0xe839</span></div>
<div title="Code: 0xe83a" class="the-icons span3"><i class="icon-starttime"></i> <span class="i-name">icon-starttime</span><span class="i-code">0xe83a</span></div>
<div title="Code: 0xe83b" class="the-icons span3"><i class="icon-calendar-empty"></i> <span class="i-name">icon-calendar-empty</span><span class="i-code">0xe83b</span></div>
</div>
<div class="row">
<div title="Code: 0xe83c" class="the-icons span3"><i class="icon-calendar"></i> <span class="i-name">icon-calendar</span><span class="i-code">0xe83c</span></div>
<div title="Code: 0xe83d" class="the-icons span3"><i class="icon-wrench"></i> <span class="i-name">icon-wrench</span><span class="i-code">0xe83d</span></div>
<div title="Code: 0xe83e" class="the-icons span3"><i class="icon-sliders"></i> <span class="i-name">icon-sliders</span><span class="i-code">0xe83e</span></div>
<div title="Code: 0xe83f" class="the-icons span3"><i class="icon-conf-alt"></i> <span class="i-name">icon-conf-alt</span><span class="i-code">0xe83f</span></div>
</div>
<div class="row">
<div title="Code: 0xe840" class="the-icons span3"><i class="icon-conf"></i> <span class="i-name">icon-conf</span><span class="i-code">0xe840</span></div>
<div title="Code: 0xe841" class="the-icons span3"><i class="icon-phone"></i> <span class="i-name">icon-phone</span><span class="i-code">0xe841</span></div>
<div title="Code: 0xe842" class="the-icons span3"><i class="icon-file-pdf"></i> <span class="i-name">icon-file-pdf</span><span class="i-code">0xe842</span></div>
<div title="Code: 0xe843" class="the-icons span3"><i class="icon-file-word"></i> <span class="i-name">icon-file-word</span><span class="i-code">0xe843</span></div>
</div>
<div class="row">
<div title="Code: 0xe844" class="the-icons span3"><i class="icon-file-excel"></i> <span class="i-name">icon-file-excel</span><span class="i-code">0xe844</span></div>
<div title="Code: 0xe845" class="the-icons span3"><i class="icon-doc-text"></i> <span class="i-name">icon-doc-text</span><span class="i-code">0xe845</span></div>
<div title="Code: 0xe846" class="the-icons span3"><i class="icon-trash"></i> <span class="i-name">icon-trash</span><span class="i-code">0xe846</span></div>
<div title="Code: 0xe847" class="the-icons span3"><i class="icon-comment-empty"></i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xe847</span></div>
</div>
<div class="row">
<div title="Code: 0xe848" class="the-icons span3"><i class="icon-comment"></i> <span class="i-name">icon-comment</span><span class="i-code">0xe848</span></div>
<div title="Code: 0xe849" class="the-icons span3"><i class="icon-chat"></i> <span class="i-name">icon-chat</span><span class="i-code">0xe849</span></div>
<div title="Code: 0xe84a" class="the-icons span3"><i class="icon-chat-empty"></i> <span class="i-name">icon-chat-empty</span><span class="i-code">0xe84a</span></div>
<div title="Code: 0xe84b" class="the-icons span3"><i class="icon-bell"></i> <span class="i-name">icon-bell</span><span class="i-code">0xe84b</span></div>
</div>
<div class="row">
<div title="Code: 0xe84c" class="the-icons span3"><i class="icon-bell-alt"></i> <span class="i-name">icon-bell-alt</span><span class="i-code">0xe84c</span></div>
<div title="Code: 0xe84d" class="the-icons span3"><i class="icon-attention-alt"></i> <span class="i-name">icon-attention-alt</span><span class="i-code">0xe84d</span></div>
<div title="Code: 0xe84e" class="the-icons span3"><i class="icon-print"></i> <span class="i-name">icon-print</span><span class="i-code">0xe84e</span></div>
<div title="Code: 0xe84f" class="the-icons span3"><i class="icon-edit"></i> <span class="i-name">icon-edit</span><span class="i-code">0xe84f</span></div>
</div>
<div class="row">
<div title="Code: 0xe850" class="the-icons span3"><i class="icon-forward"></i> <span class="i-name">icon-forward</span><span class="i-code">0xe850</span></div>
<div title="Code: 0xe851" class="the-icons span3"><i class="icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xe851</span></div>
<div title="Code: 0xe852" class="the-icons span3"><i class="icon-reply-all"></i> <span class="i-name">icon-reply-all</span><span class="i-code">0xe852</span></div>
<div title="Code: 0xe853" class="the-icons span3"><i class="icon-eye"></i> <span class="i-name">icon-eye</span><span class="i-code">0xe853</span></div>
</div>
<div class="row">
<div title="Code: 0xe854" class="the-icons span3"><i class="icon-tag"></i> <span class="i-name">icon-tag</span><span class="i-code">0xe854</span></div>
<div title="Code: 0xe855" class="the-icons span3"><i class="icon-tags"></i> <span class="i-name">icon-tags</span><span class="i-code">0xe855</span></div>
<div title="Code: 0xe856" class="the-icons span3"><i class="icon-lock-open-alt"></i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xe856</span></div>
<div title="Code: 0xe857" class="the-icons span3"><i class="icon-lock-open"></i> <span class="i-name">icon-lock-open</span><span class="i-code">0xe857</span></div>
</div>
<div class="row">
<div title="Code: 0xe858" class="the-icons span3"><i class="icon-lock"></i> <span class="i-name">icon-lock</span><span class="i-code">0xe858</span></div>
<div title="Code: 0xe859" class="the-icons span3"><i class="icon-home"></i> <span class="i-name">icon-home</span><span class="i-code">0xe859</span></div>
<div title="Code: 0xe85a" class="the-icons span3"><i class="icon-info"></i> <span class="i-name">icon-info</span><span class="i-code">0xe85a</span></div>
<div title="Code: 0xe85b" class="the-icons span3"><i class="icon-help"></i> <span class="i-name">icon-help</span><span class="i-code">0xe85b</span></div>
</div>
<div class="row">
<div title="Code: 0xe85c" class="the-icons span3"><i class="icon-search"></i> <span class="i-name">icon-search</span><span class="i-code">0xe85c</span></div>
<div title="Code: 0xe85d" class="the-icons span3"><i class="icon-flapping"></i> <span class="i-name">icon-flapping</span><span class="i-code">0xe85d</span></div>
<div title="Code: 0xe85e" class="the-icons span3"><i class="icon-rewind"></i> <span class="i-name">icon-rewind</span><span class="i-code">0xe85e</span></div>
<div title="Code: 0xe85f" class="the-icons span3"><i class="icon-chart-line"></i> <span class="i-name">icon-chart-line</span><span class="i-code">0xe85f</span></div>
</div>
<div class="row">
<div title="Code: 0xe860" class="the-icons span3"><i class="icon-bell-off"></i> <span class="i-name">icon-bell-off</span><span class="i-code">0xe860</span></div>
<div title="Code: 0xe861" class="the-icons span3"><i class="icon-bell-off-empty"></i> <span class="i-name">icon-bell-off-empty</span><span class="i-code">0xe861</span></div>
<div title="Code: 0xe862" class="the-icons span3"><i class="icon-plug"></i> <span class="i-name">icon-plug</span><span class="i-code">0xe862</span></div>
<div title="Code: 0xe863" class="the-icons span3"><i class="icon-eye-off"></i> <span class="i-name">icon-eye-off</span><span class="i-code">0xe863</span></div>
</div>
<div class="row">
<div title="Code: 0xe864" class="the-icons span3"><i class="icon-reschedule"></i> <span class="i-name">icon-reschedule</span><span class="i-code">0xe864</span></div>
<div title="Code: 0xe865" class="the-icons span3"><i class="icon-cw"></i> <span class="i-name">icon-cw</span><span class="i-code">0xe865</span></div>
<div title="Code: 0xe866" class="the-icons span3"><i class="icon-host"></i> <span class="i-name">icon-host</span><span class="i-code">0xe866</span></div>
<div title="Code: 0xe867" class="the-icons span3"><i class="icon-thumbs-up"></i> <span class="i-name">icon-thumbs-up</span><span class="i-code">0xe867</span></div>
</div>
<div class="row">
<div title="Code: 0xe868" class="the-icons span3"><i class="icon-thumbs-down"></i> <span class="i-name">icon-thumbs-down</span><span class="i-code">0xe868</span></div>
</div>
</div>
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
</body>
</html>

Binary file not shown.

View File

@ -0,0 +1,116 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
<defs>
<font id="ifont" horiz-adv-x="1000" >
<font-face font-family="ifont" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="dashboard" unicode="&#xe800;" d="m286 154v-108q0-22-16-37t-38-16h-178q-23 0-38 16t-16 37v108q0 22 16 38t38 15h178q22 0 38-15t16-38z m0 285v-107q0-22-16-38t-38-15h-178q-23 0-38 15t-16 38v107q0 23 16 38t38 16h178q22 0 38-16t16-38z m357-285v-108q0-22-16-37t-38-16h-178q-23 0-38 16t-16 37v108q0 22 16 38t38 15h178q23 0 38-15t16-38z m-357 571v-107q0-22-16-38t-38-16h-178q-23 0-38 16t-16 38v107q0 22 16 38t38 16h178q22 0 38-16t16-38z m357-286v-107q0-22-16-38t-38-15h-178q-23 0-38 15t-16 38v107q0 23 16 38t38 16h178q23 0 38-16t16-38z m357-285v-108q0-22-16-37t-38-16h-178q-22 0-38 16t-16 37v108q0 22 16 38t38 15h178q23 0 38-15t16-38z m-357 571v-107q0-22-16-38t-38-16h-178q-23 0-38 16t-16 38v107q0 22 16 38t38 16h178q23 0 38-16t16-38z m357-286v-107q0-22-16-38t-38-15h-178q-22 0-38 15t-16 38v107q0 23 16 38t38 16h178q23 0 38-16t16-38z m0 286v-107q0-22-16-38t-38-16h-178q-22 0-38 16t-16 38v107q0 22 16 38t38 16h178q23 0 38-16t16-38z" horiz-adv-x="1000" />
<glyph glyph-name="user" unicode="&#xe801;" d="m786 66q0-67-41-106t-108-39h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q5 0 24-12t41-27 60-27 75-12 74 12 61 27 41 27 24 12q34 0 62-11t48-30 34-45 24-55 15-60 8-61 2-58z m-179 498q0-88-63-151t-151-63-152 63-62 151 62 152 152 63 151-63 63-152z" horiz-adv-x="785.7" />
<glyph glyph-name="users" unicode="&#xe802;" d="m331 350q-90-3-148-71h-75q-45 0-77 22t-31 66q0 197 69 197 4 0 25-11t54-24 66-12q38 0 75 13-3-21-3-37 0-78 45-143z m598-356q0-66-41-105t-108-39h-488q-68 0-108 39t-41 105q0 30 2 58t8 61 14 61 24 54 35 45 48 30 62 11q6 0 24-12t41-26 59-27 76-12 75 12 60 27 41 26 23 12q35 0 63-11t47-30 35-45 24-54 15-61 8-61 2-58z m-572 713q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z m393-214q0-89-63-152t-151-62-152 62-63 152 63 151 152 63 151-63 63-151z m321-126q0-43-31-66t-77-22h-75q-57 68-147 71 45 65 45 143 0 16-3 37 37-13 74-13 33 0 67 12t54 24 24 11q69 0 69-197z m-71 340q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z" horiz-adv-x="1071.4" />
<glyph glyph-name="ok" unicode="&#xe803;" d="m352-10l-334 333 158 160 176-174 400 401 159-160z" horiz-adv-x="928" />
<glyph glyph-name="cancel" unicode="&#xe804;" d="m799 116l-156-157-234 235-235-235-156 157 234 234-234 234 156 157 235-235 234 235 156-157-234-234z" horiz-adv-x="817" />
<glyph glyph-name="plus" unicode="&#xe805;" d="m911 462l0-223-335 0 0-336-223 0 0 336-335 0 0 223 335 0 0 335 223 0 0-335 335 0z" horiz-adv-x="928" />
<glyph glyph-name="minus" unicode="&#xe806;" d="m18 239l0 223 893 0 0-223-893 0z" horiz-adv-x="928" />
<glyph glyph-name="folder-empty" unicode="&#xe807;" d="m464 685l447 0 0-669q0-47-33-80t-79-33l-669 0q-46 0-79 33t-33 80l0 781 446 0 0-112z m-334 0l0-223 669 0 0 112-446 0 0 111-223 0z m669-669l0 335-669 0 0-335 669 0z" horiz-adv-x="928" />
<glyph glyph-name="download" unicode="&#xe808;" d="m714 100q0 15-10 25t-25 11-26-11-10-25 10-25 26-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-40l-250-250q-10-10-25-10t-25 10l-250 250q-17 17-8 40 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" />
<glyph glyph-name="upload" unicode="&#xe809;" d="m714 29q0 14-10 25t-25 10-26-10-10-25 10-26 26-10 25 10 10 26z m143 0q0 14-10 25t-26 10-25-10-10-25 10-26 25-10 26 10 10 26z m72 125v-179q0-22-16-38t-38-16h-821q-23 0-38 16t-16 38v179q0 22 16 38t38 15h238q12-31 39-51t62-20h143q34 0 61 20t40 51h238q22 0 38-15t16-38z m-182 361q-9-22-33-22h-143v-250q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v250h-143q-23 0-33 22-9 22 8 39l250 250q10 10 25 10t25-10l250-250q18-17 8-39z" horiz-adv-x="928.6" />
<glyph glyph-name="git" unicode="&#xe80a;" d="m332 5q0 56-92 56-88 0-88-58 0-57 96-57 84 0 84 59z m-33 421q0 35-17 57t-49 23q-69 0-69-81 0-75 69-75 66 0 66 76z m150 181v-112q-20-7-44-13 9-24 9-47 0-70-41-120t-110-63q-22-5-33-15t-11-33q0-17 13-28t32-18 44-12 48-15 44-21 32-35 13-55q0-170-203-170-38 0-72 7t-65 23-49 46-18 71q0 92 102 125v3q-38 22-38 70 0 61 35 76v3q-40 13-66 60t-27 92q0 78 53 130t131 51q54 0 100-26 54 0 121 26z m178-491h-124q2 25 2 74v340q0 53-2 72h124q-3-19-3-70v-342q0-49 3-74z m335 124v-110q-40-22-97-22-35 0-60 12t-39 27-22 44-10 51-2 58v196h1v2q-4 0-11 0t-10 1q-12 0-33-3v106h54v42q0 30-4 50h127q-3-23-3-92h95v-106q-8 0-24 1t-24 1h-47v-204q0-73 48-73 34 0 61 19z m-321 528q0-32-22-57t-54-24q-32 0-54 24t-23 57q0 33 22 57t55 25q33 0 54-25t22-57z" horiz-adv-x="1000" />
<glyph glyph-name="cubes" unicode="&#xe80b;" d="m357-61l214 107v176l-214-92v-191z m-36 254l226 96-226 97-225-97z m608-254l214 107v176l-214-92v-191z m-36 254l225 96-225 97-226-97z m-250 163l214 92v149l-214-92v-149z m-36 212l246 105-246 106-246-106z m607-289v-233q0-20-10-37t-29-26l-250-125q-14-8-32-8t-32 8l-250 125q-3 1-4 2-1-1-4-2l-250-125q-14-8-32-8t-31 8l-250 125q-19 9-29 26t-11 37v233q0 21 12 39t32 26l242 104v223q0 22 12 39t31 27l250 107q13 6 28 6t28-6l250-107q20-9 32-27t12-39v-223l242-104q20-9 32-26t11-40z" horiz-adv-x="1285.7" />
<glyph glyph-name="database" unicode="&#xe80c;" d="m429 421q132 0 247 24t181 71v-95q0-38-57-71t-157-52-214-20-215 20-156 52-58 71v95q66-47 181-71t248-24z m0-428q132 0 247 24t181 71v-95q0-39-57-72t-157-52-214-19-215 19-156 52-58 72v95q66-47 181-71t248-24z m0 214q132 0 247 24t181 71v-95q0-38-57-71t-157-52-214-20-215 20-156 52-58 71v95q66-47 181-71t248-24z m0 643q116 0 214-19t157-52 57-72v-71q0-39-57-72t-157-52-214-19-215 19-156 52-58 72v71q0 39 58 72t156 52 215 19z" horiz-adv-x="857.1" />
<glyph glyph-name="gauge" unicode="&#xe80d;" d="m214 207q0 30-21 51t-50 21-51-21-21-51 21-50 51-21 50 21 21 50z m107 250q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m239-268l57 213q3 14-5 27t-21 16-27-3-17-22l-56-213q-33-3-60-25t-35-55q-11-43 11-81t66-50 81 11 50 66q9 33-4 65t-40 51z m369 18q0 30-21 51t-51 21-50-21-21-51 21-50 50-21 51 21 21 50z m-358 357q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m250-107q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m179-250q0-145-79-269-10-17-30-17h-782q-20 0-30 17-79 123-79 269 0 102 40 194t106 160 160 107 194 39 194-39 160-107 106-160 40-194z" horiz-adv-x="1000" />
<glyph glyph-name="sitemap" unicode="&#xe80e;" d="m1000 154v-179q0-22-16-38t-38-16h-178q-22 0-38 16t-16 38v179q0 22 16 38t38 15h53v107h-285v-107h53q23 0 38-15t16-38v-179q0-22-16-38t-38-16h-178q-23 0-38 16t-16 38v179q0 22 16 38t38 15h53v107h-285v-107h53q22 0 38-15t16-38v-179q0-22-16-38t-38-16h-178q-23 0-38 16t-16 38v179q0 22 16 38t38 15h53v107q0 29 21 51t51 21h285v107h-53q-23 0-38 15t-16 38v179q0 22 16 38t38 16h178q23 0 38-16t16-38v-179q0-22-16-38t-38-15h-53v-107h285q29 0 51-21t21-51v-107h53q23 0 38-15t16-38z" horiz-adv-x="1000" />
<glyph glyph-name="sort-name-up" unicode="&#xe80f;" d="m665 622h98l-40 122-6 26q-2 9-2 11h-2l-2-11q0 0-1-10t-5-16z m-254-576q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m466-66v-130h-326v50l206 295q7 10 12 16l6 5v1q-1 0-4 0t-4 0q-6-2-16-2h-130v-64h-67v128h317v-50l-206-296q-4-4-12-14l-6-7v-1l8 1q5 2 16 2h139v66h67z m50 501v-60h-161v60h42l-26 80h-136l-26-80h42v-60h-160v60h39l128 369h90l129-369h39z" horiz-adv-x="928.6" />
<glyph glyph-name="sort-name-down" unicode="&#xe810;" d="m665 51h98l-40 122-6 26q-2 9-2 11h-2l-2-11q0-1-1-10t-5-16z m-254-5q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m516-137v-59h-161v59h42l-26 80h-136l-26-80h42v-59h-160v59h39l128 370h90l129-370h39z m-50 642v-130h-326v51l206 295q7 10 12 15l6 5v2q-1 0-4-1t-4 0q-6-2-16-2h-130v-64h-67v128h317v-50l-206-295q-4-5-12-15l-6-6v-1l8 1q5 1 16 1h139v66h67z" horiz-adv-x="928.6" />
<glyph glyph-name="megaphone" unicode="&#xe811;" d="m929 493q29 0 50-21t21-51-21-50-50-21v-214q0-29-22-50t-50-22q-233 194-453 212-32-10-51-36t-17-57 22-51q-11-19-13-37t4-32 18-31 27-28 35-28q-17-32-63-46t-94-7-73 31q-4 13-17 49t-18 53-12 50-9 56 2 55 12 62h-68q-36 0-63 26t-26 63v107q0 37 26 63t63 26h268q243 0 500 215 29 0 50-22t22-50v-214z m-72-337v532q-220-168-428-191v-151q210-23 428-190z" horiz-adv-x="1000" />
<glyph glyph-name="bug" unicode="&#xe812;" d="m911 314q0-14-11-25t-25-10h-125q0-96-37-162l116-117q10-11 10-25t-10-25q-10-11-25-11t-26 11l-110 110q-3-3-8-7t-24-16-36-21-46-16-54-7v500h-71v-500q-29 0-57 7t-49 19-36 22-25 18l-8 8-102-116q-11-12-27-12-13 0-24 9-11 10-11 25t8 26l113 127q-32 63-32 153h-125q-15 0-25 10t-11 25 11 25 25 11h125v164l-97 97q-11 10-11 25t11 25 25 10 25-10l97-97h471l96 97q11 10 25 10t26-10 10-25-10-25l-97-97v-164h125q15 0 25-11t11-25z m-268 322h-357q0 74 52 126t126 52 127-52 52-126z" horiz-adv-x="928.6" />
<glyph glyph-name="tasks" unicode="&#xe813;" d="m571 64h358v72h-358v-72z m-214 286h572v71h-572v-71z m357 286h215v71h-215v-71z m286-465v-142q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v142q0 15 11 26t25 10h928q15 0 25-10t11-26z m0 286v-143q0-14-11-25t-25-10h-928q-15 0-25 10t-11 25v143q0 15 11 25t25 11h928q15 0 25-11t11-25z m0 286v-143q0-15-11-25t-25-11h-928q-15 0-25 11t-11 25v143q0 14 11 25t25 11h928q15 0 25-11t11-25z" horiz-adv-x="1000" />
<glyph glyph-name="filter" unicode="&#xe814;" d="m783 685q9-23-8-39l-275-275v-414q0-23-22-33-7-3-14-3-15 0-25 11l-143 143q-10 10-10 25v271l-275 275q-18 16-8 39 9 22 33 22h714q23 0 33-22z" horiz-adv-x="785.7" />
<glyph glyph-name="off" unicode="&#xe815;" d="m857 350q0-87-34-166t-91-137-137-92-166-34-167 34-136 92-92 137-34 166q0 102 45 191t126 151q24 18 54 14t46-28q18-23 14-53t-28-47q-54-41-84-101t-30-127q0-58 22-111t62-91 91-61 111-23 110 23 92 61 61 91 22 111q0 68-30 127t-84 101q-24 18-28 47t14 53q17 24 47 28t53-14q81-61 126-151t45-191z m-357 429v-358q0-29-21-50t-50-21-51 21-21 50v358q0 29 21 50t51 21 50-21 21-50z" horiz-adv-x="857.1" />
<glyph glyph-name="book" unicode="&#xe816;" d="m915 583q22-32 10-72l-154-505q-10-36-42-60t-69-25h-515q-43 0-83 30t-55 74q-14 37-1 71 0 2 1 15t3 20q0 5-2 12t-2 11q1 6 5 12t9 13 9 13q13 21 25 51t17 51q2 6 0 17t0 16q2 6 9 15t10 13q12 20 23 51t14 51q1 5-1 17t0 16q2 7 12 17t13 13q10 14 23 47t16 54q0 4-2 14t-1 15q1 4 5 10t10 13 10 11q4 7 9 17t8 20 9 20 11 18 15 13 20 6 26-3l0-1q21 5 28 5h425q41 0 63-32t10-72l-152-506q-20-66-40-85t-72-20h-485q-15 0-21-8-6-9-1-24 14-39 81-39h515q16 0 31 9t19 23l168 550q4 13 3 32 21-8 33-24z m-594-1q-2-7 1-12t11-6h339q8 0 15 6t9 12l12 36q2 7-2 12t-11 6h-339q-7 0-14-6t-9-12z m-46-143q-3-7 1-12t11-6h339q7 0 14 6t10 12l11 36q3 7-1 13t-11 5h-339q-8 0-14-5t-10-13z" horiz-adv-x="928.6" />
<glyph glyph-name="paste" unicode="&#xe817;" d="m429-79h500v358h-233q-22 0-38 15t-15 38v232h-214v-643z m142 804v36q0 7-5 12t-12 6h-393q-7 0-13-6t-5-12v-36q0-7 5-13t13-5h393q7 0 12 5t5 13z m143-375h167l-167 167v-167z m286-71v-375q0-23-16-38t-38-16h-535q-23 0-38 16t-16 38v89h-303q-23 0-38 16t-16 37v750q0 23 16 38t38 16h607q22 0 38-16t15-38v-183q12-7 20-15l228-228q16-16 27-42t11-50z" horiz-adv-x="1000" />
<glyph glyph-name="scissors" unicode="&#xe818;" d="m536 350q14 0 25-11t10-25-10-25-25-10-25 10-11 25 11 25 25 11z m167-36l283-222q16-11 14-31-3-20-20-28l-71-36q-7-4-16-4-10 0-17 4l-385 216-62-37q-4-2-7-2 8-28 6-54-4-43-31-83t-74-69q-74-47-154-47-76 0-124 44-51 47-44 116 4 42 31 82t73 69q74 47 155 47 46 0 84-18 5 8 13 13l68 40-68 41q-8 5-13 12-38-17-84-17-81 0-155 47-46 29-73 69t-31 82q-3 33 8 63t36 52q47 44 124 44 80 0 154-47 46-29 74-68t31-83q2-27-6-54 3-1 7-3l62-37 385 216q7 5 17 5 9 0 16-4l71-36q17-9 20-28 2-20-14-32z m-380 145q26 24 12 61t-59 65q-52 33-107 33-42 0-63-20-26-24-12-60t59-66q51-33 107-33 41 0 63 20z m-47-415q45 28 59 65t-12 60q-22 20-63 20-56 0-107-33-45-28-59-65t12-60q21-20 63-20 55 0 107 33z m99 342l54-33v7q0 20 18 31l8 4-44 26-15-14q-1-2-5-6t-7-7q-1-1-2-2t-2-1z m125-125l54-18 410 321-71 36-429-240v-64l-89-53 5-5q1-1 4-3 2-2 6-7t6-6l15-15z m393-232l71 35-290 228-99-77q-1-2-7-4z" horiz-adv-x="1000" />
<glyph glyph-name="globe" unicode="&#xe819;" d="m429 779q116 0 215-58t156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58z m152-291q-1-1-5-5t-7-6q1 0 2 3t3 6 2 4q3 4 12 8 8 4 29 7 19 5 29-6-1 1 5 7t8 7q2 1 8 2t9 5l1 12q-7-1-10 4t-3 12q0-2-4-5 0 4-2 5t-7-1-5-1q-5 2-8 5t-5 9-2 8q-1 3-5 6t-5 6q-1 1-2 3t-2 4-2 3-3 1-4-3-4-5-2-3q-2 1-4 1t-2-1-3-2-3-2q-1-1-4-1t-5-1q8 3-1 6-5 2-9 1 5 3 5 7t-5 8h3q-1 2-5 5t-10 4-7 4q-5 3-19 5t-18 0q-3-3-3-5t2-8 2-7q1-4-3-7t-3-7q0-4 7-9t6-12q-2-4-9-9t-9-6q-3-5-1-11t6-9q1-1 1-2t-2-3-3-2-4-2l-1-1q-7-3-12 3t-7 15q-4 14-9 17-13 4-17-1-2 7-22 15-14 5-33 2 4 0 0 8-4 9-10 7 1 3 2 10t0 7q2 7 7 13 1 1 4 5t5 7 1 4q19-3 28 6 2 2 6 9t6 10q5 3 8 3t8-3 8-3q8-1 8 6t-4 11q7 0 2 10-3 4-5 5-6 2-15-3-4-2 2-4-1 0-6-6t-9-10-9 3q0 0-3 7t-5 8q-5 0-9-9 1 5-6 9t-14 4q11 7-4 15-4 3-12 3t-11-2q-2-4-3-7t3-4 6-3 6-2 5-2q8-6 5-8-1 0-5-2t-6-2-4-3q-2-2 0-7t-1-8q-3 3-5 10t-4 9q4-5-14-4l-5 1q-3 0-9-1t-12-1-7 5q-3 4 0 11 0 2 2 1-2 2-6 5t-6 5q-25-8-52-23 3 0 6 1 3 1 8 3t5 4q19 7 24 3l3 3q7-9 11-14-4 3-17 1-11-4-12-7 4-7 2-10-2 2-6 6t-8 6-8 3q-9 0-13-1-81-45-131-124 4-4 7-4 2-1 3-5t1-6 6 1q5-4 2-10 1 0 25-15 10-10 11-12 2-6-5-10-1 1-5 5t-5 2q-2-3 0-10t6-7q-4 0-5-9t-2-20 0-13l1-1q-2-6 3-19t12-11q-7-1 11-24 3-4 4-5 2-1 7-4t9-6 5-5q2-3 6-13t8-13q-2-3 5-11t6-13q-1 0-2-1t-1 0q2-4 9-8t8-7q1-2 1-6t2-6 4-1q2 11-13 34-8 14-9 17-2 2-4 8t-2 8q1 0 3 0t5-2 4-3 1-1q-1-4 1-10t7-10 10-11 6-7q4-4 8-11t0-8q5 0 11-5t10-11q3-5 4-15t3-13q1-4 5-8t7-5l9-5t7-3q3-2 10-6t12-7q6-2 9-2t8 1 8 2q8 1 16-8t12-12q20-10 30-6-1 0 1-4t4-9 5-8 3-5q3-3 10-8t10-8q4 2 4 5-1-5 4-11t10-6q8 2 8 18-17-9-27 10 0 0-2 3t-2 5-1 4 0 5 2 1q5 0 6 2t-1 7-2 8q-1 4-6 11t-7 8q-3-5-9-4t-9 5q0-1-1-3t-1-4q-7 0-8 0 1 2 1 10t2 13q1 2 3 6t5 9 2 7-3 5-9 1q-11 0-15-11-1-2-2-6t-2-6-5-4q-4-2-14-1t-13 3q-8 4-13 16t-5 20q0 6 1 15t2 14-3 14q2 1 5 5t5 6q2 1 3 1t2 0 3 1 1 3q0 1-2 2-2 1-2 1 4-1 16 1t15-1q9-6 12 1 0 1-1 6t0 7q3-15 16-5 2-1 9-3t9-2q2-1 4-3t3-3 3 0 5 4q5-8 7-13 6-23 10-25 4-2 6-1t3 5 0 8-1 7l-1 4v11l0 4q-8 2-10 7t0 10 9 10q0 1 4 2t9 4 7 4q12 11 8 20 4 0 6 5 0 0-2 2t-5 2-2 2q5 2 1 8 3 2 4 7t4 5q5-7 12-1 4 5 1 9 2 4 11 6t10 5q4-1 5 1t0 7 2 7q2 2 8 5t8 2l9 7q2 2 0 2 10-1 18 6 5 6-4 11 2 3-2 5t-8 3q2 1 7 1t5 1q9 5-4 9-9 2-24-7z m-90-490q114 21 195 106-1 2-7 2t-7 2q-10 4-13 5 1 4-1 7t-5 5-7 5-6 4q-1 1-4 3t-4 3-4 2-5 2-5-1l-2-1q-2 0-3-1t-3-2-2-1 0-2q-12 10-20 13-3 0-7 3t-5 4-6 0-6-4q-3-2-4-8t-1-7q-4 3 0 10t1 10q-1 3-6 2t-6-2-7-5-5-3-4-3-5-5q-2-2-4-6t-2-7q-1 3-7 4t-5 3q1-5 2-19t3-22q4-17-7-26-15-14-16-23-2-12 7-14 0-4-5-12t-4-12q0-3 2-9z" horiz-adv-x="857.1" />
<glyph glyph-name="cloud" unicode="&#xe81a;" d="m1071 207q0-89-62-151t-152-63h-607q-103 0-177 73t-73 177q0 74 40 135t104 91q-1 15-1 24 0 118 84 202t202 84q88 0 159-50t105-128q39 35 93 35 59 0 101-42t42-101q0-42-23-77 72-17 119-75t46-134z" horiz-adv-x="1071.4" />
<glyph glyph-name="flash" unicode="&#xe81b;" d="m494 534q10-11 4-24l-302-646q-7-14-23-14-2 0-8 1-9 3-14 11t-3 16l110 451-226-56q-2-1-7-1-10 0-17 7-10 8-7 21l112 461q2 8 9 13t15 5h183q11 0 18-7t7-17q0-4-2-10l-96-258 221 54q5 2 7 2 11 0 19-9z" horiz-adv-x="500" />
<glyph glyph-name="service" unicode="&#xe81c;" d="m143 46v-107q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v107q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 72v-179q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v179q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 143v-322q0-8-5-13t-12-5h-108q-7 0-12 5t-5 13v322q0 8 5 13t12 5h108q7 0 12-5t5-13z m215 214v-536q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v536q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 286v-822q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v822q0 8 5 13t13 5h107q8 0 13-5t5-13z" horiz-adv-x="1000" />
<glyph glyph-name="down-dir" unicode="&#xe81d;" d="m571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
<glyph glyph-name="up-dir" unicode="&#xe81e;" d="m571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
<glyph glyph-name="left-dir" unicode="&#xe81f;" d="m357 600v-500q0-14-10-25t-26-11-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11 10-25z" horiz-adv-x="357.1" />
<glyph glyph-name="right-dir" unicode="&#xe820;" d="m321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11-11 25v500q0 15 11 25t25 11 25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
<glyph glyph-name="down-open" unicode="&#xe821;" d="m939 399l-414-413q-10-11-25-11t-25 11l-414 413q-11 11-11 26t11 25l92 92q11 11 26 11t25-11l296-296 296 296q11 11 25 11t26-11l92-92q11-11 11-25t-11-26z" horiz-adv-x="1000" />
<glyph glyph-name="right-open" unicode="&#xe822;" d="m618 361l-414-415q-11-10-25-10t-26 10l-92 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l92 93q11 10 26 10t25-10l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
<glyph glyph-name="up-open" unicode="&#xe823;" d="m939 107l-92-92q-11-10-26-10t-25 10l-296 297-296-297q-11-10-25-10t-26 10l-92 92q-11 11-11 26t11 25l414 414q11 10 25 10t25-10l414-414q11-11 11-25t-11-26z" horiz-adv-x="1000" />
<glyph glyph-name="left-open" unicode="&#xe824;" d="m653 682l-296-296 296-297q11-10 11-25t-11-25l-92-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 10 25 10t25-10l92-93q11-10 11-25t-11-25z" horiz-adv-x="714.3" />
<glyph glyph-name="up-big" unicode="&#xe825;" d="m899 308q0-28-21-50l-42-42q-21-21-50-21-30 0-51 21l-164 164v-393q0-29-20-47t-51-19h-71q-30 0-51 19t-21 47v393l-164-164q-20-21-50-21t-50 21l-42 42q-21 21-21 50 0 30 21 51l363 363q20 21 50 21 30 0 51-21l363-363q21-22 21-51z" horiz-adv-x="928.6" />
<glyph glyph-name="right-big" unicode="&#xe826;" d="m821 314q0-30-20-50l-363-364q-22-20-51-20-29 0-50 20l-42 42q-22 21-22 51t22 51l163 163h-393q-29 0-47 21t-18 51v71q0 30 18 51t47 20h393l-163 164q-22 21-22 51t22 50l42 42q21 21 50 21 29 0 51-21l363-363q20-20 20-51z" horiz-adv-x="857.1" />
<glyph glyph-name="left-big" unicode="&#xe827;" d="m857 350v-71q0-30-18-51t-47-21h-393l164-164q21-20 21-50t-21-50l-42-43q-21-20-51-20-29 0-50 20l-364 364q-20 21-20 50 0 29 20 51l364 363q21 21 50 21 29 0 51-21l42-42q21-21 21-50t-21-51l-164-164h393q29 0 47-20t18-51z" horiz-adv-x="857.1" />
<glyph glyph-name="down-big" unicode="&#xe828;" d="m899 386q0-30-21-50l-363-364q-22-21-51-21-29 0-50 21l-363 364q-21 20-21 50 0 29 21 51l41 41q22 21 51 21 29 0 50-21l164-164v393q0 29 21 50t51 22h71q29 0 50-22t21-50v-393l164 164q21 21 51 21 29 0 50-21l42-42q21-21 21-50z" horiz-adv-x="928.6" />
<glyph glyph-name="resize-full-alt" unicode="&#xe829;" d="m716 548l-198-198 198-198 80 80q16 18 39 8 22-9 22-33v-250q0-14-10-25t-26-11h-250q-23 0-32 23-10 21 7 38l81 81-198 198-198-198 80-81q17-17 8-38-10-23-33-23h-250q-15 0-25 11t-11 25v250q0 24 22 33 22 10 39-8l80-80 198 198-198 198-80-80q-11-11-25-11-7 0-14 3-22 9-22 33v250q0 14 11 25t25 11h250q23 0 33-23 9-22-8-38l-80-81 198-198 198 198-81 81q-17 16-7 38 9 23 32 23h250q15 0 26-11t10-25v-250q0-24-22-33-7-3-14-3-14 0-25 11z" horiz-adv-x="857.1" />
<glyph glyph-name="resize-full" unicode="&#xe82a;" d="m421 261q0-8-5-13l-185-185 80-81q10-10 10-25t-10-25-25-11h-250q-15 0-25 11t-11 25v250q0 15 11 25t25 11 25-11l80-80 185 185q6 6 13 6t13-6l64-63q5-6 5-13z m436 482v-250q0-15-10-25t-26-11-25 11l-80 80-185-185q-6-6-13-6t-13 6l-64 63q-5 6-5 13t5 13l186 185-81 81q-10 10-10 25t10 25 25 11h250q15 0 26-11t10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="resize-small" unicode="&#xe82b;" d="m429 314v-250q0-14-11-25t-25-10-25 10l-81 81-185-186q-5-5-13-5t-13 5l-63 64q-6 5-6 13t6 13l185 185-80 80q-11 11-11 25t11 25 25 11h250q14 0 25-11t11-25z m421 375q0-7-6-13l-185-185 80-80q11-11 11-25t-11-25-25-11h-250q-14 0-25 11t-10 25v250q0 14 10 25t25 10 25-10l81-81 185 186q6 5 13 5t13-5l63-64q6-5 6-13z" horiz-adv-x="857.1" />
<glyph glyph-name="move" unicode="&#xe82c;" d="m1000 350q0-14-11-25l-142-143q-11-11-26-11t-25 11-10 25v72h-215v-215h72q14 0 25-10t11-25-11-26l-143-142q-10-11-25-11t-25 11l-143 142q-11 11-11 26t11 25 25 10h72v215h-215v-72q0-14-10-25t-25-11-26 11l-142 143q-11 11-11 25t11 25l142 143q11 11 26 11t25-11 10-25v-72h215v215h-72q-14 0-25 10t-11 25 11 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26t-11-25-25-10h-72v-215h215v72q0 14 10 25t25 11 26-11l142-143q11-10 11-25z" horiz-adv-x="1000" />
<glyph glyph-name="resize-horizontal" unicode="&#xe82d;" d="m1000 350q0-14-11-25l-142-143q-11-11-26-11t-25 11-10 25v72h-572v-72q0-14-10-25t-25-11-25 11l-143 143q-11 11-11 25t11 25l143 143q10 11 25 11t25-11 10-25v-72h572v72q0 14 10 25t25 11 26-11l142-143q11-10 11-25z" horiz-adv-x="1000" />
<glyph glyph-name="resize-vertical" unicode="&#xe82e;" d="m393 671q0-14-11-25t-25-10h-71v-572h71q15 0 25-10t11-25-11-26l-143-142q-10-11-25-11t-25 11l-143 142q-10 11-10 26t10 25 25 10h72v572h-72q-14 0-25 10t-10 25 10 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26z" horiz-adv-x="428.6" />
<glyph glyph-name="zoom-in" unicode="&#xe82f;" d="m571 404v-36q0-7-5-13t-12-5h-125v-125q0-7-6-13t-12-5h-36q-7 0-13 5t-5 13v125h-125q-7 0-12 5t-6 13v36q0 7 6 12t12 5h125v125q0 8 5 13t13 5h36q7 0 12-5t6-13v-125h125q7 0 12-5t5-12z m72-18q0 103-74 176t-176 74-177-74-73-176 73-177 177-73 176 73 74 177z m286-465q0-29-21-50t-51-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
<glyph glyph-name="block" unicode="&#xe830;" d="m732 352q0 90-48 164l-421-420q76-50 166-50 62 0 118 25t96 65 65 97 24 119z m-557-167l421 421q-75 50-167 50-83 0-153-40t-110-112-41-152q0-91 50-167z m682 167q0-88-34-168t-91-137-137-92-166-34-167 34-137 92-91 137-34 168 34 167 91 137 137 91 167 34 166-34 137-91 91-137 34-167z" horiz-adv-x="857.1" />
<glyph glyph-name="zoom-out" unicode="&#xe831;" d="m571 404v-36q0-7-5-13t-12-5h-322q-7 0-12 5t-6 13v36q0 7 6 12t12 5h322q7 0 12-5t5-12z m72-18q0 103-74 176t-176 74-177-74-73-176 73-177 177-73 176 73 74 177z m286-465q0-29-21-50t-51-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
<glyph glyph-name="lightbulb" unicode="&#xe832;" d="m411 529q0-8-6-13t-12-5-13 5-5 13q0 25-30 39t-59 14q-8 0-13 5t-5 13 5 13 13 5q28 0 55-9t49-30 21-50z m89 0q0 40-19 74t-50 57-69 35-76 12-76-12-69-35-50-57-20-74q0-57 38-101 6-6 17-18t17-19q72-85 79-166h127q8 81 79 166 6 6 17 19t17 18q38 44 38 101z m71 0q0-87-57-150-25-27-42-49t-33-53-19-60q26-15 26-46 0-20-14-35 14-15 14-36 0-29-25-45 8-13 8-26 0-26-18-40t-43-14q-11-25-34-39t-48-15-49 15-33 39q-26 0-44 14t-17 40q0 13 7 26-25 16-25 45 0 21 14 36-14 15-14 35 0 31 26 46-2 28-19 60t-33 53-41 49q-58 63-58 150 0 55 25 103t65 79 92 49 104 19 104-19 91-49 66-79 24-103z" horiz-adv-x="571.4" />
<glyph glyph-name="clock" unicode="&#xe833;" d="m500 546v-250q0-7-5-12t-13-5h-178q-8 0-13 5t-5 12v36q0 8 5 13t13 5h125v196q0 8 5 13t12 5h36q8 0 13-5t5-13z m232-196q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
<glyph glyph-name="volume-up" unicode="&#xe834;" d="m429 654v-608q0-14-11-25t-25-10-25 10l-186 186h-146q-15 0-25 11t-11 25v214q0 15 11 25t25 11h146l186 186q10 10 25 10t25-10 11-25z m214-304q0-42-24-79t-63-52q-5-3-14-3-14 0-25 10t-10 26q0 12 6 20t17 14 19 12 16 20 6 32-6 32-16 20-19 12-17 14-6 20q0 15 10 26t25 10q9 0 14-3 39-15 63-52t24-79z m143 0q0-85-48-158t-125-105q-8-3-14-3-15 0-26 11t-10 25q0 22 21 33 32 16 43 25 41 30 64 75t23 97-23 97-64 75q-11 9-43 25-21 11-21 33 0 14 10 25t25 11q7 0 15-3 78-33 125-105t48-158z m143 0q0-128-71-236t-189-158q-7-3-14-3-15 0-26 11t-10 25q0 20 22 33 4 2 12 6t13 6q25 14 45 28 69 51 108 127t38 161-38 161-108 127q-20 14-45 28-4 3-13 6t-12 6q-22 13-22 33 0 14 10 25t26 11q7 0 14-3 118-51 189-158t71-236z" horiz-adv-x="928.6" />
<glyph glyph-name="volume-down" unicode="&#xe835;" d="m429 654v-608q0-14-11-25t-25-10-25 10l-186 186h-146q-15 0-25 11t-11 25v214q0 15 11 25t25 11h146l186 186q10 10 25 10t25-10 11-25z m214-304q0-42-24-79t-63-52q-5-3-14-3-14 0-25 10t-10 26q0 12 6 20t17 14 19 12 16 20 6 32-6 32-16 20-19 12-17 14-6 20q0 15 10 26t25 10q9 0 14-3 39-15 63-52t24-79z" horiz-adv-x="642.9" />
<glyph glyph-name="volume-off" unicode="&#xe836;" d="m429 654v-608q0-14-11-25t-25-10-25 10l-186 186h-146q-15 0-25 11t-11 25v214q0 15 11 25t25 11h146l186 186q10 10 25 10t25-10 11-25z" horiz-adv-x="428.6" />
<glyph glyph-name="mute" unicode="&#xe837;" d="m151 323l-56-57q-24 58-24 120v71q0 15 11 25t25 11 25-11 11-25v-71q0-30 8-63z m622 336l-202-202v-71q0-74-52-126t-126-53q-31 0-61 11l-54-54q55-28 115-28 103 0 176 73t74 177v71q0 15 10 25t26 11 25-11 10-25v-71q0-124-82-215t-203-104v-74h142q15 0 26-11t10-25-10-25-26-11h-357q-14 0-25 11t-10 25 10 25 25 11h143v74q-70 7-131 45l-142-142q-5-6-13-6t-12 6l-46 46q-6 5-6 13t6 12l688 689q6 6 13 6t13-6l46-46q5-5 5-13t-5-12z m-212 73l-347-346v285q0 74 53 127t126 52q57 0 103-33t65-85z" horiz-adv-x="785.7" />
<glyph glyph-name="mic" unicode="&#xe838;" d="m643 457v-71q0-124-82-215t-204-104v-74h143q15 0 25-11t11-25-11-25-25-11h-357q-15 0-25 11t-11 25 11 25 25 11h143v74q-121 13-204 104t-82 215v71q0 15 11 25t25 11 25-11 10-25v-71q0-104 74-177t176-73 177 73 73 177v71q0 15 11 25t25 11 25-11 11-25z m-143 214v-285q0-74-52-126t-127-53-126 53-52 126v285q0 74 52 127t126 52 127-52 52-127z" horiz-adv-x="642.9" />
<glyph glyph-name="endtime" unicode="&#xe839;" d="m661 350q0-14-11-25l-303-304q-11-10-26-10t-25 10-10 25v161h-250q-15 0-25 11t-11 25v214q0 15 11 25t25 11h250v161q0 14 10 25t25 10 26-10l303-304q11-10 11-25z m196 196v-392q0-67-47-114t-114-47h-178q-7 0-13 5t-5 13q0 2-1 11t0 15 2 13 5 11 12 3h178q37 0 63 27t27 63v392q0 37-27 63t-63 27h-174t-6 0-6 2-5 3-4 5-1 8q0 2-1 11t0 15 2 13 5 11 12 3h178q67 0 114-47t47-114z" horiz-adv-x="857.1" />
<glyph glyph-name="starttime" unicode="&#xe83a;" d="m357 46q0-2 1-11t0-14-2-14-5-11-12-3h-178q-67 0-114 47t-47 114v392q0 67 47 114t114 47h178q8 0 13-5t5-13q0-2 1-11t0-15-2-13-5-11-12-3h-178q-37 0-63-27t-27-63v-392q0-37 27-63t63-27h174t6 0 7-2 4-3 4-5 1-8z m518 304q0-14-11-25l-303-304q-11-10-25-10t-25 10-11 25v161h-250q-14 0-25 11t-11 25v214q0 15 11 25t25 11h250v161q0 14 11 25t25 10 25-10l303-304q11-10 11-25z" horiz-adv-x="928.6" />
<glyph glyph-name="calendar-empty" unicode="&#xe83b;" d="m71-79h786v572h-786v-572z m215 679v161q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-161q0-8 5-13t13-5h36q8 0 13 5t5 13z m428 0v161q0 8-5 13t-13 5h-35q-8 0-13-5t-5-13v-161q0-8 5-13t13-5h35q8 0 13 5t5 13z m215 36v-715q0-29-22-50t-50-21h-786q-29 0-50 21t-21 50v715q0 29 21 50t50 21h72v54q0 36 26 63t63 26h36q37 0 63-26t26-63v-54h214v54q0 36 27 63t63 26h35q37 0 63-26t27-63v-54h71q29 0 50-21t22-50z" horiz-adv-x="928.6" />
<glyph glyph-name="calendar" unicode="&#xe83c;" d="m71-79h161v161h-161v-161z m197 0h178v161h-178v-161z m-197 197h161v178h-161v-178z m197 0h178v178h-178v-178z m-197 214h161v161h-161v-161z m411-411h179v161h-179v-161z m-214 411h178v161h-178v-161z m428-411h161v161h-161v-161z m-214 197h179v178h-179v-178z m-196 482v161q0 7-6 12t-12 6h-36q-7 0-12-6t-6-12v-161q0-7 6-13t12-5h36q7 0 12 5t6 13z m410-482h161v178h-161v-178z m-214 214h179v161h-179v-161z m214 0h161v161h-161v-161z m18 268v161q0 7-5 12t-13 6h-35q-8 0-13-6t-5-12v-161q0-7 5-13t13-5h35q8 0 13 5t5 13z m215 36v-715q0-29-22-50t-50-21h-786q-29 0-50 21t-21 50v715q0 29 21 50t50 21h72v54q0 36 26 63t63 26h36q37 0 63-26t26-63v-54h214v54q0 36 27 63t63 26h35q37 0 63-26t27-63v-54h71q29 0 50-21t22-50z" horiz-adv-x="928.6" />
<glyph glyph-name="wrench" unicode="&#xe83d;" d="m214 29q0 14-10 25t-25 10-26-10-10-25 10-26 26-10 25 10 10 26z m360 234l-381-381q-21-20-50-20-29 0-51 20l-59 61q-21 20-21 50 0 29 21 51l380 380q22-55 64-97t97-64z m353 243q0-22-12-59-27-75-92-122t-144-46q-104 0-177 73t-73 177 73 176 177 74q32 0 67-10t60-26q9-6 9-15t-9-16l-163-94v-125l108-60q2 2 44 27t75 45 40 20q8 0 13-5t4-14z" horiz-adv-x="928.6" />
<glyph glyph-name="sliders" unicode="&#xe83e;" d="m196 64v-71h-196v71h196z m197 72q14 0 25-11t11-25v-143q0-14-11-25t-25-11h-143q-14 0-25 11t-11 25v143q0 15 11 25t25 11h143z m89 214v-71h-482v71h482z m-357 286v-72h-125v72h125z m732-572v-71h-411v71h411z m-536 643q15 0 26-10t10-26v-142q0-15-10-26t-26-10h-142q-15 0-26 10t-10 26v142q0 15 10 26t26 10h142z m358-286q14 0 25-10t10-25v-143q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v143q0 14 11 25t25 10h143z m178-71v-71h-125v71h125z m0 286v-72h-482v72h482z" horiz-adv-x="857.1" />
<glyph glyph-name="conf-alt" unicode="&#xe83f;" d="m500 350q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m429-286q0 29-22 51t-50 21-50-21-21-51q0-29 21-50t50-21 51 21 21 50z m0 572q0 29-22 50t-50 21-50-21-21-50q0-30 21-51t50-21 51 21 21 51z m-215-235v-103q0-6-4-11t-9-6l-86-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-13-17-46-50t-44-33q-6 0-11 4l-64 50q-21-11-43-17-6-60-13-87-4-13-17-13h-104q-6 0-11 4t-5 10l-13 85q-19 6-42 18l-66-50q-4-4-11-4-6 0-12 4-80 75-80 90 0 5 4 10 5 8 23 30t26 34q-13 24-20 46l-85 13q-5 1-9 5t-4 11v103q0 6 4 11t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 11 12 17 46 50t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 41-17l66 49q5 4 11 4 7 0 12-4 81-75 81-90 0-5-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q5-2 9-6t4-11z m357-298v-78q0-9-83-17-6-15-16-29 28-63 28-77 0-2-2-4-68-40-69-40-5 0-26 27t-29 37q-11-1-17-1t-17 1q-7-11-29-37t-25-27q-1 0-69 40-3 2-3 4 0 14 29 77-10 14-17 29-83 8-83 17v78q0 9 83 18 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 1 17 1t17-1q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-9 83-18z m0 572v-78q0-9-83-18-6-15-16-29 28-63 28-77 0-2-2-4-68-39-69-39-5 0-26 26t-29 38q-11-1-17-1t-17 1q-7-12-29-38t-25-26q-1 0-69 39-3 2-3 4 0 14 29 77-10 14-17 29-83 9-83 18v78q0 9 83 17 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 2 17 2t17-2q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-8 83-17z" horiz-adv-x="1071.4" />
<glyph glyph-name="conf" unicode="&#xe840;" d="m571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-13 0-6-4-12-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13z" horiz-adv-x="857.1" />
<glyph glyph-name="phone" unicode="&#xe841;" d="m786 158q0-15-6-39t-12-38q-11-28-68-60-52-28-103-28-16 0-30 2t-32 7-26 8-31 11-28 10q-54 20-97 47-72 44-148 120t-120 148q-27 43-46 97-2 5-10 28t-12 31-8 26-7 32-2 29q0 52 29 104 31 56 59 68 14 6 38 12t39 6q8 0 12-2 10-3 30-43 6-10 16-30t20-35 17-30q2-2 10-14t12-20 4-16q0-11-16-28t-35-30-34-30-16-25q0-5 3-13t4-11 8-14 7-10q42-77 97-132t131-97q1 0 10-6t14-8 11-5 13-2q10 0 25 15t30 35 31 35 28 16q7 0 15-4t20-12 14-10q14-8 30-17t35-20 31-17q39-19 42-29 2-4 2-12z" horiz-adv-x="785.7" />
<glyph glyph-name="file-pdf" unicode="&#xe842;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-287 331q18-14 47-31 33 4 65 4 82 0 99-27 9-13 1-29 0-1-1-1l-1-2v0q-3-21-39-21-27 0-65 11t-72 29q-123-13-219-46-85-146-135-146-8 0-15 4l-14 6q0 1-3 3-6 6-4 20 5 23 32 51t73 54q8 5 13-3 1-1 1-2 29 47 60 110 38 76 58 146-13 46-17 89t4 71q6 22 23 22h12q13 0 20-8 10-12 5-38-1-3-2-4 0-2 0-5v-17q-1-68-8-107 31-91 82-133z m-322-229q30 13 77 88-29-22-49-47t-28-41z m223 513q-9-23-2-73 1 4 4 24 0 2 4 24 1 3 3 5-1 0-1 1t0 1-1 1q0 12-7 20 0-1 0-1v-2z m-70-368q76 30 159 45-1 0-7 5t-9 8q-43 37-71 98-15-48-47-110-16-31-25-46z m361 8q-14 14-78 14 42-16 69-16 8 0 10 1 0 0-1 1z" horiz-adv-x="857.1" />
<glyph glyph-name="file-word" unicode="&#xe843;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-656 500v-59h39l92-369h88l72 271q4 11 5 25 1 9 1 14h3l1-14q1-1 2-11t3-14l72-271h89l91 369h39v59h-167v-59h50l-55-245q-3-11-4-25l-1-12h-3l-1 12q-1 2-2 11t-3 14l-81 304h-63l-81-304q-1-5-2-13t-2-12l-2-12h-2l-2 12q-1 14-4 25l-55 245h50v59h-167z" horiz-adv-x="857.1" />
<glyph glyph-name="file-excel" unicode="&#xe844;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-547 131v-59h157v59h-42l58 90q3 4 5 9t5 8 2 2h1q0-2 2-6 2-2 3-4t3-4 4-5l60-90h-43v-59h163v59h-38l-107 152 108 158h38v59h-156v-59h41l-57-89q-2-4-6-9t-5-8l-1-1h-1q-1 2-3 5-3 6-9 13l-59 89h42v59h-162v-59h38l106-152-109-158h-38z" horiz-adv-x="857.1" />
<glyph glyph-name="doc-text" unicode="&#xe845;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-572 483q0 7 5 12t13 5h393q8 0 13-5t5-12v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36z m411-125q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z m0-143q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z" horiz-adv-x="857.1" />
<glyph glyph-name="trash" unicode="&#xe846;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15 6-5h464q2 0 6 5t8 15 4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
<glyph glyph-name="comment-empty" unicode="&#xe847;" d="m500 636q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-54q-13-50-39-95 85 35 154 95l24 21 31-3q39-5 73-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-7-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 7t1 5 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
<glyph glyph-name="comment" unicode="&#xe848;" d="m1000 350q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12-10-1-17 5t-10 16v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 73 40 139t106 114 160 76 194 28q136 0 251-48t182-130 67-179z" horiz-adv-x="1000" />
<glyph glyph-name="chat" unicode="&#xe849;" d="m786 421q0-77-53-143t-143-104-197-38q-48 0-98 9-70-49-155-72-21-5-48-9h-2q-6 0-12 5t-6 12q-1 1-1 3t1 4 1 3l1 3t2 3 2 3 3 3 2 2q3 3 13 14t15 16 12 17 14 21 11 25q-69 40-108 98t-40 125q0 78 53 144t143 104 197 38 197-38 143-104 53-144z m214-142q0-67-40-126t-108-98q5-14 11-25t14-21 13-16 14-17 13-14q0 0 2-2t3-3 2-3 2-3l1-3t1-3 1-4-1-3q-2-8-7-13t-13-4q-27 4-48 9-85 23-155 72-50-9-98-9-151 0-263 74 32-3 49-3 90 0 172 25t148 72q69 52 107 119t37 141q0 43-13 85 72-39 114-99t42-128z" horiz-adv-x="1000" />
<glyph glyph-name="chat-empty" unicode="&#xe84a;" d="m393 636q-85 0-160-29t-118-79-44-107q0-45 30-88t83-73l54-32-19-46q19 11 34 21l25 18 30-6q43-8 85-8 85 0 159 29t118 79 44 106-44 107-118 79-159 29z m0 71q106 0 197-38t143-104 53-144-53-143-143-104-197-38q-48 0-98 9-70-49-155-72-21-5-48-9h-2q-6 0-12 5t-6 12q-1 1-1 3t1 4 1 3l1 3t2 3 2 3 3 3 2 2q3 3 13 14t15 16 12 17 14 21 11 25q-69 40-108 98t-40 125q0 78 53 144t143 104 197 38z m459-652q5-14 11-25t14-21 13-16 14-17 13-14q0 0 2-2t3-3 2-3 2-3l1-3t1-3 1-4-1-3q-2-8-7-13t-13-4q-27 4-48 9-85 23-155 72-50-9-98-9-151 0-263 74 32-3 49-3 90 0 172 25t148 72q69 52 107 119t37 141q0 43-13 85 72-39 114-99t42-128q0-67-40-126t-108-98z" horiz-adv-x="1000" />
<glyph glyph-name="bell" unicode="&#xe84b;" d="m509-96q0 8-9 8-33 0-57 24t-23 57q0 9-9 9t-9-9q0-41 29-70t69-28q9 0 9 9z m-372 160h726q-149 168-149 465 0 28-13 58t-39 58-67 45-95 17-95-17-67-45-39-58-13-58q0-297-149-465z m827 0q0-29-21-50t-50-21h-250q0-59-42-101t-101-42-101 42-42 101h-250q-29 0-50 21t-21 50q28 24 51 49t47 67 42 89 27 114 11 146q0 84 66 157t171 89q-5 10-5 21 0 23 16 38t38 16 38-16 16-38q0-11-5-21 106-16 171-89t66-157q0-78 11-146t27-114 42-89 47-67 51-49z" horiz-adv-x="1000" />
<glyph glyph-name="bell-alt" unicode="&#xe84c;" d="m509-96q0 8-9 8-33 0-57 24t-23 57q0 9-9 9t-9-9q0-41 29-70t69-28q9 0 9 9z m455 160q0-29-21-50t-50-21h-250q0-59-42-101t-101-42-101 42-42 101h-250q-29 0-50 21t-21 50q28 24 51 49t47 67 42 89 27 114 11 146q0 84 66 157t171 89q-5 10-5 21 0 23 16 38t38 16 38-16 16-38q0-11-5-21 106-16 171-89t66-157q0-78 11-146t27-114 42-89 47-67 51-49z" horiz-adv-x="1000" />
<glyph glyph-name="attention-alt" unicode="&#xe84d;" d="m286 154v-125q0-15-11-25t-25-11h-143q-14 0-25 11t-11 25v125q0 14 11 25t25 10h143q15 0 25-10t11-25z m16 589l-15-429q-1-14-12-25t-25-10h-143q-14 0-25 10t-12 25l-15 429q-1 14 9 25t25 11h179q14 0 25-11t9-25z" horiz-adv-x="357.1" />
<glyph glyph-name="print" unicode="&#xe84e;" d="m214-7h500v143h-500v-143z m0 357h500v214h-89q-22 0-38 16t-16 38v89h-357v-357z m643-36q0 15-10 25t-26 11-25-11-10-25 10-25 25-10 26 10 10 25z m72 0v-232q0-7-6-12t-12-6h-125v-89q0-22-16-38t-38-16h-536q-22 0-37 16t-16 38v89h-125q-7 0-13 6t-5 12v232q0 44 32 76t75 31h36v304q0 22 16 38t37 16h375q23 0 50-12t42-26l85-85q15-16 27-43t11-49v-143h35q45 0 76-31t32-76z" horiz-adv-x="928.6" />
<glyph glyph-name="edit" unicode="&#xe84f;" d="m496 189l64 65-85 85-64-65v-31h53v-54h32z m245 402q-9 9-18 0l-196-196q-9-9 0-18t18 0l196 196q9 9 0 18z m45-331v-106q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q35 0 65-14 9-4 10-13 2-10-5-16l-27-28q-8-8-18-4-13 3-25 3h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v70q0 7 5 12l36 36q8 8 20 4t11-16z m-54 411l161-160-375-375h-161v160z m248-73l-51-52-161 161 51 51q16 16 38 16t38-16l85-84q16-16 16-38t-16-38z" horiz-adv-x="1000" />
<glyph glyph-name="forward" unicode="&#xe850;" d="m1000 493q0-15-11-25l-285-286q-11-11-25-11t-26 11-10 25v143h-125q-55 0-98-3t-86-12-74-24-59-39-45-56-27-77-10-101q0-31 3-69 0-4 2-13t1-15q0-8-5-14t-13-6q-9 0-15 10-4 5-8 12t-7 17-6 13q-71 159-71 252 0 111 30 186 90 225 488 225h125v143q0 14 10 25t26 10 25-10l285-286q11-11 11-25z" horiz-adv-x="1000" />
<glyph glyph-name="reply" unicode="&#xe851;" d="m1000 225q0-93-71-252-2-4-6-13t-7-17-8-12q-6-10-15-10-9 0-13 6t-5 14q0 5 1 15t2 13q3 38 3 69 0 56-10 101t-27 77-45 56-59 39-74 24-86 12-98 3h-125v-143q0-14-10-25t-26-11-25 11l-285 286q-11 10-11 25t11 25l285 286q11 10 25 10t26-10 10-25v-143h125q398 0 488-225 30-75 30-186z" horiz-adv-x="1000" />
<glyph glyph-name="reply-all" unicode="&#xe852;" d="m357 246v-39q0-23-22-33-7-3-14-3-15 0-25 11l-285 286q-11 10-11 25t11 25l285 286q17 17 39 7 22-9 22-32v-39l-221-222q-11-11-11-25t11-25z m643-21q0-32-9-74t-22-77-27-70-22-51l-12-22q-4-10-15-10-3 0-5 1-14 4-13 19 24 223-59 315-36 40-95 62t-150 29v-140q0-23-21-33-8-3-14-3-15 0-25 11l-286 286q-11 10-11 25t11 25l286 286q16 17 39 7 21-9 21-32v-147q230-15 335-123 94-97 94-284z" horiz-adv-x="1000" />
<glyph glyph-name="eye" unicode="&#xe853;" d="m929 314q-85 132-213 197 34-58 34-125 0-104-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 242 68 187 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
<glyph glyph-name="tag" unicode="&#xe854;" d="m250 600q0 30-21 51t-50 20-51-20-21-51 21-50 51-21 50 21 21 50z m595-321q0-30-20-51l-274-274q-22-21-51-21-30 0-50 21l-399 399q-21 21-36 57t-15 65v232q0 29 21 50t50 22h233q29 0 65-15t57-36l399-399q20-21 20-50z" horiz-adv-x="857.1" />
<glyph glyph-name="tags" unicode="&#xe855;" d="m250 600q0 30-21 51t-50 20-51-20-21-51 21-50 51-21 50 21 21 50z m595-321q0-30-20-51l-274-274q-22-21-51-21-30 0-50 21l-399 399q-21 21-36 57t-15 65v232q0 29 21 50t50 22h233q29 0 65-15t57-36l399-399q20-21 20-50z m215 0q0-30-21-51l-274-274q-22-21-51-21-20 0-33 8t-29 25l262 262q21 21 21 51 0 29-21 50l-399 399q-21 21-57 36t-65 15h125q29 0 65-15t57-36l399-399q21-21 21-50z" horiz-adv-x="1071.4" />
<glyph glyph-name="lock-open-alt" unicode="&#xe856;" d="m589 421q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v179q0 103 74 177t176 73 177-73 73-177q0-15-10-25t-25-11h-36q-14 0-25 11t-11 25q0 59-42 101t-101 42-101-42-41-101v-179h410z" horiz-adv-x="642.9" />
<glyph glyph-name="lock-open" unicode="&#xe857;" d="m929 529v-143q0-15-11-25t-25-11h-36q-14 0-25 11t-11 25v143q0 59-41 101t-101 41-101-41-42-101v-108h53q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h375v108q0 103 73 176t177 74 176-74 74-176z" horiz-adv-x="928.6" />
<glyph glyph-name="lock" unicode="&#xe858;" d="m179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
<glyph glyph-name="home" unicode="&#xe859;" d="m786 296v-267q0-15-11-26t-25-10h-214v214h-143v-214h-214q-15 0-25 10t-11 26v267q0 1 0 2t0 2l321 264 321-264q1-1 1-4z m124 39l-34-41q-5-5-12-6h-2q-7 0-12 3l-386 322-386-322q-7-4-13-4-7 2-12 7l-35 41q-4 5-3 13t6 12l401 334q18 15 42 15t43-15l136-114v109q0 8 5 13t13 5h107q8 0 13-5t5-13v-227l122-102q5-5 6-12t-4-13z" horiz-adv-x="928.6" />
<glyph glyph-name="info" unicode="&#xe85a;" d="m357 100v-71q0-15-10-25t-26-11h-285q-15 0-25 11t-11 25v71q0 15 11 25t25 11h35v214h-35q-15 0-25 11t-11 25v71q0 15 11 25t25 11h214q15 0 25-11t11-25v-321h35q15 0 26-11t10-25z m-71 643v-107q0-15-11-25t-25-11h-143q-14 0-25 11t-11 25v107q0 14 11 25t25 11h143q15 0 25-11t11-25z" horiz-adv-x="357.1" />
<glyph glyph-name="help" unicode="&#xe85b;" d="m393 149v-134q0-9-7-16t-15-6h-134q-9 0-16 6t-7 16v134q0 9 7 16t16 6h134q8 0 15-6t7-16z m176 335q0-30-8-56t-20-43-31-33-32-25-34-19q-23-13-38-37t-15-37q0-10-7-18t-16-9h-134q-8 0-14 10t-6 21v26q0 46 37 87t79 60q33 15 47 32t14 42q0 23-26 41t-60 18q-36 0-60-16-20-14-60-64-7-9-17-9-7 0-14 4l-91 70q-8 6-9 14t3 16q89 148 259 148 45 0 90-17t81-46 59-72 23-88z" horiz-adv-x="571.4" />
<glyph glyph-name="search" unicode="&#xe85c;" d="m643 386q0 103-74 176t-176 74-177-74-73-176 73-177 177-73 176 73 74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
<glyph glyph-name="flapping" unicode="&#xe85d;" d="m0 34v173h229q28 0 52 10 31-84 98-145-71-38-150-38h-229z m0 458v173h229q65 0 123-25t101-67 68-101 25-123q0-58 41-100t101-42h85q1 0 3 0t4 0v52q0 16 10 22t22-3l234-144q8-5 8-14 0-3-2-7t-4-5l-2-2-234-143q-13-9-22-3t-10 21v54q-1 0-4-1t-3 0h-85q-64 0-123 25t-101 67-67 101-25 122q0 59-42 101t-101 42h-229z m538 136q68 37 150 37h85q1 0 3 0t4 0v54q0 15 10 21t22-3l234-144q8-6 8-14 0-4-2-7t-4-5l-2-2-234-144q-13-8-22-2t-10 21v53q-1 0-4 0t-3-1h-85q-26 0-51-10-32 85-99 146z" horiz-adv-x="1054.7" />
<glyph glyph-name="rewind" unicode="&#xe85e;" d="m532 736q170 0 289-120t119-290-119-290-289-120q-142 0-252 88l70 74q84-60 182-60 126 0 216 90t90 218-90 218-216 90q-124 0-214-87t-92-211l142 0-184-204-184 204 124 0q2 166 122 283t286 117z" horiz-adv-x="940" />
<glyph glyph-name="chart-line" unicode="&#xe85f;" d="m1143-7v-72h-1143v858h71v-786h1072z m-72 696v-242q0-12-10-17t-20 4l-68 68-353-353q-6-6-13-6t-13 6l-130 130-232-233-107 108 326 326q6 6 13 6t13-6l130-130 259 259-67 67q-9 9-5 20t17 11h243q7 0 12-5t5-13z" horiz-adv-x="1142.9" />
<glyph glyph-name="bell-off" unicode="&#xe860;" d="m869 375q34-199 167-311 0-29-22-50t-50-21h-250q0-59-42-101t-101-42-100 42-42 100z m-298-480q9 0 9 9t-9 8q-32 0-56 24t-24 57q0 9-9 9t-9-9q0-41 29-70t69-28z m560 892q4-5 4-13t-6-12l-1045-905q-5-5-13-4t-12 6l-47 53q-4 6-4 14t6 12l104 89q-11 18-11 37 28 24 51 49t47 67 42 89 28 114 11 146q0 84 65 157t171 89q-4 10-4 21 0 23 15 38t38 16 38-16 16-38q0-11-4-21 69-10 122-46t82-88l234 202q5 5 13 4t12-6z" horiz-adv-x="1142.9" />
<glyph glyph-name="bell-off-empty" unicode="&#xe861;" d="m580-96q0 8-9 8-32 0-56 24t-24 57q0 9-9 9t-9-9q0-41 29-70t69-28q9 0 9 9z m-299 265l489 424q-23 49-74 81t-125 33q-51 0-94-17t-68-45-38-58-14-58q0-215-76-360z m755-105q0-29-22-50t-50-21h-250q0-59-42-101t-101-42-100 42-42 100l83 72h422q-92 105-127 256l62 55q34-199 167-311z m48 777l47-54q4-5 4-13t-6-12l-1045-905q-5-5-13-4t-12 6l-47 53q-4 6-4 14t6 12l104 89q-11 18-11 37 28 24 51 49t47 67 42 89 28 114 11 146q0 84 65 157t171 89q-4 10-4 21 0 23 15 38t38 16 38-16 16-38q0-11-4-21 69-10 122-46t82-88l234 202q5 5 13 4t12-6z" horiz-adv-x="1142.9" />
<glyph glyph-name="plug" unicode="&#xe862;" d="m979 597q21-20 21-50t-21-51l-223-223 83-84-89-89q-91-91-217-104t-230 56l-202-202h-101v101l202 202q-69 103-56 230t104 217l89 89 84-83 223 223q21 21 51 21t50-21 21-50-21-51l-223-224 131-130 223 223q22 21 51 21t50-21z" horiz-adv-x="1000" />
<glyph glyph-name="eye-off" unicode="&#xe863;" d="m310 105l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197 94-144 239-209z m217 424q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m202 106q0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 49-80 36-147 96t-117 137q-11 17-11 38t11 39q86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15z m21-249q0-78-44-142t-117-92l157 281q4-26 4-47z m250-72q0-19-11-38-22-36-61-81-84-96-194-149t-234-53l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-86t81-102q11-19 11-39z" horiz-adv-x="1000" />
<glyph glyph-name="reschedule" unicode="&#xe864;" d="m186 140l116 116 0-292-276 16 88 86q-116 122-114 290t120 288q100 100 240 116l4-102q-100-16-172-88-88-88-90-213t84-217z m332 598l276-16-88-86q116-122 114-290t-120-288q-96-98-240-118l-2 104q98 16 170 88 88 88 90 213t-84 217l-114-116z" horiz-adv-x="820" />
<glyph glyph-name="cw" unicode="&#xe865;" d="m408 760q168 0 287-116t123-282l122 0-184-206-184 206 144 0q-4 124-94 210t-214 86q-126 0-216-90t-90-218q0-126 90-216t216-90q104 0 182 60l70-76q-110-88-252-88-168 0-288 120t-120 290 120 290 288 120z" horiz-adv-x="940" />
<glyph glyph-name="host" unicode="&#xe866;" d="m232 136q-37 0-63 26t-26 63v393q0 37 26 63t63 26h607q37 0 63-26t27-63v-393q0-37-27-63t-63-26h-607z m-18 482v-393q0-7 6-13t12-5h607q8 0 13 5t5 13v393q0 7-5 12t-13 6h-607q-7 0-12-6t-6-12z m768-518h89v-54q0-22-26-37t-63-16h-893q-36 0-63 16t-26 37v54h982z m-402-54q9 0 9 9t-9 9h-89q-9 0-9-9t9-9h89z" horiz-adv-x="1071.4" />
<glyph glyph-name="thumbs-up" unicode="&#xe867;" d="m143 100q0 15-11 25t-25 11-25-11-11-25 11-25 25-11 25 11 11 25z m643 321q0 29-22 50t-50 22h-196q0 32 27 89t26 89q0 55-17 81t-72 27q-14-15-21-48t-17-70-33-61q-13-13-43-51-2-3-13-17t-18-22-19-24-22-25-22-19-22-16-20-5h-18v-357h18q7 0 18-1t18-4 21-6 20-7 20-7 16-5q118-41 191-41h67q107 0 107 93 0 15-2 31 16 9 26 30t10 41-10 38q29 28 29 67 0 13-5 31t-14 26q18 1 30 26t12 45z m71 1q0-50-27-91 5-18 5-38 0-43-21-81 1-12 1-24 0-56-33-99 0-78-48-123t-126-45h-72q-54 0-106 13t-121 36q-65 23-77 23h-161q-29 0-50 21t-21 50v357q0 30 21 51t50 21h153q20 13 77 86 32 42 60 72 13 14 19 47t17 71 35 60q22 21 50 21 47 0 84-18t57-57 20-104q0-51-27-107h98q58 0 101-42t42-100z" horiz-adv-x="857.1" />
<glyph glyph-name="thumbs-down" unicode="&#xe868;" d="m143 600q0 15-11 25t-25 11-25-11-11-25 11-25 25-11 25 11 11 25z m643-321q0 19-12 45t-30 26q8 10 14 27t5 30q0 39-29 67 10 18 10 38t-10 41-26 30q2 16 2 31 0 47-27 70t-76 23h-71q-73 0-191-41-3-1-16-6t-20-7-20-6-21-6-18-4-18-1h-18v-358h18q9 0 20-5t22-15 22-19 22-25 19-24 18-23 13-16q30-38 43-51 23-24 33-61t17-70 21-48q54 0 72 27t17 81q0 32-26 89t-27 89h196q28 0 50 22t22 49z m71-1q0-57-42-100t-101-42h-98q27-55 27-107 0-66-20-104-19-39-57-57t-84-18q-28 0-50 21-19 18-30 45t-14 51-10 47-17 36q-27 28-60 71-57 73-77 86h-153q-29 0-50 21t-21 51v357q0 29 21 50t50 21h161q12 0 77 22 72 25 125 37t111 13h63q78 0 126-45t48-120v-3q33-43 33-99 0-13-1-24 21-38 21-81 0-20-5-38 27-41 27-91z" horiz-adv-x="857.1" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Authentication;
namespace Icinga\Forms\Authentication;
use Icinga\Web\Form;
use Icinga\Web\Url;
@ -32,7 +32,7 @@ class LoginForm extends Form
array(
'required' => true,
'label' => t('Username'),
'placeholder' => t('Please enter your username...'),
'placeholder' => t(''),
'class' => false === isset($formData['username']) ? 'autofocus' : ''
)
);
@ -42,7 +42,7 @@ class LoginForm extends Form
array(
'required' => true,
'label' => t('Password'),
'placeholder' => t('...and your password'),
'placeholder' => t(''),
'class' => isset($formData['username']) ? 'autofocus' : ''
)
);

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
namespace Icinga\Forms\Config\Authentication;
use Zend_Validate_Callback;
use Icinga\Web\Form;
@ -31,7 +31,9 @@ class AutologinBackendForm extends Form
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The name of this authentication backend'),
'description' => t(
'The name of this authentication provider that is used to differentiate it from others'
),
'validators' => array(
array(
'Regex',
@ -50,9 +52,8 @@ class AutologinBackendForm extends Form
'text',
'strip_username_regexp',
array(
'required' => true,
'label' => t('Backend Domain Pattern'),
'description' => t('The domain pattern of this authentication backend'),
'label' => t('Filter Pattern'),
'description' => t('The regular expression to use to strip specific parts off from usernames. Leave empty if you do not want to strip off anything'),
'value' => '/\@[^$]+$/',
'validators' => array(
new Zend_Validate_Callback(function ($value) {
@ -82,7 +83,7 @@ class AutologinBackendForm extends Form
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
public static function isValidAuthenticationBackend(Form $form)
{
return true;
}

View File

@ -2,11 +2,11 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
namespace Icinga\Forms\Config\Authentication;
use Exception;
use Icinga\Application\Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\ResourceFactory;
use Icinga\Authentication\Backend\DbUserBackend;
@ -54,7 +54,9 @@ class DbBackendForm extends Form
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The name of this authentication provider'),
'description' => t(
'The name of this authentication provider that is used to differentiate it from others'
),
)
);
$this->addElement(
@ -86,9 +88,9 @@ class DbBackendForm extends Form
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (false === $this->isValidAuthenticationBackend($this)) {
if (false === static::isValidAuthenticationBackend($this)) {
return false;
}
}
@ -100,21 +102,29 @@ class DbBackendForm extends Form
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
public static function isValidAuthenticationBackend(Form $form)
{
$element = $form->getElement('resource');
try {
$dbUserBackend = new DbUserBackend(ResourceFactory::create($element->getValue()));
$dbUserBackend = new DbUserBackend(ResourceFactory::createResource($form->getResourceConfig()));
if ($dbUserBackend->count() < 1) {
$element->addError(t('No users found under the specified database backend'));
$form->addError(t('No users found under the specified database backend'));
return false;
}
} catch (Exception $e) {
$element->addError(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
$form->addError(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
return false;
}
return true;
}
/**
* Return the configuration for the chosen resource
*
* @return Config
*/
public function getResourceConfig()
{
return ResourceFactory::getResourceConfig($this->getValue('resource'));
}
}

View File

@ -2,12 +2,13 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
namespace Icinga\Forms\Config\Authentication;
use Exception;
use Icinga\Application\Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\AuthenticationException;
use Icinga\Authentication\Backend\LdapUserBackend;
/**
@ -54,7 +55,9 @@ class LdapBackendForm extends Form
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The name of this authentication backend')
'description' => t(
'The name of this authentication provider that is used to differentiate it from others'
)
)
);
$this->addElement(
@ -97,7 +100,16 @@ class LdapBackendForm extends Form
'value' => 'ldap'
)
);
$this->addElement(
'text',
'base_dn',
array(
'required' => false,
'label' => t('Base DN'),
'description' => t('The path where users can be found on the ldap server. ' .
' Leave empty to select all users available on the specified resource.')
)
);
return $this;
}
@ -106,9 +118,9 @@ class LdapBackendForm extends Form
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (false === $this->isValidAuthenticationBackend($this)) {
if (false === static::isValidAuthenticationBackend($this)) {
return false;
}
}
@ -120,22 +132,34 @@ class LdapBackendForm extends Form
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
public static function isValidAuthenticationBackend(Form $form)
{
$element = $form->getElement('resource');
try {
$ldapUserBackend = new LdapUserBackend(
ResourceFactory::create($element->getValue()),
ResourceFactory::createResource($form->getResourceConfig()),
$form->getElement('user_class')->getValue(),
$form->getElement('user_name_attribute')->getValue()
$form->getElement('user_name_attribute')->getValue(),
$form->getElement('base_dn')->getValue()
);
$ldapUserBackend->assertAuthenticationPossible();
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
return false;
} catch (Exception $e) {
$element->addError(sprintf(t('Connection validation failed: %s'), $e->getMessage()));
$form->addError(sprintf(t('Unable to validate authentication: %s'), $e->getMessage()));
return false;
}
return true;
}
/**
* Return the configuration for the chosen resource
*
* @return Config
*/
public function getResourceConfig()
{
return ResourceFactory::getResourceConfig($this->getValue('resource'));
}
}

View File

@ -2,18 +2,18 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
namespace Icinga\Forms\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Form\ConfigForm;
use Icinga\Forms\ConfigForm;
use Icinga\Web\Notification;
use Icinga\Application\Config;
use Icinga\Application\Platform;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
use Icinga\Form\Config\Authentication\DbBackendForm;
use Icinga\Form\Config\Authentication\LdapBackendForm;
use Icinga\Form\Config\Authentication\AutologinBackendForm;
use Icinga\Forms\Config\Authentication\DbBackendForm;
use Icinga\Forms\Config\Authentication\LdapBackendForm;
use Icinga\Forms\Config\Authentication\AutologinBackendForm;
class AuthenticationBackendConfigForm extends ConfigForm
{
@ -39,8 +39,6 @@ class AuthenticationBackendConfigForm extends ConfigForm
* @param Config $resources The resource configuration
*
* @return self
*
* @throws ConfigurationError In case no resources are available for authentication
*/
public function setResourceConfig(Config $resourceConfig)
{
@ -49,10 +47,6 @@ class AuthenticationBackendConfigForm extends ConfigForm
$resources[strtolower($resource->type)][] = $name;
}
if (empty($resources)) {
throw new ConfigurationError(t('Could not find any resources for authentication'));
}
$this->resources = $resources;
return $this;
}
@ -197,17 +191,17 @@ class AuthenticationBackendConfigForm extends ConfigForm
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
$backendForm = $this->getBackendForm($this->getElement('type')->getValue());
if (false === $backendForm->isValidAuthenticationBackend($this)) {
if (false === $backendForm::isValidAuthenticationBackend($this)) {
$this->addElement($this->getForceCreationCheckbox());
return false;
}
}
$authBackend = $request->getQuery('auth_backend');
$authBackend = $this->request->getQuery('auth_backend');
try {
if ($authBackend === null) { // create new backend
$this->add($this->getValues());
@ -235,9 +229,9 @@ class AuthenticationBackendConfigForm extends ConfigForm
*
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
*/
public function onRequest(Request $request)
public function onRequest()
{
$authBackend = $request->getQuery('auth_backend');
$authBackend = $this->request->getQuery('auth_backend');
if ($authBackend !== null) {
if ($authBackend === '') {
throw new ConfigurationError(t('Authentication backend name missing'));
@ -251,6 +245,17 @@ class AuthenticationBackendConfigForm extends ConfigForm
$configValues['type'] = $configValues['backend'];
$configValues['name'] = $authBackend;
$this->populate($configValues);
} elseif (empty($this->resources)) {
$autologinBackends = array_filter(
$this->config->toArray(),
function ($authBackendCfg) {
return isset($authBackendCfg['backend']) && $authBackendCfg['backend'] === 'autologin';
}
);
if (false === empty($autologinBackends)) {
throw new ConfigurationError(t('Could not find any resources for authentication'));
}
}
}
@ -280,7 +285,7 @@ class AuthenticationBackendConfigForm extends ConfigForm
public function createElements(array $formData)
{
$backendTypes = array();
$backendType = isset($formData['type']) ? $formData['type'] : 'db';
$backendType = isset($formData['type']) ? $formData['type'] : null;
if (isset($this->resources['db'])) {
$backendTypes['db'] = t('Database');
@ -299,6 +304,10 @@ class AuthenticationBackendConfigForm extends ConfigForm
$backendTypes['autologin'] = t('Autologin');
}
if ($backendType === null) {
$backendType = key($backendTypes);
}
$this->addElement(
'select',
'type',
@ -307,7 +316,7 @@ class AuthenticationBackendConfigForm extends ConfigForm
'required' => true,
'autosubmit' => true,
'label' => t('Backend Type'),
'description' => t('The type of the resource to use for this authenticaton backend'),
'description' => t('The type of the resource to use for this authenticaton provider'),
'multiOptions' => $backendTypes
)
);
@ -319,4 +328,14 @@ class AuthenticationBackendConfigForm extends ConfigForm
$this->addElements($this->getBackendForm($backendType)->createElements($formData)->getElements());
}
/**
* Return the configuration for the chosen resource
*
* @return Config
*/
public function getResourceConfig()
{
return ResourceFactory::getResourceConfig($this->getValue('resource'));
}
}

View File

@ -2,12 +2,11 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
namespace Icinga\Forms\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Forms\ConfigForm;
class AuthenticationBackendReorderForm extends ConfigForm
{
@ -30,17 +29,26 @@ class AuthenticationBackendReorderForm extends ConfigForm
return $this->config->keys();
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
// This adds just a dummy element to be able to utilize Form::getValue as part of onSuccess()
$this->addElement('hidden', 'backend_newpos');
}
/**
* Update the authentication backend order and save the configuration
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
$formData = $this->getRequestData($request);
if (isset($formData['backend_newpos'])) {
$newPosData = $this->getValue('backend_newpos');
if ($newPosData) {
$configForm = $this->getConfigForm();
list($backendName, $position) = explode('|', $formData['backend_newpos'], 2);
list($backendName, $position) = explode('|', $newPosData, 2);
try {
if ($configForm->move($backendName, $position)->save()) {

View File

@ -2,12 +2,14 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\General;
namespace Icinga\Forms\Config\General;
use DateTimeZone;
use Icinga\Web\Form;
use Icinga\Util\Translator;
use Icinga\Application\Icinga;
use Icinga\Data\ResourceFactory;
use Icinga\Util\Translator;
use Icinga\Web\Form;
/**
* Form class to modify the general application configuration
@ -27,56 +29,18 @@ class ApplicationConfigForm extends Form
*/
public function createElements(array $formData)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$this->addElement(
'select',
'global_language',
array(
'label' => t('Default Language'),
'required' => true,
'multiOptions' => $languages,
'description' => t(
'Select the language to use by default. Can be overwritten by a user in his preferences.'
)
)
);
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$this->addElement(
'select',
'global_timezone',
array(
'label' => t('Default Application Timezone'),
'required' => true,
'multiOptions' => $tzList,
'description' => t(
'Select the timezone to be used as the default. User\'s can set their own timezone if'
. ' they like to, but this is the timezone to be used as the default setting .'
),
'value' => date_default_timezone_get()
)
);
$this->addElement(
'text',
'global_modulePath',
array(
'label' => t('Module Path'),
'required' => true,
'value' => implode(':', Icinga::app()->getModuleManager()->getModuleDirs()),
'description' => t(
'Contains the directories that will be searched for available modules, separated by '
. 'colons. Modules that don\'t exist in these directories can still be symlinked in '
. 'the module folder, but won\'t show up in the list of disabled modules.'
),
'value' => realpath(ICINGAWEB_APPDIR . '/../modules')
)
)
);

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\General;
namespace Icinga\Forms\Config\General;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
@ -30,13 +30,13 @@ class LoggingConfigForm extends Form
'logging_log',
array(
'required' => true,
'class' => 'autosubmit',
'autosubmit' => true,
'label' => t('Logging Type'),
'description' => t('The type of logging to utilize.'),
'multiOptions' => array(
'syslog' => 'Syslog',
'file' => t('File'),
'none' => t('None')
'file' => t('File', 'app.config.logging.type'),
'none' => t('None', 'app.config.logging.type')
)
)
);
@ -50,16 +50,16 @@ class LoggingConfigForm extends Form
'label' => t('Logging Level'),
'description' => t('The maximum logging level to emit.'),
'multiOptions' => array(
Logger::$levels[Logger::ERROR] => t('Error'),
Logger::$levels[Logger::WARNING] => t('Warning'),
Logger::$levels[Logger::INFO] => t('Information'),
Logger::$levels[Logger::DEBUG] => t('Debug')
Logger::$levels[Logger::ERROR] => t('Error', 'app.config.logging.level'),
Logger::$levels[Logger::WARNING] => t('Warning', 'app.config.logging.level'),
Logger::$levels[Logger::INFO] => t('Information', 'app.config.logging.level'),
Logger::$levels[Logger::DEBUG] => t('Debug', 'app.config.logging.level')
)
)
);
}
if (isset($formData['logging_log']) && $formData['logging_log'] === 'syslog') {
if (false === isset($formData['logging_log']) || $formData['logging_log'] === 'syslog') {
$this->addElement(
'text',
'logging_application',

View File

@ -2,13 +2,12 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
namespace Icinga\Forms\Config;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Form\Config\General\LoggingConfigForm;
use Icinga\Form\Config\General\ApplicationConfigForm;
use Icinga\Forms\ConfigForm;
use Icinga\Forms\Config\General\LoggingConfigForm;
use Icinga\Forms\Config\General\ApplicationConfigForm;
/**
* Form class for application-wide and logging specific settings
@ -38,7 +37,7 @@ class GeneralConfigForm extends ConfigForm
/**
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
$sections = array();
foreach ($this->getValues() as $sectionAndPropertyName => $value) {
@ -62,7 +61,7 @@ class GeneralConfigForm extends ConfigForm
/**
* @see Form::onRequest()
*/
public function onRequest(Request $request)
public function onRequest()
{
$values = array();
foreach ($this->config as $section => $properties) {

View File

@ -2,14 +2,13 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
namespace Icinga\Forms\Config\Resource;
use Exception;
use Icinga\Application\Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Form\Element\Number;
use Icinga\Data\ResourceFactory;
use Icinga\Application\Platform;
/**
* Form class for adding/modifying database resources
@ -29,6 +28,23 @@ class DbResourceForm extends Form
*/
public function createElements(array $formData)
{
$dbChoices = array();
if (Platform::zendClassExists('Zend_Db_Adapter_Pdo_Mysql')) {
$dbChoices['mysql'] = 'MySQL';
}
if (Platform::zendClassExists('Zend_Db_Adapter_Pdo_Pgsql')) {
$dbChoices['pgsql'] = 'PostgreSQL';
}
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Resource Name'),
'description' => t('The unique name of this resource')
)
);
$this->addElement(
'select',
'db',
@ -36,11 +52,7 @@ class DbResourceForm extends Form
'required' => true,
'label' => t('Database Type'),
'description' => t('The type of SQL database'),
'multiOptions' => array(
'mysql' => 'MySQL',
'pgsql' => 'PostgreSQL'
//'oracle' => 'Oracle'
)
'multiOptions' => $dbChoices
)
);
$this->addElement(
@ -54,14 +66,13 @@ class DbResourceForm extends Form
)
);
$this->addElement(
new Number(
array(
'required' => true,
'name' => 'port',
'label' => t('Port'),
'description' => t('The port to use'),
'value' => 3306
)
'number',
'port',
array(
'required' => true,
'label' => t('Port'),
'description' => t('The port to use'),
'value' => 3306
)
);
$this->addElement(
@ -101,9 +112,9 @@ class DbResourceForm extends Form
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (false === $this->isValidResource($this)) {
if (false === static::isValidResource($this)) {
return false;
}
}
@ -115,7 +126,7 @@ class DbResourceForm extends Form
*
* @return bool Whether validation succeeded or not
*/
public function isValidResource(Form $form)
public static function isValidResource(Form $form)
{
try {
$resource = ResourceFactory::createResource(new Config($form->getValues()));

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
namespace Icinga\Forms\Config\Resource;
use Icinga\Web\Form;
use Icinga\Web\Form\Validator\ReadablePathValidator;
@ -25,6 +25,15 @@ class FileResourceForm extends Form
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Resource Name'),
'description' => t('The unique name of this resource')
)
);
$this->addElement(
'text',
'filename',

View File

@ -2,13 +2,11 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
namespace Icinga\Forms\Config\Resource;
use Exception;
use Icinga\Application\Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Form\Element\Number;
use Icinga\Data\ResourceFactory;
/**
@ -29,6 +27,15 @@ class LdapResourceForm extends Form
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Resource Name'),
'description' => t('The unique name of this resource')
)
);
$this->addElement(
'text',
'hostname',
@ -40,14 +47,13 @@ class LdapResourceForm extends Form
)
);
$this->addElement(
new Number(
array(
'required' => true,
'name' => 'port',
'label' => t('Port'),
'description' => t('The port of the LDAP server to use for authentication'),
'value' => 389
)
'number',
'port',
array(
'required' => true,
'label' => t('Port'),
'description' => t('The port of the LDAP server to use for authentication'),
'value' => 389
)
);
$this->addElement(
@ -56,7 +62,7 @@ class LdapResourceForm extends Form
array(
'required' => true,
'label' => t('Root DN'),
'description' => t('The path where users can be found on the ldap server')
'description' => t('Only the root and its child nodes will be accessible on this resource.')
)
);
$this->addElement(
@ -87,9 +93,9 @@ class LdapResourceForm extends Form
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (false === $this->isValidResource($this)) {
if (false === static::isValidResource($this)) {
return false;
}
}
@ -101,11 +107,17 @@ class LdapResourceForm extends Form
*
* @return bool Whether validation succeeded or not
*/
public function isValidResource(Form $form)
public static function isValidResource(Form $form)
{
try {
$resource = ResourceFactory::createResource(new Config($form->getValues()));
$resource->connect();
if (false === $resource->testCredentials(
$form->getElement('bind_dn')->getValue(),
$form->getElement('bind_pw')->getValue()
)
) {
throw new Exception();
}
} catch (Exception $e) {
$form->addError(t('Connectivity validation failed, connection to the given resource not possible.'));
return false;

View File

@ -2,12 +2,11 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Resource;
namespace Icinga\Forms\Config\Resource;
use Exception;
use Icinga\Application\Config;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Application\Icinga;
use Icinga\Data\ResourceFactory;
@ -29,6 +28,15 @@ class LivestatusResourceForm extends Form
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Resource Name'),
'description' => t('The unique name of this resource')
)
);
$this->addElement(
'text',
'socket',
@ -48,9 +56,9 @@ class LivestatusResourceForm extends Form
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (false === $this->isValidResource($this)) {
if (false === static::isValidResource($this)) {
return false;
}
}
@ -62,7 +70,7 @@ class LivestatusResourceForm extends Form
*
* @return bool Whether validation succeeded or not
*/
public function isValidResource(Form $form)
public static function isValidResource(Form $form)
{
try {
$resource = ResourceFactory::createResource(new Config($form->getValues()));

View File

@ -2,16 +2,15 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
namespace Icinga\Forms\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Form\Config\Resource\DbResourceForm;
use Icinga\Form\Config\Resource\FileResourceForm;
use Icinga\Form\Config\Resource\LdapResourceForm;
use Icinga\Form\Config\Resource\LivestatusResourceForm;
use Icinga\Forms\ConfigForm;
use Icinga\Forms\Config\Resource\DbResourceForm;
use Icinga\Forms\Config\Resource\FileResourceForm;
use Icinga\Forms\Config\Resource\LdapResourceForm;
use Icinga\Forms\Config\Resource\LivestatusResourceForm;
use Icinga\Application\Platform;
use Icinga\Exception\ConfigurationError;
@ -128,17 +127,17 @@ class ResourceConfigForm extends ConfigForm
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
$resourceForm = $this->getResourceForm($this->getElement('type')->getValue());
if (method_exists($resourceForm, 'isValidResource') && false === $resourceForm->isValidResource($this)) {
if (method_exists($resourceForm, 'isValidResource') && false === $resourceForm::isValidResource($this)) {
$this->addElement($this->getForceCreationCheckbox());
return false;
}
}
$resource = $request->getQuery('resource');
$resource = $this->request->getQuery('resource');
try {
if ($resource === null) { // create new resource
$this->add($this->getValues());
@ -166,9 +165,9 @@ class ResourceConfigForm extends ConfigForm
*
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
*/
public function onRequest(Request $request)
public function onRequest()
{
$resource = $request->getQuery('resource');
$resource = $this->request->getQuery('resource');
if ($resource !== null) {
if ($resource === '') {
throw new ConfigurationError(t('Resource name missing'));
@ -220,15 +219,6 @@ class ResourceConfigForm extends ConfigForm
$resourceTypes['db'] = t('SQL Database');
}
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Resource Name'),
'description' => t('The unique name of this resource')
)
);
$this->addElement(
'select',
'type',

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
namespace Icinga\Forms;
use Exception;
use Icinga\Web\Form;

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
namespace Icinga\Forms;
use Icinga\Web\Form;

View File

@ -2,7 +2,7 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Dashboard;
namespace Icinga\Forms\Dashboard;
use Icinga\Application\Config;
use Icinga\Web\Widget\Dashboard;

View File

@ -0,0 +1,211 @@
<?php
namespace Icinga\Forms;
use Icinga\Application\Config;
use Icinga\Application\Logger;
use Icinga\Protocol\Ldap\Exception as LdapException;
use Icinga\Protocol\Ldap\Connection;
use Icinga\Protocol\Dns;
use Icinga\Web\Form;
/**
* Form class for application-wide and logging specific settings
*/
class LdapDiscoveryForm extends Form
{
/**
* The discovered server settings
*
* @var array
*/
private $capabilities = null;
/**
* The discovered root_dn
*
* @var null
*/
private $namingContext = null;
/**
* The working domain name
*
* @var null
*/
private $domain = null;
/**
* The working port name
*
* @var int
*/
private $port = 389;
/**
* Initialize this page
*/
public function init()
{
$this->setName('form_ldap_discovery');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'domain',
array(
'required' => true,
'label' => t('Search Domain'),
'description' => t('Search this domain for records of available servers.'),
)
);
if (false) {
$this->addElement(
'note',
'additional_description',
array(
'value' => t('No Ldap servers found on this domain.'
. ' You can try to specify host and port and try again, or just skip this step and '
. 'configure the server manually.'
)
)
);
$this->addElement(
'text',
'hostname',
array(
'required' => false,
'label' => t('Host'),
'description' => t('IP or host name to search.'),
)
);
$this->addElement(
'text',
'port',
array(
'required' => false,
'label' => t('Port'),
'description' => t('Port', 389),
)
);
}
return $this;
}
public function isValid($data)
{
if (false === parent::isValid($data)) {
return false;
}
if ($this->discover($this->getValue('domain'))) {
return true;
}
return true;
}
private function discover($domain)
{
// Attempt 1: Connect to the domain directly
if ($this->discoverCapabilities(array(
'hostname' => $domain,
'port' => 389)
)) {
return true;
}
// Attempt 2: Discover all available ldap dns records and connect to the first one
$cap = false;
$records = array_merge(Dns::getSrvRecords($domain, 'ldap'), Dns::getSrvRecords($domain, 'ldaps'));
if (isset($records[0])) {
$record = $records[0];
if (isset($record['port'])) {
$cap = $this->discoverCapabilities(array(
'hostname' => $record['target'],
'port' => $record['port']
));
} else {
$cap = $this->discoverCapabilities(array(
'hostname' => $record['target'],
'port' => 389
));
}
}
return $cap;
}
private function discoverCapabilities($config)
{
$conn = new Connection(new Config($config));
try {
$conn->connect();
$this->capabilities = $conn->getCapabilities();
$this->namingContext = $conn->getDefaultNamingContext();
$this->port = $config['port'];
$this->domain = $config['hostname'];
return true;
} catch (LdapException $e) {
Logger::info(
'Ldap discovery for ' . $config['hostname'] . ':' . $config['port'] . ' failed: ' . $e->getMessage()
);
return false;
}
}
public function suggestResourceSettings()
{
if (! isset($this->capabilities)) {
return array();
}
if ($this->capabilities->msCapabilities->ActiveDirectoryOid) {
return array(
'hostname' => $this->domain,
'port' => $this->port,
'root_dn' => $this->namingContext
);
} else {
return array(
'hostname' => $this->domain,
'port' => $this->port,
'root_dn' => $this->namingContext
);
}
}
public function hasSuggestion()
{
return isset($this->capabilities);
}
public function suggestBackendSettings()
{
if (! isset($this->capabilities)) {
return array();
}
if ($this->capabilities->msCapabilities->ActiveDirectoryOid) {
return array(
'base_dn' => $this->namingContext,
'user_class' => 'user',
'user_name_attribute' => 'sAMAccountName'
);
} else {
return array(
'base_dn' => $this->namingContext,
'user_class' => 'inetOrgPerson',
'user_name_attribute' => 'uid'
);
}
}
public function isAd()
{
return $this->capabilities->msCapabilities->ActiveDirectoryOid;
}
}

View File

@ -2,18 +2,18 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
namespace Icinga\Forms;
use Exception;
use DateTimeZone;
use Icinga\Application\Logger;
use Icinga\Authentication\Manager;
use Icinga\User\Preferences;
use Icinga\User\Preferences\PreferencesStore;
use Icinga\Util\TimezoneDetect;
use Icinga\Util\Translator;
use Icinga\Web\Form;
use Icinga\Web\Notification;
use Icinga\Web\Request;
use Icinga\Web\Session;
/**
@ -41,7 +41,6 @@ class PreferenceForm extends Form
public function init()
{
$this->setName('form_config_preferences');
$this->setSubmitLabel(t('Save Changes'));
}
/**
@ -76,7 +75,6 @@ class PreferenceForm extends Form
*/
public function save()
{
$this->store->load(); // Necessary for patching existing preferences
$this->store->save($this->preferences);
return $this;
}
@ -86,11 +84,13 @@ class PreferenceForm extends Form
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
public function onSuccess()
{
$this->preferences = new Preferences($this->store->load());
$webPreferences = $this->preferences->get('icingaweb', array());
foreach ($this->getValues() as $key => $value) {
if ($value === null) {
if ($value === null || $value === 'autodetect') {
if (isset($webPreferences[$key])) {
unset($webPreferences[$key]);
}
@ -100,14 +100,15 @@ class PreferenceForm extends Form
}
$this->preferences->icingaweb = $webPreferences;
// TODO: Is this even necessary in case the session is written on response?
$session = Session::getSession();
$session->user->setPreferences($this->preferences);
$session->write();
Session::getSession()->user->setPreferences($this->preferences);
try {
$this->save();
Notification::success(t('Preferences successfully saved'));
if ($this->getElement('btn_submit_preferences')->isChecked()) {
$this->save();
Notification::success(t('Preferences successfully saved'));
} else {
Notification::success(t('Preferences successfully saved for the current session'));
}
} catch (Exception $e) {
Logger::error($e);
Notification::error($e->getMessage());
@ -119,11 +120,19 @@ class PreferenceForm extends Form
*
* @see Form::onRequest()
*/
public function onRequest(Request $request)
public function onRequest()
{
$values = $this->preferences->get('icingaweb', array());
$values['browser_language'] = false === isset($values['language']);
$values['local_timezone'] = false === isset($values['timezone']);
$auth = Manager::getInstance();
$values = $auth->getUser()->getPreferences()->get('icingaweb');
if (! isset($values['language'])) {
$values['language'] = 'autodetect';
}
if (! isset($values['timezone'])) {
$values['timezone'] = 'autodetect';
}
$this->populate($values);
}
@ -133,72 +142,40 @@ class PreferenceForm extends Form
public function createElements(array $formData)
{
$languages = array();
$languages['autodetect'] = sprintf(t('Browser (%s)', 'preferences.form'), $this->getLocale());
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$tzList = array();
$tzList['autodetect'] = sprintf(t('Browser (%s)', 'preferences.form'), $this->getDefaultTimezone());
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$this->addElement(
'checkbox',
'browser_language',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'value' => true,
'label' => t('Use your browser\'s language suggestions')
)
);
$useBrowserLanguage = isset($formData['browser_language']) ? $formData['browser_language'] == 1 : true;
$languageSelection = $this->createElement(
'select',
'language',
array(
'required' => false === $useBrowserLanguage,
'required' => true,
'label' => t('Your Current Language'),
'description' => t('Use the following language to display texts and messages'),
'multiOptions' => $languages,
'value' => substr(setlocale(LC_ALL, 0), 0, 5)
)
);
if ($useBrowserLanguage) {
$languageSelection->setAttrib('disabled', 'disabled');
}
$this->addElement($languageSelection);
$this->addElement(
'checkbox',
'local_timezone',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'value' => true,
'label' => t('Use your local timezone')
)
);
$useLocalTimezone = isset($formData['local_timezone']) ? $formData['local_timezone'] == 1 : true;
$timezoneSelection = $this->createElement(
'select',
'timezone',
array(
'required' => false === $useLocalTimezone,
'required' => true,
'label' => t('Your Current Timezone'),
'description' => t('Use the following timezone for dates and times'),
'multiOptions' => $tzList,
'value' => $this->getDefaultTimezone()
)
);
if ($useLocalTimezone) {
$timezoneSelection->setAttrib('disabled', 'disabled');
}
$this->addElement($timezoneSelection);
$this->addElement(
'checkbox',
@ -208,6 +185,43 @@ class PreferenceForm extends Form
'label' => t('Use benchmark')
)
);
$this->addElement(
'submit',
'btn_submit_preferences',
array(
'ignore' => true,
'label' => t('Save to the Preferences'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'div'))
)
)
);
$this->addElement(
'submit',
'btn_submit_session',
array(
'ignore' => true,
'label' => t('Save for the current Session'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'div'))
)
)
);
$this->addDisplayGroup(
array('btn_submit_preferences', 'btn_submit_session'),
'submit_buttons',
array(
'decorators' => array(
'FormElements',
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group'))
)
)
);
}
/**
@ -221,7 +235,18 @@ class PreferenceForm extends Form
if ($detect->success()) {
return $detect->getTimezoneName();
} else {
return date_default_timezone_get();
return @date_default_timezone_get();
}
}
/**
* Return the preferred locale based on the given HTTP header and the available translations
*
* @return string
*/
protected function getLocale()
{
$locale = Translator::getPreferredLocaleCode($_SERVER['HTTP_ACCEPT_LANGUAGE']);
return $locale;
}
}

View File

@ -1,11 +1,10 @@
<div id="login">
<div class="logo">
<div class="image">
<img src="<?= $this->baseUrl('img/logo_icinga_big.png') ?>" alt="<?= t('The Icinga logo') ?>" >
<img class="fade-in one" src="<?= $this->baseUrl('img/logo_icinga_big.png') ?>" alt="<?= t('The Icinga logo') ?>" >
</div>
</div>
<div class="form" data-base-target="layout">
<h1><?= $this->translate('Icingaweb Login') ?></h1>
<?php
/* TODO: remove this as soon as notifications and forms are ready */
if (isset($this->errorInfo)): ?>
@ -14,6 +13,18 @@
</div>
<?php endif ?>
<?= $this->form ?>
<div class="footer">Icinga Web 2 &copy; 2013-2014 Icinga Team</div>
<div class="footer">Icinga Web 2 &copy; 2013-2014<br><a href="https://www.icinga.org">The Icinga Project</a></div>
<?php if ($configMissing): ?>
<div class="config-note"><?= sprintf(
t(
'You seem not to have Icinga Web 2 configured yet so it\'s not possible to log in without any defined '
. 'authentication method. Please define a authentication method by following the instructions in the'
. ' %1$sdocumentation%3$s or by using our %2$sweb-based setup-wizard%3$s.'
),
'<a href="http://docs.icinga.org/" title="Icinga Web 2 Documentation">', // TODO: Documentation link
'<a href="' . $this->href('setup') . '" title="Icinga Web 2 Setup-Wizard">',
'</a>'
); ?></div>
<?php endif ?>
</div>
</div>

View File

@ -4,8 +4,8 @@
<div class="content" data-base-target="_next">
<p>
<a href="<?= $this->href('/config/createAuthenticationBackend'); ?>">
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New Authentication Backend'); ?>
<?= $this->icon('plus'); ?><?= $this->translate('Create A New Authentication Backend'); ?>
</a>
</p>
<?= $form; ?>
</div>
</div>

View File

@ -1,5 +1,6 @@
<div class="controls">
<?= $this->tabs ?>
<h1><?= $this->escape($module->getTitle()) ?></h1>
</div>
<div class="content">
<?php if (! $module): ?>
@ -12,7 +13,6 @@ $permissions = $module->getProvidedPermissions();
$state = $moduleData->enabled ? ($moduleData->loaded ? 'enabled' : 'failed') : 'disabled'
?>
<h1><?= $this->escape($module->getTitle()) ?></h1>
<table class="avp">
<tr>
<th><?= $this->escape('Name') ?></th>

View File

@ -11,9 +11,9 @@
<tr>
<td>
<?php if ($module->enabled): ?>
<?= $this->icon('success.png', $this->translate('Module is enabled')) ?>
<?= $this->icon('thumbs-up', $this->translate('Module is enabled')) ?>
<?php else: ?>
<?= $this->icon('remove.png', $this->translate('Module is disabled')) ?>
<?= $this->icon('thumbs-down', $this->translate('Module is disabled')) ?>
<?php endif ?>
<a href="<?= $this->url(
'config/module/',

View File

@ -4,7 +4,7 @@
<div class="content" data-base-target="_next">
<p>
<a href="<?= $this->href('/config/createresource'); ?>">
<?= $this->icon('create.png'); ?> <?= $this->translate('Create A New Resource'); ?>
<?= $this->icon('plus'); ?> <?= $this->translate('Create A New Resource'); ?>
</a>
</p>
<table class="action">
@ -17,16 +17,16 @@
<tr>
<td>
<a href="<?= $this->href('config/editresource', array('resource' => $name)); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($name); ?>
<?= $this->icon('edit'); ?> <?= $this->escape($name); ?>
</a>
</td>
<td style="text-align: center">
<a href="<?= $this->href('config/removeresource', array('resource' => $name)); ?>">
<?= $this->icon('remove.png'); ?>
<?= $this->icon('minus'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>

View File

@ -11,23 +11,23 @@
<tr>
<td class="action">
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendNames[$i]); ?>
<?= $this->icon('edit'); ?> <?= $this->escape($backendNames[$i]); ?>
</a>
</td>
<td>
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('remove.png', $this->translate('Remove')); ?>
<?= $this->icon('minus', $this->translate('Remove')); ?>
</a>
</td>
<td>
<?php if ($i > 0): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf('%s|%s', $backendNames[$i], $i - 1); ?>">
<?= $this->icon('up.png', $this->translate('Move up in authentication order')); ?>
<?= $this->icon('up-big', $this->translate('Move up in authentication order')); ?>
</button>
<?php endif; ?>
<?php if ($i + 1 < count($backendNames)): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf('%s|%s', $backendNames[$i], $i + 1); ?>">
<?= $this->icon('down.png', $this->translate('Move down in authentication order')); ?>
<?= $this->icon('down-big', $this->translate('Move down in authentication order')); ?>
</button>
<?php endif; ?>
</td>
@ -37,4 +37,4 @@
</table>
<?= $form->getElement($form->getTokenElementName()); ?>
<?= $form->getElement($form->getUidElementName()); ?>
</form>
</form>

View File

@ -0,0 +1,99 @@
<?php
use Icinga\Web\Url;
if ($xAxisPaginator->count() <= 1 && $yAxisPaginator->count() <= 1) {
return; // Display this pagination only if there are multiple pages
}
$fromTo = t('%s: %d to %d of %d');
$xAxisPages = $xAxisPaginator->getPages('all');
$yAxisPages = $yAxisPaginator->getPages('all');
$totalYAxisPages = $yAxisPaginator->count();
$currentYAxisPage = $yAxisPaginator->getCurrentPageNumber();
$prevYAxisPage = $currentYAxisPage > 1 ? $currentYAxisPage - 1 : null;
$nextYAxisPage = $currentYAxisPage < $totalYAxisPages ? $currentYAxisPage + 1 : null;
$totalXAxisPages = $xAxisPaginator->count();
$currentXAxisPage = $xAxisPaginator->getCurrentPageNumber();
$prevXAxisPage = $currentXAxisPage > 1 ? $currentXAxisPage - 1 : null;
$nextXAxisPage = $currentXAxisPage < $totalXAxisPages ? $currentXAxisPage + 1 : null;
?>
<table class="joystick-pagination">
<tbody>
<tr>
<td>&nbsp;</td>
<td>
<?php if ($prevYAxisPage): ?>
<a target="_self" href="<?= Url::fromRequest()->overwriteParams(array(
'page' => $currentXAxisPage . ',' . $prevYAxisPage
))->getAbsoluteUrl(); ?>" title="<?= sprintf(
$fromTo,
t('Hosts'),
($prevYAxisPage - 1) * $yAxisPages->itemCountPerPage + 1,
$prevYAxisPage * $yAxisPages->itemCountPerPage,
$yAxisPages->totalItemCount
); ?>"><?= $this->icon('up-open'); ?></a>
<?php else: ?>
<?= $this->icon('up-open'); ?>
<?php endif ?>
</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>
<?php if ($prevXAxisPage): ?>
<a target="_self" href="<?= Url::fromRequest()->overwriteParams(array(
'page' => $prevXAxisPage . ',' . $currentYAxisPage
))->getAbsoluteUrl(); ?>" title="<?= sprintf(
$fromTo,
t('Services'),
($prevXAxisPage - 1) * $xAxisPages->itemCountPerPage + 1,
$prevXAxisPage * $xAxisPages->itemCountPerPage,
$xAxisPages->totalItemCount
); ?>"><?= $this->icon('left-open'); ?></a>
<?php else: ?>
<?= $this->icon('left-open'); ?>
<?php endif ?>
</td>
<td>&nbsp;</td>
<td>
<?php if ($nextXAxisPage): ?>
<a target="_self" href="<?= Url::fromRequest()->overwriteParams(array(
'page' => $nextXAxisPage . ',' . $currentYAxisPage
))->getAbsoluteUrl(); ?>" title="<?= sprintf(
$fromTo,
t('Services'),
$currentXAxisPage * $xAxisPages->itemCountPerPage + 1,
$nextXAxisPage === $xAxisPages->last ? $xAxisPages->totalItemCount : $nextXAxisPage * $xAxisPages->itemCountPerPage,
$xAxisPages->totalItemCount
); ?>"><?= $this->icon('right-open'); ?></a>
<?php else: ?>
<?= $this->icon('right-open'); ?>
<?php endif ?>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<?php if ($nextYAxisPage): ?>
<a target="_self" href="<?= Url::fromRequest()->overwriteParams(array(
'page' => $currentXAxisPage . ',' . $nextYAxisPage
))->getAbsoluteUrl(); ?>" title="<?= sprintf(
$fromTo,
t('Hosts'),
$currentYAxisPage * $yAxisPages->itemCountPerPage + 1,
$nextYAxisPage === $yAxisPages->last ? $yAxisPages->totalItemCount : $nextYAxisPage * $yAxisPages->itemCountPerPage,
$yAxisPages->totalItemCount
); ?>"><?= $this->icon('down-open'); ?></a>
<?php else: ?>
<?= $this->icon('down-open'); ?>
<?php endif ?>
</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>

View File

@ -1,6 +1,9 @@
#!/usr/bin/php
<?php
use Icinga\Application\Cli;
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
require_once dirname(__DIR__) . '/library/Icinga/Application/Cli.php';
Cli::start()->dispatch();
Icinga\Application\Cli::start()->dispatch();

6
config/.gitignore vendored
View File

@ -1,6 +0,0 @@
authentication.ini
config.ini
modules/monitoring/backends.ini
modules/monitoring/instances.ini
resources.ini

View File

@ -1,29 +0,0 @@
; authentication.ini
;
; Each section listed in this configuration represents a backend used to authenticate users. The backend configurations
; must define a resource referring to a configured database or LDAP connection in the INI file resources.ini.
;
; The backends will be processed from top to bottom using the first backend for authentication which reports that
; the user trying to log in is available.
[autologin]
backend = autologin
;
; If you want to strip the domain
; strip_username_regexp = /\@[^$]+$/
[internal_ldap_authentication]
@ldap_auth_disabled@
backend = ldap
resource = internal_ldap
user_class = @ldap_user_objectclass@
user_name_attribute = @ldap_attribute_username@
group_base_dn = @ldap_group_base_dn@
group_attribute = @ldap_group_attribute@
group_member_attribute = @ldap_group_member_attribute@
group_class = @ldap_group_class@
[internal_db_authentication]
@internal_auth_disabled@
backend = db
resource = internal_db

View File

@ -1,41 +0,0 @@
[global]
timezone = "Europe/Berlin"
; Contains the directories that will be searched for available modules. Modules that
; don't exist in these directories can still be symlinked in the module folder, but
; won't show up in the list of disabled modules
; modulePath = "/vagrant/modules:/usr/share/icingaweb/modules"
[logging]
enable = true
; Writing to a Stream
type = "file"
; Write data to the following file
target = "@icingaweb_log_path@/icingaweb.log"
; Write data to a PHP stream
;target = "php://output"
; Writing to the System Log
;type = "syslog"
; Prefix all syslog messages generated with the string "icingaweb"
;application = "icingaweb"
;facility = "LOG_USER"
level = 1
; The default level is WARNING, which means that only events of this level and
; above will be tracked. Level numbers descend in order of importance where
; ERROR (0) is the most important level and DEBUG (3) is the least important
; level:
;
; ERROR = 0 - Error: error conditions
; WARNING = 1 - Warning: warning conditions
; INFO = 2 - Informational: informational messages
; DEBUG = 3 - Debug: debug messages
[preferences]
; Use INI file storage to save preferences to a local disk
type = "ini"
; Use database storage to save preferences in either a MySQL or PostgreSQL database
;type = db
;resource = icingaweb-mysql

View File

@ -1 +0,0 @@
Enabled modules shall be symlinked here.

View File

@ -1,4 +0,0 @@
# Use given CA file
TLS_REQCERT demand
TLS_CACERT @prefix@/config/ssl/cacerts/trusted.crt

View File

@ -1,4 +0,0 @@
# This config file will allow TLS-based LDAP connections ignoring
# unknown certificates
TLS_REQCERT never

View File

@ -1,9 +0,0 @@
[membership-set1]
backend = groupX
users = icingaadmin,tgelf
groups = admin,users
[membership-set2]
backend = groupY
users = icingaadmin
groups = support1,support2

View File

@ -1,19 +0,0 @@
[localdb]
@ido_enabled@
type = ido
resource = "ido"
[locallive]
@livestatus_enabled@
type = livestatus
resource = livestatus
[localfile]
@statusdat_enabled@
type = statusdat
resource = statusdat
;[localfailsafe]
;enabled=false
;type = combo
;backends = localdb, locallive, localfile

View File

@ -1,2 +0,0 @@
[security]
protected_customvars = "*pw*,*pass*,community"

View File

@ -1,2 +0,0 @@
[icinga]
path = "@icinga_commandpipe@"

View File

@ -1,11 +0,0 @@
[test1]
users = icingaadmin,root,tgelf
groups = support2,support2
permission_1 = monitoring, monitoring/log
permission_2 = monitoring/command/all
[test2]
users = root
groups = admin
permission_2 = test/permission/1, test/permission/2
permission_3 = test/permission/15, test/permission/7

View File

@ -1,55 +0,0 @@
; resources.ini
;
; The configuration file *resources.ini* contains data sources that
; can be referenced in other configurations. This allows you to manage
; all connections to SQL databases in one single place, avoiding the need
; to edit several different configuration files, when the connection
; information of a resource change.
;
; Each section represents a resource, with the section name being the
; identifier used to reference this certain section. Depending on the
; resource type, each section contains different properties. The property
; *type* defines the resource type and thus how the properties are going to
; be interpreted. Currently only the resource type *db* is available.
[internal_db]
type = db
db = @internal_db_type@
host = @internal_db_host@
port = @internal_db_port@
password = @internal_db_password@
username = @internal_db_user@
dbname = @internal_db_name@
[ido]
type = db
db = @ido_db_type@
host = @ido_host@
port = @ido_port@
password = @ido_password@
username = @ido_user@
dbname = @ido_db_name@
[statusdat]
type = statusdat
status_file = @statusdat_file@
object_file = @objects_cache_file@
[livestatus]
type = livestatus
socket = @livestatus_socket@
[internal_ldap]
type = ldap
hostname = @ldap_host@
port = @ldap_port@
root_dn = "@ldap_rootdn@"
bind_dn = "@ldap_binddn@"
bind_pw = @ldap_bindpass@
[logfile]
type = file
filename = "@icingaweb_log_path@/icingaweb.log"
fields = "/^(?<datetime>[0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}(\\+[0-9]{2}:[0-9]{2})?) - (?<loglevel>[A-Za-z]+) - (?<message>.*)$/"
; format: PCRE

View File

@ -1,16 +0,0 @@
[test1]
users = "user1"
groups = "no-such-group"
name = "monitoring/filter"
restriction = "hostgroup=lalala&service_description=*ping*"
[test2]
users = "user2"
name = "monitoring/filter"
restriction = "hostgroup=kunden*&service_description=*ping*"
[test3]
users = "user3"
name = "monitoring/filter"
restriction = "hostgroup=kunden*&service_description=*ping-ping*"

4125
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,448 +0,0 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.61])
AC_INIT([IcingaWeb2], [1.0.0], [info@icinga.org])
AC_PREFIX_DEFAULT(/usr/local/icingaweb)
if test "x$prefix" = "xNONE" ; then
installDir="/usr/local/icingaweb"
prefix=$installDir
else
installDir=$prefix
fi
# Checks for programs.
AC_PROG_INSTALL
AC_PROG_GREP
AC_PROG_SED
# Check for php
AC_ARG_VAR([PHP],[php cli binary])
AC_CHECK_PHP_INCLUDE([Zend/Application.php],[Zend Framework])
AC_CHECK_PHP_VERSION([5],[3],[0])
AC_CHECK_BIN([PHP], [php])
# Checks for libraries.
AC_CHECK_PHP_MODULE([sockets json])
#
# Configuration files
#
AC_ARG_WITH([icingaweb_config_path],
AS_HELP_STRING([--with-icingaweb-config-path=PATH], [Configuration path for icinga web (default $prefix/config)]),
icingaweb_config_path=$withval,
icingaweb_config_path=$prefix/config
)
#
# Log files
#
AC_ARG_WITH([icingaweb_log_path],
AS_HELP_STRING([--with-icingaweb-log-path=PATH], [Log path for icinga web (default $prefix/var/log)]),
icingaweb_log_path=$withval,
icingaweb_log_path=$prefix/var/log
)
#
# Users for webfiles
#
AC_ARG_WITH([web_user],
AS_HELP_STRING([--with-web-user=USER], [username for web writable files (default www-data)]),
web_user=$withval,
AC_USER_GUESS([www wwwrun www-data apache httpd nobody],[web_user],[www-data])
)
AC_ARG_WITH([web_group],
AS_HELP_STRING([--with-web-group=GROUP], [group for web writable files (default www-data)]),
web_group=$withval,
AC_GROUP_GUESS([www www-data apache httpd nogroup nobody],[web_group], [www-data])
)
AC_ARG_WITH([web_path],
AS_HELP_STRING([--with-web-path=PATH], [web sub path (default /icingaweb)]),
web_path=$withval,
web_path=/icingaweb
)
AC_ARG_WITH([httpd_config_path],
AS_HELP_STRING([--with-httpd-config-path=PATH], [Include folder apache2 (default /etc/apache2/conf.d)]),
httpd_config_path=$withval,
httpd_config_path=AC_PATH_GUESS([/etc/httpd/conf.d /etc/apache2/conf-available /etc/apache2/conf.d /etc/apache/conf.d], [httpd_config_path], [/etc/apache2/conf.d])
)
#
# Users and groups for installation
#
AC_ARG_WITH([bin_user],
AS_HELP_STRING([--with-bin-user=USER], [user for all other files (default root)]),
bin_user=$withval,
bin_user=root
)
AC_ARG_WITH([bin_group],
AS_HELP_STRING([--with-bin-group=GROUP], [group for all other files (default bin)]),
bin_group=$withval,
bin_group=bin
)
#
# Internal database setup
#
AC_ARG_WITH([internal_db_type],
AS_HELP_STRING([--with-internal-db-type=TYPE], [database type to use for internal database (default mysql, supported: pgsql, mysql)]),
internal_db_type=$withval,
internal_db_type=mysql
)
ICINGA_CHECK_DBTYPE($internal_db_type, [--with-internal-db-type])
AC_ARG_WITH([internal_db_name],
AS_HELP_STRING([--with-internal-db-name=NAME], [database name to use for internal database (default icingaweb)]),
internal_db_name=$withval,
internal_db_name=icingaweb
)
AC_ARG_WITH([internal_db_host],
AS_HELP_STRING([--with-internal-db-host=HOST], [database host to use for internal database (default localhost)]),
internal_db_host=$withval,
internal_db_host=localhost
)
AC_ARG_WITH([internal_db_port],
AS_HELP_STRING([--with-internal-db-port=PORT], [database port to use for internal database (default: 3306 for mysql, 5432 for pgsql)]),
internal_db_port=$withval,
internal_db_port=db_default_port
)
AC_ARG_WITH([internal_db_password],
AS_HELP_STRING([--with-internal-db-password=PASS], [database pass to use for internal database (default icingaweb)]),
internal_db_password=$withval,
internal_db_password=icingaweb
)
AC_ARG_WITH([internal_db_user],
AS_HELP_STRING([--with-internal-db-user=USER], [database user to use for internal database (default icingaweb)]),
internal_db_user=$withval,
internal_db_user=icingaweb
)
#
# Authorization method
#
AC_ARG_WITH([internal_authentication],
AC_HELP_STRING([--with-internal-authentication], [use the internal database for authentication (default: yes)]),
internal_authentication=$withval,
internal_authentication=yes
)
AC_ARG_WITH([ldap_authentication],
AC_HELP_STRING([--with-ldap-authentication], [use a ldap server for authentication (default: no)]),
ldap_authentication=$withval,
ldap_authentication=no
)
#
# LDAP Authorization
#
AC_ARG_WITH([ldap_host],
AS_HELP_STRING([--with-ldap-host=HOST], [host to use for authentication via ldap (default localhost)]),
ldap_host=$withval,
ldap_host=localhost
)
AC_ARG_WITH([ldap_port],
AS_HELP_STRING([--with-ldap-port=PORT], [port to use for authentication via ldap (default 389)]),
ldap_port=$withval,
ldap_port=389
)
AC_ARG_WITH([ldap_binddn],
AS_HELP_STRING([--with-ldap-binddn=DN], [dn to use for retrieving user information via ldap (default cn=admin, cn=config)]),
ldap_binddn=$withval,
ldap_binddn=["cn=admin,cn=config"]
)
AC_ARG_WITH([ldap_bindpass],
AS_HELP_STRING([--with-ldap-bindpass=PASS], [password to use for retrieving user information via ldap (default admin)]),
ldap_bindpass=$withval,
ldap_bindpass=["admin"]
)
AC_ARG_WITH([ldap_rootdn],
AS_HELP_STRING([--with-ldap-rootdn=LDAP_ATTRIBUTE], [root dn to use for user lookup (default ou=people, dc=icinga, dc=org)]),
ldap_rootdn=$withval,
ldap_rootdn=["ou=people, dc=icinga, dc=org"]
)
AC_ARG_WITH([ldap_user_objectclass],
AS_HELP_STRING([--with-ldap-user-objectclass=LDAP_OBJECT_CLASS], [ldap object class to use for user authentication (default: inetOrgPerson)]),
ldap_user_objectclass=$withval,
ldap_user_objectclass="inetOrgPerson"
)
AC_ARG_WITH([ldap_attribute_username],
AS_HELP_STRING([--with-ldap-attribute-username=LDAP_ATTRIBUTE], [user attribute to use for the username (default: uid)]),
ldap_attribute_username=$withval,
ldap_attribute_username="uid"
)
#
# Icinga backend selection
#
AC_ARG_WITH([icinga_backend],
AS_HELP_STRING([--with-icinga-backend=(ido, statusdat, livestatus)], [backend to use for rb (default: statusdat)]),
icinga_backend=$withval,
icinga_backend="statusdat"
)
ICINGA_CHECK_BACKENDTYPE($icinga_backend, [--with-icinga-backend])
#
# Ido settings
#
AC_ARG_WITH([ido_db_type],
AS_HELP_STRING([--with-ido-db-type=(mysql, pgsql)], [database engine to use for retrieving data from the ido db (default: mysql)]),
ido_db_type=$withval,
ido_db_type="mysql"
)
ICINGA_CHECK_DBTYPE($ido_db_type, [--with-ido-db-type])
AC_ARG_WITH([ido_host],
AS_HELP_STRING([--with-ido-host=HOST], [host to use for retrieving data from the ido db (default: localhost)]),
ido_host=$withval,
ido_host="localhost"
)
AC_ARG_WITH([ido_port],
AS_HELP_STRING([--with-ido-port=PORT], [backend to use for retrieving data from the ido db (default: 3306 for mysql. 5432 for pgsql)]),
ido_port=$withval,
ido_port=db_default_port
)
AC_ARG_WITH([ido_db_name],
AS_HELP_STRING([--with-ido-db-name=DATABASE], [database name to use for retrieving data from the ido db (default: icinga)]),
ido_db_name=$withval,
ido_db_name="icinga"
)
AC_ARG_WITH([ido_user],
AS_HELP_STRING([--with-ido-user=USER], [user to use for retrieving data from the ido db (default: icinga)]),
ido_user=$withval,
ido_user="icinga"
)
AC_ARG_WITH([ido_password],
AS_HELP_STRING([--with-ido-password=PASSWORD], [password to use for retrieving data from the ido db (default: icinga)]),
ido_password=$withval,
ido_password="icinga"
)
#
# Statusdat file location
#
AC_ARG_WITH([statusdat_file],
AS_HELP_STRING([--with-statusdat-file=FILE], [location of the status.dat file when retrieving data from status.dat (default: /usr/local/icinga/var/status.dat)]),
statusdat_file=$withval,
statusdat_file="/usr/local/icinga/var/status.dat"
)
AC_ARG_WITH([objects_cache_file],
AS_HELP_STRING([--with-objects-cache-file=FILE], [location of the objects.cache file when retrieving data from status.dat (default: /usr/local/icinga/var/objects.cache)]),
objects_cache_file=$withval,
objects_cache_file="/usr/local/icinga/var/objects.cache"
)
#
# Livestatus connection
#
AC_ARG_WITH([livestatus_socket],
AS_HELP_STRING([--with-livestatus-socket=FILE], [location of the livestatus socket (default: /usr/local/icinga/var/rw/live)]),
livestatus_socket=$withval,
livestatus_socket="/usr/local/icinga/var/rw/live"
)
#
# Icinga commandpipe
#
AC_ARG_WITH([icinga_commandpipe],
AS_HELP_STRING([--with-icinga-commandpipe=FILE], [location of the command pipe used for sending commands (default: /usr/local/icinga/var/rw/icinga.cmd)]),
icinga_commandpipe=$withval,
icinga_commandpipe="/usr/local/icinga/var/rw/icinga.cmd"
)
AC_ARG_WITH([objects_cache_file],
AS_HELP_STRING([--with-objects-file=FILE], [location of the objects.cache file when retrieving data from status.dat (default: /usr/local/icinga/var/objects.cache)]),
objects_cache_file=$withval,
objects_cache_file="/usr/local/icinga/var/objects.cache"
)
#
# Livestatus connection
#
AC_ARG_WITH([livestatus_socket],
AS_HELP_STRING([--with-livestatus-socket=FILE], [location of the livestatus socket (default: /usr/local/icinga/var/rw/live)]),
livestatus_socket=$withval,
livestatus_socket="/usr/local/icinga/var/rw/live"
)
#
# Icinga commandpipe
#
AC_ARG_WITH([icinga_commandpipe],
AS_HELP_STRING([--with-icinga-commandpipe=FILE], [location of the command pipe used for sending commands (default: /usr/local/icinga/var/rw/icinga.cmd)]),
icinga_commandpipe=$withval,
icinga_commandpipe="/usr/local/icinga/var/rw/icinga.cmd"
)
# Installation options
INSTALL_OPTS="-o $bin_user -g $bin_group"
INSTALL_OPTS_WEB="-o $web_user -g $web_group"
AS_IF([test "x$internal_db_type" = xmysql], [
AC_CHECK_PHP_INCLUDE([Zend/Db/Adapter/Pdo/Mysql.php],[Zend Framework - MySQL PDO Adapter])
AC_CHECK_PHP_MODULE([mysql])
AS_IF([test "x$internal_db_port" == xdb_default_port], [internal_db_port=3306])
])
AS_IF([test "x$ido_db_type" = xmysql], [
AC_CHECK_PHP_INCLUDE([Zend/Db/Adapter/Pdo/Mysql.php],[Zend Framework - MySQL PDO Adapter])
AC_CHECK_PHP_MODULE([mysql])
AS_IF([test "x$ido_port" = xdb_default_port], [ido_port=3306])
])
AS_IF([test "x$internal_db_type" = xpgsql], [
AC_CHECK_PHP_INCLUDE([Zend/Db/Adapter/Pdo/Pgsql.php],[Zend Framework - PostgreSQL PDO Adapter])
AC_CHECK_PHP_MODULE([pgsql])
AS_IF([test "x$internal_db_port" = xdb_default_port], [internal_db_port=5432])
])
AS_IF([test "x$ido_db_type" = xpgsql], [
AC_CHECK_PHP_INCLUDE([Zend/Db/Adapter/Pdo/Pgsql.php],[Zend Framework - PostgreSQL PDO Adapter])
AC_CHECK_PHP_MODULE([pgsql])
AS_IF([test "x$ido_port" = xdb_default_port], [ido_port=5432])
])
#
# Disable authentication backends
#
ido_enabled="disabled = \"1\""
statusdat_enabled="disabled = \"1\""
livestatus_enabled="disabled = \"1\""
AS_CASE([$icinga_backend],
["ido"], [ido_enabled=""],
["statusdat"], [statusdat_enabled=""],
["livestatus"], [livestatus_enabled=""],
[statusdat_enabled=""])
ldap_auth_disabled="disabled = \"1\""
AS_IF([test "x$ldap_authentication" != xno],
AC_CHECK_PHP_MODULE([ldap])
ldap_auth_disabled=""
)
internal_auth_disabled="disabled = \"1\""
AS_IF([test "x$internal_authentication" != xno],
AC_CHECK_PHP_MODULE([ldap])
internal_auth_disabled=""
)
#
# Substitution variables
#
# Installation directives
AC_SUBST(app_name)
AC_SUBST(web_user)
AC_SUBST(web_group)
AC_SUBST(web_path)
AC_SUBST(httpd_config_path)
AC_SUBST(bin_user)
AC_SUBST(bin_group)
AC_SUBST(icingaweb_config_path)
AC_SUBST(icingaweb_log_path)
# Internal db setup
AC_SUBST(internal_db_type)
AC_SUBST(internal_db_name)
AC_SUBST(internal_db_host)
AC_SUBST(internal_db_port)
AC_SUBST(internal_db_user)
AC_SUBST(internal_db_password)
# ldap setup
AC_SUBST(ldap_host)
AC_SUBST(ldap_port)
AC_SUBST(ldap_rootdn)
AC_SUBST(ldap_binddn)
AC_SUBST(ldap_bindpass)
AC_SUBST(ldap_user_objectclass)
AC_SUBST(ldap_attribute_basedn)
AC_SUBST(ldap_attribute_username)
# backend setup
AC_SUBST(icinga_backend)
# ido backend variables
AC_SUBST(ido_enabled)
AC_SUBST(ido_db_type)
AC_SUBST(ido_host)
AC_SUBST(ido_port)
AC_SUBST(ido_db_name)
AC_SUBST(ido_user)
AC_SUBST(ido_password)
# status.dat backend
AC_SUBST(statusdat_enabled)
AC_SUBST(statusdat_file)
AC_SUBST(objects_cache_file)
# livestatus backend
AC_SUBST(livestatus_socket)
AC_SUBST(livestatus_enabled)
# command pipe
AC_SUBST(icinga_commandpipe)
# Comment placeholders for toggling backends
AC_SUBST(ldap_auth_disabled)
AC_SUBST(internal_auth_disabled)
# Application and installation
AC_SUBST(PHP)
AC_SUBST(INSTALL_OPTS)
AC_SUBST(INSTALL_OPTS_WEB)
#
# Create config files
#
AC_CONFIG_FILES([
Makefile
config/authentication.ini
config/config.ini
config/resources.ini
config/modules/monitoring/backends.ini
config/modules/monitoring/instances.ini
etc/apache/icingaweb.conf
])
#
# Commit and write
#
AC_OUTPUT

View File

View File

@ -1,27 +0,0 @@
# Create API documentation
## Prerequisites
You need phpDocumentor 2 installed on your system to create the api
documentation. Please visit [phpdoc's website](http://phpdoc.org/) for more
information. Additionally, the graphviz package is required to be installed.
## Configuration
phpDocumentator is configured with xml configuration reside in doc/phpdoc.xml.
In there you'll find the target path where the documentation is created as
html. Default location is doc/api/. Just point to index.html in this directory
with a browser.
If you generated the documentation already, you can follow [this link](apidoc/idnex.html).
## Generation
Change to Icinga Web 2 root directory (source tree) and run:
bin/createapidoc.sh
## Options for createapidoc.sh
--build Optional, silent build mode
--help Displays help message

View File

@ -1,198 +0,0 @@
# The Container Component (app/container)
The container component is the most basic building block for icingaweb. Even when displaying an empty controller,
you always have at least two containers in your viewport which are implicitly created: The main and the detail container.
Container handle the following tasks:
* Updating the url part responsible for the container
* Handling Url changes like they occur when the browser history is used by synchronizing their content with the
associated Url part
* Informing subcomponents about changes in the container
## The Container Api
You can find the sourcecode for containers along with jsdoc comments at *./public/js/icinga/components/container.js*.
Here we will discuss the most important calls and their synopsis:
### Accessing Containers:
The container component returns a 'Container' object which allows you to access responsible containers for dom nodes via
the following methods:
* using `new Container($myDomNodes)` which returns a stateless container object wrapping the container responsible for
the first node in $myDomNodes
* using `Container.getMainContainer()` or `Container.getDetailContainer()` which remove the main or detail container
(this one is stateful with a few notes, read on)
**Note:** `new Container($('#icingamain')) != Container.getMainContainer()`, but
`(new Container($('#icingamain'))).containerDom == Container.getMainContainer().containerDom`
** Example #1 getting the container responsible for a dom node **
**HTML**
<div id="icingamain">
<div class="myNode">
Some kind of node
</div>
<div id="somecontainer" data-icinga-component="app/container">
<div class="mySecondNode">
Some other kind of node
<p>
Insert your lorem ipsum here
</p>
</div>
</div>
</div>
**JS**:
require(['jquery', 'app/container'], function($, Container) {
var firstContainer = new Container($('.myNode')); // firstContainer wraps '#icingamain'
var mainContainer = Container.getMainContainer(); // also wraps '#icingamain'
var secondContainer = new Container($('.myNode p')); // #somecontainer is wrapped by secondContainer
firstContainer.someProperty = 'What a nice property!';
mainContainer.someState = 'I have some state';
console.log(firstContainer.someProperty); // return 'What a nice property'
console.log(main.someProperty); // return 'undefined'
console.log(Container.getMainContainer().someState) // return 'I have some state' when page hasn't been refreshed
});
## Containers And The Browser Url
As noted before (and indicated by the `getMainContainer()` and `getDetailContainer()` function), the main and detail
container have a special role. Considering the following Url:
http://my.monitoringhost.org/icingaweb/monitoring/list/host?page=4&detail=%2Fmonitoring%2Fshow%2Fhost%3Fhost%3Dlocalhost
This URL displays the 4th page of your host list in the main container (monitoring/list/host?page=4) and the host information
for localhost in the detail container (monitoring/show/host?host=localhost). When you split this Url up in logical pieces
it looks like this:
http://my.monitoringhost.org/icingaweb/monitoring/list/host?page=4&detail=%2Fmonitoring%2Fshow%2Fhost%3Fhost%3Dlocalhost
\___________ _______________________/\_________ ______________/ \_ ____/\________________ _______________________/
\/ \/ \/ \/
1. Base URL 2.Main container URL and Query 3.Detail param 4. Encoded detail URL and params
1. **Base URL** : I don't think this needs much explanation.
2. **Main container URL and query** : This is the *normal* part of your Url and denotes the controller route that is
being displayed in your main container
3. **Detail parameter**: This parameter will be ignored by the main container and used for rendering the detail container,
if omitted there's simple no detail view to be displayed
4 **Encoded detail URL**: The value of the "detail" parameter is the Url (without the base Url) that returns the content
of the detail area
### Updating A Container's Url
If you want your container to display content from a different Url, you can use the *replaceDomFromUrl()* on your
Container object:
**Example #2 Updating A Containers URL**
**HTML:**
<div id="icingamain">
<div id"mainSub"></div>
</div>
<div id="icingadetail">
<div id"detailSub"></div>
</div>
**JS:**
// this loads the page with the new main container
require(['jquery', 'app/container'], function($, Container) {
new Container('#mainSub').replaceDomFormUrl('/another/url');
}
// this loads the page with the new detail container
require(['jquery', 'app/container'], function($, Container) {
new Container('#detailSub').replaceDomFormUrl('/another/url');
}
// this does NOT work:
require(['jquery', 'app/container'], function($, Container) {
Container.getMainContainer().replaceDomFormUrl('/another/url');
// will never be reached due to a reload
Container.getMainContainer().replaceDomFormUrl('/another/url2');
}
// this loads the page with both main and detail changed (this is rarely needed and should be avoided)
require(['icinga', 'jquery', 'app/container'], function('Icinga', $, Container) {
// it's better to use this:
var mainContainer = Container.getMainContainer();
var detailContainer = Container.getDetailContainer();
mainContainer.updateContainerHref('/another/url'); // first update the main container href
detailContainer.updateContainerHref('/another/url2'); // update the detail href
var url = mainContainer.getContainerHref(detailContainer.getContainerHref()); // fetch the new url
Icinga.replaceBodyFromUrl(url); // and update manual
}
This results in the URL changing to './another/url?detail=%2Fanother%2Fdetail%2Furl.
The advantage of using a Container instance with the subelements (i.e. '\#mainSub') over calling getMain/DetailContainer
directly is that you don't need to know in what container your view is displayed - when you move 'mainSub' into the
detail container, the detail container would be updated afterwards.
**NOTE**: You should read the '...' section in order to understand why you shouldn't do it like in this example
### How container refresh states are handled
If you refresh containers content (load url or replace dom), the container displaya a loading
mask as default behaviour. To disable this mask and handle it yourself, you can register own events:
**Example #3 Load indicator events**
require(['icinga', 'jquery', 'app/container'], function('Icinga', $, Container) {
var mainContainer = Container.getMainContainer();
// Detach the default behaviour from container
mainContainer.removeDefaultLoadIndicator();
var showFunction = function() {
console.log('container is loading');
};
var hideFunction = function() {
console.log('container content refreshed');
};
// Install new handlers
mainContainer.registerOnShowLoadIndicator(showFunction);
mainContainer.registerOnHideLoadIndicator(hideFunction);
};
**Example #4 Use this for your components**
Please have a look into [components documentation](components.md) for detailed information about components.
define(['components/app/container', 'jquery', 'logging', 'URIjs/URI', 'URIjs/URITemplate'],
function(Container, $, logger, URI) {
"use strict";
/**
* Master/Detail grid component handling history, link behaviour, selection (@TODO 3788) and updates of
* grids
*
* @param {HTMLElement} The outer element to apply the behaviour on
*/
return function(gridDomNode) {
/**
* Constructor method for this component
*/
this.construct = function(target) {
// Container object for the component
this.container = new Container(target);
// Detach default handlers
this.container.removeDefaultLoadIndicator();
};
this.construct(gridDomNode);
};
};

View File

@ -74,8 +74,7 @@ create all database tables. You will find the installation guides for the differ
>
> RPM packages install the schema into /usr/share/doc/icingaweb-&lt;version&gt;/schema
bash$ mysql -u root -p icingaweb < etc/schema/accounts.mysql.sql
bash$ mysql -u root -p icingaweb < etc/schema/preferences.mysql.sql
bash$ mysql -u root -p icingaweb < etc/schema/mysql.sql
#### PostgreSQL
@ -108,8 +107,7 @@ And restart your database ('service postgresql restart' or '/etc/init.d/postgres
>
> RPM packages install the schema into /usr/share/doc/icingaweb-&lt;version&gt;/schema
bash$ psql -U icingaweb -a -f etc/schema/accounts.pgsql.sql
bash$ psql -U icingaweb -a -f etc/schema/preferences.pgsql.sql
bash$ psql -U icingaweb -a -f etc/schema/pgsql.sql

View File

@ -1 +0,0 @@
icingaweb.conf

View File

@ -1,32 +0,0 @@
Alias @web_path@ "@prefix@/public"
<Directory "@prefix@/public">
Options SymLinksIfOwnerMatch
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
<RequireAll>
Require all granted
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order allow,deny
Allow from all
</IfModule>
SetEnv ICINGAWEB_CONFIGDIR @icingaweb_config_path@
EnableSendfile Off
RewriteEngine on
RewriteBase @web_path@/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</Directory>

View File

@ -1,24 +0,0 @@
create table account (
`username` varchar(255) COLLATE latin1_general_ci NOT NULL,
`salt` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`active` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*
* user: icingaadmin
* password: icinga
*/
INSERT INTO account (
`username`,
`salt`,
`password`,
`active`
)
VALUES (
'icingaadmin',
'57cfd5746224be4f60c25d4e8514bec35ad2d01810723a138756b285898e71b2',
'43f8e0588eb39f1a41383b48def0b1fdc45e79b8f67194cccee4453eb3f4ea13',
1
);

View File

@ -1,28 +0,0 @@
create table "account" (
"username" character varying(255) NOT NULL,
"salt" character varying(255),
"password" character varying(255) NOT NULL,
"active" boolean
);
ALTER TABLE ONLY "account"
ADD CONSTRAINT account_pkey PRIMARY KEY ("username");
CREATE UNIQUE INDEX username_lower_unique_idx ON "account" USING btree (lower((username)::text));
/*
* user: icingaadmin
* password: icinga
*/
INSERT INTO "account" (
"username",
"salt",
"password",
"active"
)
VALUES (
'icingaadmin',
'57cfd5746224be4f60c25d4e8514bec35ad2d01810723a138756b285898e71b2',
'43f8e0588eb39f1a41383b48def0b1fdc45e79b8f67194cccee4453eb3f4ea13',
true
);

View File

@ -27,9 +27,10 @@ CREATE TABLE `icingaweb_user`(
CREATE TABLE `icingaweb_user_preference`(
`username` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`section` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`value` varchar(255) NOT NULL,
`ctime` timestamp NULL DEFAULT NULL,
`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`username`,`name`)
PRIMARY KEY (`username`,`section`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -0,0 +1,96 @@
/**
* Table "icingaweb_group"
*/
CREATE TABLE "icingaweb_group" (
"name" character varying(64) NOT NULL,
"parent" character varying(64) NULL DEFAULT NULL,
"ctime" timestamp NULL DEFAULT NULL,
"mtime" timestamp NULL DEFAULT NULL
);
ALTER TABLE ONLY "icingaweb_group"
ADD CONSTRAINT pk_icingaweb_group
PRIMARY KEY (
"name"
);
CREATE UNIQUE INDEX idx_icingaweb_group
ON "icingaweb_group"
USING btree (
lower((name)::text)
);
/**
* Table "icingaweb_group_membership"
*/
CREATE TABLE "icingaweb_group_membership" (
"group_name" character varying(64) NOT NULL,
"username" character varying(64) NOT NULL,
"ctime" timestamp NULL DEFAULT NULL,
"mtime" timestamp NULL DEFAULT NULL
);
ALTER TABLE ONLY "icingaweb_group_membership"
ADD CONSTRAINT pk_icingaweb_group_membership
PRIMARY KEY (
"group_name",
"username"
);
CREATE UNIQUE INDEX idx_icingaweb_group_membership
ON "icingaweb_group_membership"
USING btree (
lower((group_name)::text),
lower((username)::text)
);
/**
* Table "icingaweb_user"
*/
CREATE TABLE "icingaweb_user" (
"name" character varying(64) NOT NULL,
"active" smallint NOT NULL,
"password_hash" bytea NOT NULL,
"ctime" timestamp NULL DEFAULT NULL,
"mtime" timestamp NULL DEFAULT NULL
);
ALTER TABLE ONLY "icingaweb_user"
ADD CONSTRAINT pk_icingaweb_user
PRIMARY KEY (
"name"
);
CREATE UNIQUE INDEX idx_icingaweb_user
ON "icingaweb_user"
USING btree (
lower((name)::text)
);
/**
* Table "icingaweb_user_preference"
*/
CREATE TABLE "icingaweb_user_preference" (
"username" character varying(64) NOT NULL,
"name" character varying(64) NOT NULL,
"value" character varying(255) NOT NULL,
"ctime" timestamp NULL DEFAULT NULL,
"mtime" timestamp NULL DEFAULT NULL
);
ALTER TABLE ONLY "icingaweb_user_preference"
ADD CONSTRAINT pk_icingaweb_user_preference
PRIMARY KEY (
"username",
"name"
);
CREATE UNIQUE INDEX idx_icingaweb_user_preference
ON "icingaweb_user_preference"
USING btree (
lower((username)::text),
lower((name)::text)
);

View File

@ -1,6 +0,0 @@
create table `preference`(
`username` VARCHAR(255) COLLATE latin1_general_ci NOT NULL,
`key` VARCHAR(100) COLLATE latin1_general_ci NOT NULL,
`value` VARCHAR(255) NOT NULL,
PRIMARY KEY (`username`, `key`)
) ENGINE=InnoDB;

View File

@ -1,10 +0,0 @@
create table "preference"(
"username" VARCHAR(255) NOT NULL,
"key" VARCHAR(100) NOT NULL,
"value" VARCHAR(255) NOT NULL
);
ALTER TABLE ONLY "preference"
ADD CONSTRAINT preference_pkey PRIMARY KEY ("username", "key");
CREATE UNIQUE INDEX username_and_key_lower_unique_idx ON "preference" USING btree (lower((username)::text), lower((key)::text));

View File

@ -31,7 +31,7 @@
%define prefixdir %{_datadir}/%{name}
%define usermodparam -a -G
%define logdir %{_localstatedir}/log/%{name}
%define docdir %{sharedir}/log
%define docdir %{sharedir}/doc
%if "%{_vendor}" == "suse"
%define phpname php5
@ -179,7 +179,8 @@ install -D -m0644 packages/rpm/etc/httpd/conf.d/icingaweb.conf %{buildroot}/%{ap
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/modules/monitoring
%{__mkdir} -p %{buildroot}/%{_sysconfdir}/%{name}/enabledModules
%{__cp} -r application doc library modules public %{buildroot}/%{sharedir}/
# make sure to install local icingacli for setup wizard token generation & webserver config
%{__cp} -r application doc library modules public bin %{buildroot}/%{sharedir}/
## config
# authentication is db only
@ -194,8 +195,8 @@ install -D -m0644 packages/rpm/etc/%{name}/modules/monitoring/instances.ini %{bu
ln -s %{sharedir}/modules/monitoring %{buildroot}/%{_sysconfdir}/%{name}/enabledModules/monitoring
## config
# install icingacli
install -D -m0755 packages/rpm/usr/bin/icingacli %{buildroot}/usr/bin/icingacli
# symlink icingacli
ln -sf %{buildroot}/%{sharedir}/bin/icingacli %{buildroot}/usr/bin/icingacli
%pre
# Add apacheuser in the icingacmd group

View File

@ -1,520 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2009-04-28.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -6,6 +6,7 @@ namespace Icinga\Application;
use ErrorException;
use Exception;
use LogicException;
use Icinga\Application\Modules\Manager as ModuleManager;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
@ -39,6 +40,43 @@ use Icinga\Exception\IcingaException;
*/
abstract class ApplicationBootstrap
{
/**
* Base directory
*
* Parent folder for at least application, bin, modules, library/vendor and public
*
* @var string
*/
protected $baseDir;
/**
* Application directory
*
* @var string
*/
protected $appDir;
/**
* Vendor library directory
*
* @var string
*/
protected $vendorDir;
/**
* Library directory
*
* @var string
*/
protected $libDir;
/**
* Configuration directory
*
* @var string
*/
protected $configDir;
/**
* Icinga auto loader
*
@ -46,13 +84,6 @@ abstract class ApplicationBootstrap
*/
private $loader;
/**
* Library directory
*
* @var string
*/
private $libDir;
/**
* Config object
*
@ -60,20 +91,6 @@ abstract class ApplicationBootstrap
*/
protected $config;
/**
* Configuration directory
*
* @var string
*/
private $configDir;
/**
* Application directory
*
* @var string
*/
private $appDir;
/**
* Module manager
*
@ -97,27 +114,20 @@ abstract class ApplicationBootstrap
/**
* Constructor
*
* @param string $baseDir Icinga Web 2 base directory
* @param string $configDir Path to Icinga Web 2's configuration files
*/
protected function __construct($configDir = null)
protected function __construct($baseDir = null, $configDir = null)
{
if ($baseDir === null) {
$baseDir = dirname($this->getBootstrapDirectory());
}
$this->baseDir = $baseDir;
$this->appDir = $baseDir . '/application';
$this->vendorDir = $baseDir . '/library/vendor';
$this->libDir = realpath(__DIR__ . '/../..');
if (!defined('ICINGA_LIBDIR')) {
define('ICINGA_LIBDIR', $this->libDir);
}
if (defined('ICINGAWEB_APPDIR')) {
$this->appDir = ICINGAWEB_APPDIR;
} elseif (array_key_exists('ICINGAWEB_APPDIR', $_SERVER)) {
$this->appDir = $_SERVER['ICINGAWEB_APPDIR'];
} else {
$this->appDir = realpath($this->libDir. '/../application');
}
if (!defined('ICINGAWEB_APPDIR')) {
define('ICINGAWEB_APPDIR', $this->appDir);
}
if ($configDir === null) {
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
@ -129,7 +139,13 @@ abstract class ApplicationBootstrap
$this->configDir = $canonical ? $canonical : $configDir;
$this->setupAutoloader();
$this->setupZendAutoloader();
set_include_path(
implode(
PATH_SEPARATOR,
array($this->vendorDir, get_include_path())
)
);
Benchmark::measure('Bootstrap, autoloader registered');
@ -195,44 +211,6 @@ abstract class ApplicationBootstrap
return $this->isWeb;
}
/**
* Getter for application dir
*
* Optional append sub directory
*
* @param string $subdir optional subdir
*
* @return string
*/
public function getApplicationDir($subdir = null)
{
return $this->getDirWithSubDir($this->appDir, $subdir);
}
/**
* Getter for config dir
*
* @param string $subdir
*
* @return string
*/
public function getConfigDir($subdir = null)
{
return $this->getDirWithSubDir($this->configDir, $subdir);
}
/**
* Get the path to the bootstrapping directory.
*
* This is usually /public for Web and EmbeddedWeb
*
* @return string
*/
public function getBootstrapDirecory()
{
return dirname($_SERVER['SCRIPT_FILENAME']);
}
/**
* Helper to glue directories together
*
@ -251,15 +229,102 @@ abstract class ApplicationBootstrap
}
/**
* Starting concrete bootstrap classes
* Get the base directory
*
* @param string $configDir
* @param string $subDir Optional sub directory to get
*
* @return ApplicationBootstrap
* @return string
*/
public static function start($configDir = null)
public function getBaseDir($subDir = null)
{
$application = new static($configDir);
return $this->getDirWithSubDir($this->baseDir, $subDir);
}
/**
* Get the application directory
*
* @param string $subDir Optional sub directory to get
*
* @return string
*/
public function getApplicationDir($subDir = null)
{
return $this->getDirWithSubDir($this->appDir, $subDir);
}
/**
* Get the vendor library directory
*
* @param string $subDir Optional sub directory to get
*
* @return string
*/
public function getVendorDir($subDir = null)
{
return $this->getDirWithSubDir($this->vendorDir, $subDir);
}
/**
* Get the configuration directory
*
* @param string $subDir Optional sub directory to get
*
* @return string
*/
public function getConfigDir($subDir = null)
{
return $this->getDirWithSubDir($this->configDir, $subDir);
}
/**
* Get the Icinga library directory
*
* @param string $subDir Optional sub directory to get
*
* @return string
*/
public function getLibraryDir($subDir = null)
{
return $this->getDirWithSubDir($this->libDir, $subDir);
}
/**
* Get the path to the bootstrapping directory
*
* This is usually /public for Web and EmbeddedWeb and /bin for the CLI
*
* @return string
*
* @throws LogicException If the base directory can not be detected
*/
public function getBootstrapDirectory()
{
$script = $_SERVER['SCRIPT_FILENAME'];
$canonical = realpath($script);
if ($canonical !== false) {
$dir = dirname($canonical);
} elseif (substr($script, -14) === '/webrouter.php') {
// If Icinga Web 2 is served using PHP's built-in webserver with our webrouter.php script, the $_SERVER
// variable SCRIPT_FILENAME is set to DOCUMENT_ROOT/webrouter.php which is not a valid path to
// realpath but DOCUMENT_ROOT here still is the bootstrapping directory
$dir = dirname($script);
} else {
throw new LogicException('Can\'t detected base directory');
}
return $dir;
}
/**
* Start the bootstrap
*
* @param string $baseDir Icinga Web 2 base directory
* @param string $configDir Path to Icinga Web 2's configuration files
*
* @return static
*/
public static function start($baseDir = null, $configDir = null)
{
$application = new static($baseDir, $configDir);
$application->bootstrap();
return $application;
}
@ -283,7 +348,7 @@ abstract class ApplicationBootstrap
/**
* Register the Zend Autoloader
*
* @return self
* @return $this
*/
protected function setupZendAutoloader()
{
@ -291,17 +356,12 @@ abstract class ApplicationBootstrap
\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())
)
\Zend_Paginator::addScrollingStylePrefixPath(
'Icinga_Web_Paginator_ScrollingStyle_', $this->libDir . '/Icinga/Web/Paginator/ScrollingStyle'
);
return $this;
}
/**
* Setup module manager
*
@ -312,11 +372,26 @@ abstract class ApplicationBootstrap
$this->moduleManager = new ModuleManager(
$this,
$this->configDir . '/enabledModules',
explode(':', $this->config->fromSection('global', 'modulePath', ICINGAWEB_APPDIR . '/../modules'))
explode(':', $this->config->fromSection('global', 'modulePath', $this->baseDir . '/modules'))
);
return $this;
}
/**
* Load all core modules
*
* @return self
*/
protected function loadCoreModules()
{
try {
$this->moduleManager->loadCoreModules();
} catch (NotReadableError $e) {
Logger::error(new IcingaException('Cannot load core modules. An exception was thrown:', $e));
}
return $this;
}
/**
* Load all enabled modules
*
@ -357,12 +432,14 @@ abstract class ApplicationBootstrap
protected function loadConfig()
{
Config::$configDir = $this->configDir;
try {
$this->config = Config::app();
} catch (NotReadableError $e) {
Logger::error(new IcingaException('Cannot load application configuration. An exception was thrown:', $e));
$this->config = new Config();
}
return $this;
}
@ -382,6 +459,7 @@ abstract class ApplicationBootstrap
return false; // Continue with the normal error handler
}
switch($errno) {
case E_NOTICE:
case E_WARNING:
case E_STRICT:
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
@ -398,7 +476,7 @@ abstract class ApplicationBootstrap
*/
protected function setupLogger()
{
if (($loggingConfig = $this->config->get('logging')) !== null) {
if (($loggingConfig = $this->config->logging) !== null) {
try {
Logger::create($loggingConfig);
} catch (ConfigurationError $e) {
@ -428,42 +506,62 @@ abstract class ApplicationBootstrap
}
/**
* Setup default timezone
* Detect the timezone
*
* @return self
* @throws ConfigurationError if the timezone in config.ini isn't valid
* @return null|string
*/
protected function setupTimezone()
protected function detectTimezone()
{
$default = @date_default_timezone_get();
if (! $default) {
$default = 'UTC';
return null;
}
/**
* Set up the timezone
*
* @return $this
*/
protected final function setupTimezone()
{
$timezone = $this->detectTimeZone();
if ($timezone === null || @date_default_timezone_set($timezone) === false) {
$timezone = @date_default_timezone_get();
if ($timezone === false) {
$timezone = 'UTC';
date_default_timezone_set($timezone);
}
}
$timeZoneString = $this->config->fromSection('global', 'timezone', $default);
date_default_timezone_set($timeZoneString);
DateTimeFactory::setConfig(array('timezone' => $timeZoneString));
DateTimeFactory::setConfig(array('timezone' => $timezone));
return $this;
}
/**
* Setup internationalization using gettext
* Detect the locale
*
* Uses the preferred language sent by the browser or the default one
*
* @return self
* @return null|string
*/
protected function setupInternationalization()
protected function detectLocale()
{
return null;
}
/**
* Set up internationalization using gettext
*
* @return $this
*/
protected final function setupInternationalization()
{
if ($this->hasLocales()) {
Translator::registerDomain(Translator::DEFAULT_DOMAIN, $this->getLocaleDir());
}
$locale = $this->detectLocale();
if ($locale === null) {
$locale = Translator::DEFAULT_LOCALE;
}
try {
Translator::setupLocale(
isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])
? Translator::getPreferredLocaleCode($_SERVER['HTTP_ACCEPT_LANGUAGE'])
: Translator::DEFAULT_LOCALE
);
Translator::setupLocale($locale);
} catch (Exception $error) {
Logger::error($error);
}

View File

@ -43,7 +43,8 @@ class Cli extends ApplicationBootstrap
->parseBasicParams()
->setupLogger()
->setupResourceFactory()
->setupModuleManager();
->setupModuleManager()
->loadCoreModules();
}
protected function setupLogging()
@ -52,8 +53,7 @@ class Cli extends ApplicationBootstrap
new Config(
array(
'level' => Logger::INFO,
'log' => 'file',
'file' => 'php://stderr'
'log' => 'stdout',
)
)
);

View File

@ -27,7 +27,9 @@ class EmbeddedWeb extends ApplicationBootstrap
*/
protected function bootstrap()
{
return $this->loadConfig()
return $this
->setupZendAutoloader()
->loadConfig()
->setupErrorHandling()
->setupTimezone()
->setupModuleManager()

View File

@ -11,10 +11,18 @@ use Icinga\Application\Config;
*/
abstract class LogWriter
{
/**
* @var Zend_Config
*/
protected $config;
/**
* Create a new log writer initialized with the given configuration
*/
abstract public function __construct(Config $config);
public function __construct(Config $config)
{
$this->config = $config;
}
/**
* Log a message with the given severity

View File

@ -0,0 +1,50 @@
<?php
namespace Icinga\Application\Logger\Writer;
use Icinga\Cli\Screen;
use Icinga\Application\Logger\Logger;
use Icinga\Application\Logger\LogWriter;
use Zend_Config;
/**
* Class to write log messages to STDOUT
*/
class StdoutWriter extends LogWriter
{
protected $screen;
protected function screen()
{
if ($this->screen === null) {
$this->screen = Screen::instance();
}
return $this->screen;
}
/**
* Log a message with the given severity
*
* @param int $severity The severity to use
* @param string $message The message to log
*/
public function log($severity, $message)
{
$color = 'black';
switch ($severity) {
case Logger::$ERROR:
$color = 'red';
break;
case Logger::$WARNING:
$color = 'orange';
break;
case Logger::$INFO:
$color = 'green';
break;
case Logger::$DEBUG:
$color = 'blue';
break;
}
file_put_contents('php://stderr', $this->screen()->colorize($message, $color) . "\n");
}
}

View File

@ -67,6 +67,18 @@ class Manager
*/
private $modulePaths = array();
/**
* The core modules
*
* Core modules do not need to be enabled to load and cannot be disabled
* by the user. This must not be writable programmatically!
*
* @var array
*/
private $coreModules = array(
'setup'
);
/**
* Create a new instance of the module manager
*
@ -157,7 +169,21 @@ class Manager
}
/**
* Try to set all enabled modules in loaded sate
* Try to set all core modules in loaded state
*
* @return self
* @see Manager::loadModule()
*/
public function loadCoreModules()
{
foreach ($this->coreModules as $name) {
$this->loadModule($name);
}
return $this;
}
/**
* Try to set all enabled modules in loaded state
*
* @return self
* @see Manager::loadModule()
@ -211,6 +237,8 @@ class Manager
'Cannot enable module "%s". Module is not installed.',
$name
);
} elseif (in_array($name, $this->coreModules)) {
return $this;
}
clearstatcache(true);
@ -427,7 +455,7 @@ class Manager
}
$installed = $this->listInstalledModules();
foreach ($installed as $name) {
foreach (array_diff($installed, $this->coreModules) as $name) {
$info[$name] = (object) array(
'name' => $name,
'path' => $this->installedBaseDirs[$name],
@ -487,11 +515,14 @@ class Manager
/**
* Detect installed modules from every path provided in modulePaths
*
* @param array $availableDirs Installed modules location
*
* @return self
*/
public function detectInstalledModules()
public function detectInstalledModules(array $availableDirs = null)
{
foreach ($this->modulePaths as $basedir) {
$modulePaths = $availableDirs !== null ? $availableDirs : $this->modulePaths;
foreach ($modulePaths as $basedir) {
$canonical = realpath($basedir);
if ($canonical === false) {
Logger::warning('Module path "%s" does not exist', $basedir);
@ -528,4 +559,14 @@ class Manager
ksort($this->installedBaseDirs);
return $this;
}
/**
* Get the directories where to look for installed modules
*
* @return array
*/
public function getModuleDirs()
{
return $this->modulePaths;
}
}

View File

@ -17,6 +17,7 @@ use Icinga\Web\Hook;
use Icinga\Web\Menu;
use Icinga\Web\Widget;
use Icinga\Web\Widget\Dashboard\Pane;
use Icinga\Module\Setup\SetupWizard;
use Icinga\Util\File;
use Icinga\Exception\ProgrammingError;
use Icinga\Exception\IcingaException;
@ -133,6 +134,13 @@ class Module
*/
private $configTabs = array();
/**
* Provided setup wizard
*
* @var string
*/
private $setupWizard;
/**
* Icinga application
*
@ -641,6 +649,31 @@ class Module
return $tabs;
}
/**
* Whether this module provides a setup wizard
*
* @return bool
*/
public function providesSetupWizard()
{
$this->launchConfigScript();
if (class_exists($this->setupWizard)) {
$wizard = new $this->setupWizard;
return $wizard instanceof SetupWizard;
}
return false;
}
/**
* Return this module's setup wizard
*
* @return SetupWizard
*/
public function getSetupWizard()
{
return new $this->setupWizard;
}
/**
* Provide a named permission
@ -704,6 +737,19 @@ class Module
return $this;
}
/**
* Provide a setup wizard
*
* @param string $className The name of the class
*
* @return self
*/
protected function provideSetupWizard($className)
{
$this->setupWizard = $className;
return $this;
}
/**
* Register new namespaces on the autoloader
*
@ -717,7 +763,7 @@ class Module
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName, $moduleLibraryDir);
if (is_dir($this->getFormDir())) {
$this->app->getLoader()->registerNamespace(
'Icinga\\Module\\' . $moduleName. '\\Form',
'Icinga\\Module\\' . $moduleName. '\\Forms',
$this->getFormDir()
);
}

View File

@ -30,6 +30,16 @@ class Platform
*/
protected static $fqdn;
/**
* Return the operating system's name
*
* @return string
*/
public static function getOperatingSystemName()
{
return php_uname('s');
}
/**
* Test of windows
*
@ -37,7 +47,7 @@ class Platform
*/
public static function isWindows()
{
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
return strtoupper(substr(self::getOperatingSystemName(), 0, 3)) === 'WIN';
}
/**
@ -47,7 +57,7 @@ class Platform
*/
public static function isLinux()
{
return strtoupper(substr(PHP_OS, 0, 5)) === 'LINUX';
return strtoupper(substr(self::getOperatingSystemName(), 0, 5)) === 'LINUX';
}
/**
@ -116,7 +126,35 @@ class Platform
if (substr(self::$fqdn, 0, strlen(self::$hostname)) === self::$hostname) {
self::$domain = substr(self::$fqdn, strlen(self::$hostname) + 1);
} else {
self::$domain = array_shift(preg_split('~\.~', self::$hostname, 2));
$parts = preg_split('~\.~', self::$hostname, 2);
self::$domain = array_shift($parts);
}
}
/**
* Return the version of PHP
*
* @return string
*/
public static function getPhpVersion()
{
return phpversion();
}
/**
* Return the username PHP is running as
*
* @return string
*/
public static function getPhpUser()
{
if (static::isWindows()) {
return get_current_user(); // http://php.net/manual/en/function.get-current-user.php#75059
}
if (function_exists('posix_geteuid')) {
$userInfo = posix_getpwuid(posix_geteuid());
return $userInfo['name'];
}
}
@ -131,4 +169,32 @@ class Platform
{
return extension_loaded($extensionName);
}
/**
* Return the value for the given PHP configuration option
*
* @param string $option The option name for which to return the value
*
* @return string|false
*/
public static function getPhpConfig($option)
{
return ini_get($option);
}
/**
* Return whether the given Zend framework class exists
*
* @param string $name The name of the class to check
*
* @return bool
*/
public static function zendClassExists($name)
{
if (class_exists($name)) {
return true;
}
return (@include str_replace('_', '/', $name) . '.php') !== false;
}
}

View File

@ -7,6 +7,7 @@ namespace Icinga\Application;
require_once __DIR__ . '/ApplicationBootstrap.php';
use Icinga\Authentication\Manager as AuthenticationManager;
use Icinga\Authentication\Manager;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotReadableError;
use Icinga\Application\Logger;
@ -14,6 +15,8 @@ use Icinga\Util\TimezoneDetect;
use Icinga\Web\Request;
use Icinga\Web\Response;
use Icinga\Web\View;
use Icinga\Web\Session\Session as BaseSession;
use Icinga\Web\Session;
use Icinga\User;
use Icinga\Util\Translator;
use Icinga\Util\DateTimeFactory;
@ -58,6 +61,13 @@ class Web extends ApplicationBootstrap
*/
private $request;
/**
* Session object
*
* @var BaseSession
*/
private $session;
/**
* User object
*
@ -80,10 +90,12 @@ class Web extends ApplicationBootstrap
protected function bootstrap()
{
return $this
->setupZendAutoloader()
->setupLogging()
->setupErrorHandling()
->loadConfig()
->setupResourceFactory()
->setupSession()
->setupUser()
->setupTimezone()
->setupLogger()
@ -92,6 +104,7 @@ class Web extends ApplicationBootstrap
->setupZendMvc()
->setupFormNamespace()
->setupModuleManager()
->loadCoreModules()
->loadEnabledModules()
->setupRoute()
->setupPagination();
@ -163,6 +176,7 @@ class Web extends ApplicationBootstrap
$this->setupFrontController();
$this->setupViewRenderer();
return $this;
}
@ -182,6 +196,17 @@ class Web extends ApplicationBootstrap
return $this;
}
/**
* Initialize a session provider
*
* @return self
*/
private function setupSession()
{
$this->session = Session::create();
return $this;
}
/**
* Inject dependencies into request
*
@ -267,29 +292,19 @@ class Web extends ApplicationBootstrap
}
/**
* Setup user timezone if set and valid, otherwise global default timezone
*
* @return self
* @see ApplicationBootstrap::setupTimezone
* (non-PHPDoc)
* @see ApplicationBootstrap::detectTimezone() For the method documentation.
*/
protected function setupTimezone()
protected function detectTimezone()
{
$userTimezone = null;
if ($this->user !== null && $this->user->getPreferences() !== null) {
$auth = Manager::getInstance();
if (! $auth->isAuthenticated()
|| ($timezone = $auth->getUser()->getPreferences()->getValue('icingaweb', 'timezone')) === null
) {
$detect = new TimezoneDetect();
$userTimezone = $this->user->getPreferences()
->getValue('icingaweb', 'timezone', $detect->getTimezoneName());
$timezone = $detect->getTimezoneName();
}
try {
DateTimeFactory::setConfig(array('timezone' => $userTimezone));
date_default_timezone_set($userTimezone);
} catch (ConfigurationError $e) {
return parent::setupTimezone();
}
return $this;
return $timezone;
}
/**
@ -299,35 +314,30 @@ class Web extends ApplicationBootstrap
*
* @return self
*/
protected function setupInternationalization()
protected function detectLocale()
{
parent::setupInternationalization();
if ($this->user !== null && $this->user->getPreferences() !== null
&& (($locale = $this->user->getPreferences()->getValue('icingaweb', 'language')) !== null)
$auth = Manager::getInstance();
if (! $auth->isAuthenticated()
|| ($locale = $auth->getUser()->getPreferences()->getValue('icingaweb', 'language')) === null
&& isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])
) {
try {
Translator::setupLocale($locale);
} catch (Exception $error) {
Logger::warning(
'Cannot set locale "' . $locale . '" configured in ' .
'preferences of user "' . $this->user->getUsername() . '"'
);
}
$locale = Translator::getPreferredLocaleCode($_SERVER['HTTP_ACCEPT_LANGUAGE']);
}
return $this;
return $locale;
}
/**
* Setup an autoloader namespace for Icinga\Form
* Setup an autoloader namespace for Icinga\Forms
*
* @return self
*/
private function setupFormNamespace()
{
$this->getLoader()->registerNamespace(
'Icinga\\Form',
'Icinga\\Forms',
$this->getApplicationDir('forms')
);
return $this;
}
}
// @codeCoverageIgnoreEnd

View File

@ -54,7 +54,7 @@ class AutoLoginBackend extends UserBackend
if (isset($_SERVER['REMOTE_USER'])) {
$username = $_SERVER['REMOTE_USER'];
$user->setRemoteUserInformation($username, 'REMOTE_USER');
if ($this->stripUsernameRegexp !== null) {
if ($this->stripUsernameRegexp) {
$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

View File

@ -4,6 +4,7 @@
namespace Icinga\Authentication\Backend;
use PDO;
use Icinga\Authentication\UserBackend;
use Icinga\Data\Db\DbConnection;
use Icinga\User;
@ -11,16 +12,29 @@ use Icinga\Exception\AuthenticationException;
use Exception;
use Zend_Db_Expr;
use Zend_Db_Select;
use Icinga\Exception\IcingaException;
class DbUserBackend extends UserBackend
{
/**
* The algorithm to use when hashing passwords
*
* @var string
*/
const HASH_ALGORITHM = '$1$'; // MD5
/**
* The length of the salt to use when hashing a password
*
* @var int
*/
const SALT_LENGTH = 12; // 12 is required by MD5
/**
* Connection to the database
*
* @var DbConnection
*/
private $conn;
protected $conn;
public function __construct(DbConnection $conn)
{
@ -36,45 +50,69 @@ class DbUserBackend extends UserBackend
*/
public function hasUser(User $user)
{
$select = new Zend_Db_Select($this->conn->getConnection());
$row = $select->from('account', array(new Zend_Db_Expr(1)))
->where('username = ?', $user->getUsername())
$select = new Zend_Db_Select($this->conn->getDbAdapter());
$row = $select->from('icingaweb_user', array(new Zend_Db_Expr(1)))
->where('name = ?', $user->getUsername())
->query()->fetchObject();
return ($row !== false) ? true : false;
}
/**
* Authenticate the given user and return true on success, false on failure and null on error
* Add a new user
*
* @param string $username The name of the new user
* @param string $password The new user's password
* @param bool $active Whether the user is active
*/
public function addUser($username, $password, $active = true)
{
$passwordHash = $this->hashPassword($password);
$stmt = $this->conn->getDbAdapter()->prepare(
'INSERT INTO icingaweb_user VALUES (:name, :active, :password_hash, now(), DEFAULT);'
);
$stmt->bindParam(':name', $username, PDO::PARAM_STR);
$stmt->bindParam(':active', $active, PDO::PARAM_INT);
$stmt->bindParam(':password_hash', $passwordHash, PDO::PARAM_LOB);
$stmt->execute();
}
/**
* Fetch the hashed password for the given user
*
* @param string $username The name of the user
*
* @return string
*/
protected function getPasswordHash($username)
{
$stmt = $this->conn->getDbAdapter()->prepare(
'SELECT password_hash FROM icingaweb_user WHERE name = :name AND active = 1'
);
$stmt->execute(array(':name' => $username));
$stmt->bindColumn(1, $lob, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
return is_resource($lob) ? stream_get_contents($lob) : $lob;
}
/**
* Authenticate the given user and return true on success, false on failure and throw an exception on error
*
* @param User $user
* @param string $password
*
* @return bool|null
* @return bool
*
* @throws AuthenticationException
*/
public function authenticate(User $user, $password)
{
try {
$salt = $this->getSalt($user->getUsername());
if ($salt === null) {
return false;
}
if ($salt === '') {
throw new IcingaException(
'Cannot find salt for user %s',
$user->getUsername()
);
}
$select = new Zend_Db_Select($this->conn->getConnection());
$row = $select->from('account', array(new Zend_Db_Expr(1)))
->where('username = ?', $user->getUsername())
->where('active = ?', true)
->where('password = ?', $this->hashPassword($password, $salt))
->query()->fetchObject();
return ($row !== false) ? true : false;
$passwordHash = $this->getPasswordHash($user->getUsername());
$passwordSalt = $this->getSalt($passwordHash);
$hashToCompare = $this->hashPassword($password, $passwordSalt);
return $hashToCompare === $passwordHash;
} catch (Exception $e) {
throw new AuthenticationException(
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
@ -86,29 +124,40 @@ class DbUserBackend extends UserBackend
}
/**
* Get salt by username
* Extract salt from the given password hash
*
* @param string $username
* @param string $hash The hashed password
*
* @return string|null
* @return string
*/
private function getSalt($username)
protected function getSalt($hash)
{
$select = new Zend_Db_Select($this->conn->getConnection());
$row = $select->from('account', array('salt'))->where('username = ?', $username)->query()->fetchObject();
return ($row !== false) ? $row->salt : null;
return substr($hash, strlen(self::HASH_ALGORITHM), self::SALT_LENGTH);
}
/**
* Return a random salt
*
* The returned salt is safe to be used for hashing a user's password
*
* @return string
*/
protected function generateSalt()
{
return openssl_random_pseudo_bytes(self::SALT_LENGTH);
}
/**
* Hash a password
*
* @param string $password
* @param string $salt
* @param string $password
* @param string $salt
*
* @return string
*/
private function hashPassword($password, $salt) {
return hash_hmac('sha256', $password, $salt);
protected function hashPassword($password, $salt = null)
{
return crypt($password, self::HASH_ALGORITHM . ($salt !== null ? $salt : $this->generateSalt()));
}
/**
@ -118,12 +167,29 @@ class DbUserBackend extends UserBackend
*/
public function count()
{
$select = new Zend_Db_Select($this->conn->getConnection());
$select = new Zend_Db_Select($this->conn->getDbAdapter());
$row = $select->from(
'account',
'icingaweb_user',
array('count' => 'COUNT(*)')
)->query()->fetchObject();
return ($row !== false) ? $row->count : 0;
}
/**
* Return the names of all available users
*
* @return array
*/
public function listUsers()
{
$query = $this->conn->select()->from('icingaweb_user', array('name'));
$users = array();
foreach ($query->fetchAll() as $row) {
$users[] = $row->name;
}
return $users;
}
}

View File

@ -4,7 +4,6 @@
namespace Icinga\Authentication\Backend;
use Icinga\Application\Logger;
use Icinga\User;
use Icinga\Authentication\UserBackend;
use Icinga\Protocol\Ldap\Connection;
@ -20,20 +19,36 @@ class LdapUserBackend extends UserBackend
**/
protected $conn;
protected $baseDn;
protected $userClass;
protected $userNameAttribute;
protected $groupOptions;
public function __construct(Connection $conn, $userClass, $userNameAttribute, $groupOptions = null)
public function __construct(Connection $conn, $userClass, $userNameAttribute, $baseDn, $groupOptions = null)
{
$this->conn = $conn;
$this->baseDn = trim($baseDn) !== '' ? $baseDn : $conn->getDN();
$this->userClass = $userClass;
$this->userNameAttribute = $userNameAttribute;
$this->groupOptions = $groupOptions;
}
/**
* @return \Icinga\Protocol\Ldap\Query
*/
protected function selectUsers()
{
return $this->conn->select()->setBase($this->baseDn)->from(
$this->userClass,
array(
$this->userNameAttribute
)
);
}
/**
* Create query
*
@ -41,14 +56,9 @@ class LdapUserBackend extends UserBackend
*
* @return \Icinga\Protocol\Ldap\Query
**/
protected function createQuery($username)
protected function selectUser($username)
{
return $this->conn->select()
->from(
$this->userClass,
array($this->userNameAttribute)
)
->where(
return $this->selectUsers()->where(
$this->userNameAttribute,
str_replace('*', '', $username)
);
@ -69,7 +79,7 @@ class LdapUserBackend extends UserBackend
public function assertAuthenticationPossible()
{
try {
$q = $this->conn->select()->from($this->userClass);
$q = $this->conn->select()->setBase($this->baseDn)->from($this->userClass);
$result = $q->fetchRow();
} catch (LdapException $e) {
throw new AuthenticationException('Connection not possible.', $e);
@ -79,7 +89,7 @@ class LdapUserBackend extends UserBackend
throw new AuthenticationException(
'No objects with objectClass="%s" in DN="%s" found.',
$this->userClass,
$this->conn->getDN()
$this->baseDn
);
}
@ -99,12 +109,12 @@ class LdapUserBackend extends UserBackend
*
* @param string $dn
*
* @return array|null
* @return array
*/
public function getGroups($dn)
{
if (empty($this->groupOptions) || ! isset($this->groupOptions['group_base_dn'])) {
return null;
return array();
}
$q = $this->conn->select()
@ -140,7 +150,7 @@ class LdapUserBackend extends UserBackend
public function hasUser(User $user)
{
$username = $user->getUsername();
return $this->conn->fetchOne($this->createQuery($username)) === $username;
return $this->conn->fetchOne($this->selectUser($username)) === $username;
}
/**
@ -173,7 +183,7 @@ class LdapUserBackend extends UserBackend
return false;
}
try {
$userDn = $this->conn->fetchDN($this->createQuery($user->getUsername()));
$userDn = $this->conn->fetchDN($this->selectUser($user->getUsername()));
$authenticated = $this->conn->testCredentials(
$userDn,
$password
@ -203,14 +213,20 @@ class LdapUserBackend extends UserBackend
*/
public function count()
{
return $this->conn->count($this->selectUsers());
}
return $this->conn->count(
$this->conn->select()->from(
$this->userClass,
array(
$this->userNameAttribute
)
)
);
/**
* Return the names of all available users
*
* @return array
*/
public function listUsers()
{
$users = array();
foreach ($this->selectUsers()->fetchAll() as $row) {
$users[] = $row->{$this->userNameAttribute};
}
return $users;
}
}

View File

@ -119,10 +119,7 @@ class Manager
*/
public function persistCurrentUser()
{
$session = Session::getSession();
$session->set('user', $this->user);
$session->write();
$session->refreshId();
Session::getSession()->set('user', $this->user)->refreshId();
}
/**

View File

@ -103,6 +103,7 @@ abstract class UserBackend implements Countable
$resource,
$backendConfig->get('user_class', 'user'),
$backendConfig->get('user_name_attribute', 'sAMAccountName'),
$backendConfig->get('base_dn', $resource->getDN()),
$groupOptions
);
break;
@ -129,6 +130,7 @@ abstract class UserBackend implements Countable
$resource,
$backendConfig->user_class,
$backendConfig->user_name_attribute,
$backendConfig->get('base_dn', $resource->getDN()),
$groupOptions
);
break;

View File

@ -66,7 +66,7 @@ class Loader
public function __construct(App $app)
{
$this->app = $app;
$this->coreAppDir = ICINGAWEB_APPDIR . '/clicommands';
$this->coreAppDir = $app->getApplicationDir('clicommands');
}
/**

View File

@ -216,7 +216,10 @@ class DbConnection implements Selectable
*/
public function fetchRow(DbQuery $query)
{
return $this->dbAdapter->fetchRow($query->getSelectQuery());
Benchmark::measure('DB is fetching row');
$result = $this->dbAdapter->fetchRow($query->getSelectQuery());
Benchmark::measure('DB row done');
return $result;
}
/**

View File

@ -72,6 +72,12 @@ class DbQuery extends SimpleQuery
parent::init();
}
public function setUseSubqueryCount($useSubqueryCount = true)
{
$this->useSubqueryCount = $useSubqueryCount;
return $this;
}
public function where($condition, $value = null)
{
// $this->count = $this->select = null;
@ -259,11 +265,13 @@ class DbQuery extends SimpleQuery
*/
public function getCountQuery()
{
// TODO: there may be situations where we should clone the "select"
// TODO: there may be situations where we should clone the "select"
$count = $this->dbSelect();
if ($this->group) {
$count->group($this->group);
}
$this->applyFilterSql($count);
if ($this->useSubqueryCount) {
if ($this->useSubqueryCount || $this->group) {
$count->columns($this->columns);
$columns = array('cnt' => 'COUNT(*)');
return $this->db->select()->from($count, $columns);

Some files were not shown because too many files have changed in this diff Show More