/** * Apply permissions, restrictions and roles to the given user * * @param User $user */ public function applyRoles(User $user) { $username = $user->getUsername(); try { $roles = Config::app('roles'); } catch (NotReadableError $e) { Logger::error('Can\'t get permissions and restrictions for user \'%s\'. An exception was thrown:', $username, $e); return; } $userGroups = $user->getGroups(); $permissions = array(); $restrictions = array(); $roleObjs = array(); foreach ($roles as $roleName => $role) { if ($this->match($username, $userGroups, $role)) { $permissionsFromRole = StringHelper::trimSplit($role->permissions); $permissions = array_merge($permissions, array_diff($permissionsFromRole, $permissions)); $restrictionsFromRole = $role->toArray(); unset($restrictionsFromRole['users']); unset($restrictionsFromRole['groups']); unset($restrictionsFromRole['permissions']); foreach ($restrictionsFromRole as $name => $restriction) { if (!isset($restrictions[$name])) { $restrictions[$name] = array(); } $restrictions[$name][] = $restriction; } $roleObj = new Role(); $roleObjs[] = $roleObj->setName($roleName)->setPermissions($permissionsFromRole)->setRestrictions($restrictionsFromRole); } } $user->setPermissions($permissions); $user->setRestrictions($restrictions); $user->setRoles($roleObjs); }
/** * Set the hook as failed w/ the given message * * @param string $message Error message or error format string * @param mixed ...$arg Format string argument */ private function fail($message) { $args = array_slice(func_get_args(), 1); $lastError = vsprintf($message, $args); Logger::debug($lastError); $this->lastError = $lastError; }
/** * Set the filter and render it internally. * * @param Filter $filter * * @return $this * * @throws ProgrammingError */ public function setFilter(Filter $filter) { $this->filter = $filter; $this->query = $this->renderFilter($this->filter); Logger::debug('Rendered elasticsearch filter: %s', json_encode($this->query)); return $this; }
/** * Append the given log entry and fail this inspection with the given error * * @param $entry string|Inspection A log entry or nested inspection * * @throws ProgrammingError When called multiple times * * @return this fluent interface */ public function error($entry) { if (isset($this->error)) { throw new ProgrammingError('Inspection object used after error'); } Logger::error($entry); $this->log[] = $entry; $this->error = $entry; return $this; }
/** * Display exception */ public function errorAction() { $error = $this->_getParam('error_handler'); $exception = $error->exception; /** @var \Exception $exception */ Logger::error($exception); Logger::error('Stacktrace: %s', $exception->getTraceAsString()); switch ($error->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: $modules = Icinga::app()->getModuleManager(); $path = ltrim($this->_request->get('PATH_INFO'), '/'); $path = preg_split('~/~', $path); $path = array_shift($path); $this->getResponse()->setHttpResponseCode(404); $this->view->message = $this->translate('Page not found.'); if ($this->Auth()->isAuthenticated() && $modules->hasInstalled($path) && !$modules->hasEnabled($path)) { $this->view->message .= ' ' . sprintf($this->translate('Enabling the "%s" module might help!'), $path); } break; default: switch (true) { case $exception instanceof HttpMethodNotAllowedException: $this->getResponse()->setHttpResponseCode(405); $this->getResponse()->setHeader('Allow', $exception->getAllowedMethods()); break; case $exception instanceof HttpNotFoundException: $this->getResponse()->setHttpResponseCode(404); break; case $exception instanceof MissingParameterException: $this->getResponse()->setHttpResponseCode(400); $this->getResponse()->setHeader('X-Status-Reason', 'Missing parameter ' . $exception->getParameter()); break; case $exception instanceof HttpBadRequestException: $this->getResponse()->setHttpResponseCode(400); break; case $exception instanceof SecurityException: $this->getResponse()->setHttpResponseCode(403); break; default: $this->getResponse()->setHttpResponseCode(500); break; } $this->view->message = $exception->getMessage(); if ($this->getInvokeArg('displayExceptions')) { $this->view->stackTrace = $exception->getTraceAsString(); } break; } if ($this->getRequest()->isApiRequest()) { $this->getResponse()->json()->setErrorMessage($this->view->message)->sendResponse(); } $this->view->request = $error->request; }
/** * Display the application log */ public function applicationlogAction() { if (!Logger::writesToFile()) { $this->httpNotFound('Page not found'); } $this->addTitleTab('application log'); $resource = new FileReader(new ConfigObject(array('filename' => Config::app()->get('logging', 'file'), '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>.*)(?!.)/msS'))); $this->view->logData = $resource->select()->order('DESC'); $this->setupLimitControl(); $this->setupPaginationControl($this->view->logData); }
/** * Parse the given query text and returns the json as expected by the semantic search box * * @param String $text The query to parse * @return array The result structure to be returned in json format */ private function parse($text, $target) { try { $queryTree = $this->registry->createQueryTreeForFilter($text); $registry = $this->moduleRegistry; return array('state' => 'success', 'proposals' => $this->registry->getProposalsForQuery($text), 'urlParam' => $registry::getUrlForTarget($target, $queryTree), 'valid' => count($this->registry->getIgnoredQueryParts()) === 0); } catch (\Exception $exc) { Logger::error($exc); $this->getResponse()->setHttpResponseCode(500); return array('state' => 'error', 'message' => 'Search service is currently not available'); } }
/** * Resolve a macro based on the given object * * @param string $macro The macro to resolve * @param MonitoredObject|stdClass $object The object used to resolve the macro * * @return string The new value or the macro if it cannot be resolved */ public static function resolveMacro($macro, $object) { if (isset(self::$icingaMacros[$macro]) && isset($object->{self::$icingaMacros[$macro]})) { return $object->{self::$icingaMacros[$macro]}; } try { $value = $object->{$macro}; } catch (Exception $e) { $value = null; Logger::debug('Unable to resolve macro "%s". An error occured: %s', $macro, $e); } return $value !== null ? $value : $macro; }
public function setAuthenticated(User $user, $persist = true) { $username = $user->getUsername(); try { $config = Config::app(); } catch (NotReadableError $e) { Logger::error(new IcingaException('Cannot load preferences for user "%s". An exception was thrown: %s', $username, $e)); $config = new Config(); } if ($config->get('preferences', 'store', 'ini') !== 'none') { $preferencesConfig = $config->getSection('preferences'); try { $preferencesStore = PreferencesStore::create($preferencesConfig, $user); $preferences = new Preferences($preferencesStore->load()); } catch (Exception $e) { Logger::error(new IcingaException('Cannot load preferences for user "%s". An exception was thrown: %s', $username, $e)); $preferences = new Preferences(); } } else { $preferences = new Preferences(); } $user->setPreferences($preferences); $groups = $user->getGroups(); foreach (Config::app('groups') as $name => $config) { try { $groupBackend = UserGroupBackend::create($name, $config); $groupsFromBackend = $groupBackend->getMemberships($user); } catch (Exception $e) { Logger::error('Can\'t get group memberships for user \'%s\' from backend \'%s\'. An exception was thrown: %s', $username, $name, $e); continue; } if (empty($groupsFromBackend)) { continue; } $groupsFromBackend = array_values($groupsFromBackend); $groups = array_merge($groups, array_combine($groupsFromBackend, $groupsFromBackend)); } $user->setGroups($groups); $admissionLoader = new AdmissionLoader(); list($permissions, $restrictions) = $admissionLoader->getPermissionsAndRestrictions($user); $user->setPermissions($permissions); $user->setRestrictions($restrictions); $this->user = $user; if ($persist) { $this->persistCurrentUser(); } }
/** * {@inheritdoc} */ protected function setupLogger() { $config = new ConfigObject(); $config->log = $this->params->shift('log', 'stderr'); if ($config->log === 'file') { $config->file = $this->params->shiftRequired('log-path'); } elseif ($config->log === 'syslog') { $config->application = 'icingacli'; } if ($this->params->get('verbose', false)) { $config->level = Logger::INFO; } elseif ($this->params->get('debug', false)) { $config->level = Logger::DEBUG; } else { $config->level = Logger::WARNING; } Logger::create($config); return $this; }
/** * Register all custom user backends from all loaded modules */ protected static function registerCustomUserBackends() { if (static::$customBackends !== null) { return; } static::$customBackends = array(); $providedBy = array(); foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $module) { foreach ($module->getUserBackends() as $identifier => $className) { if (array_key_exists($identifier, $providedBy)) { Logger::warning('Cannot register user backend of type "%s" provided by module "%s".' . ' The type is already provided by module "%s"', $identifier, $module->getName(), $providedBy[$identifier]); } elseif (in_array($identifier, static::$defaultBackends)) { Logger::warning('Cannot register user backend of type "%s" provided by module "%s".' . ' The type is a default type provided by Icinga Web 2', $identifier, $module->getName()); } else { $providedBy[$identifier] = $module->getName(); static::$customBackends[$identifier] = $className; } } } }
protected function addMessage($message, $type = 'info') { if (!in_array($type, array('info', 'error', 'warning', 'success'))) { throw new ProgrammingError('"%s" is not a valid notification type', $type); } if ($this->isCli) { $msg = sprintf('[%s] %s', $type, $message); switch ($type) { case 'info': case 'success': Logger::info($msg); break; case 'warning': Logger::warn($msg); break; case 'error': Logger::error($msg); break; } return; } $this->messages[] = (object) array('type' => $type, 'message' => $message); }
/** * Parse the given value based on the ASN.1 standard (GeneralizedTime) and return its timestamp representation * * @param string|null $value * * @return int */ protected function retrieveGeneralizedTime($value) { if ($value === null) { return $value; } if (($dateTime = DateTime::createFromFormat('YmdHis.uO', $value)) !== false || ($dateTime = DateTime::createFromFormat('YmdHis.uZ', $value)) !== false || ($dateTime = DateTime::createFromFormat('YmdHis.u', $value)) !== false || ($dateTime = DateTime::createFromFormat('YmdHis', $value)) !== false || ($dateTime = DateTime::createFromFormat('YmdHi', $value)) !== false || ($dateTime = DateTime::createFromFormat('YmdH', $value)) !== false) { return $dateTime->getTimeStamp(); } else { Logger::debug(sprintf('Failed to parse "%s" based on the ASN.1 standard (GeneralizedTime) in repository "%s".', $value, $this->getName())); } }
/** * Fetch and return all users from all user backends * * @return ArrayDatasource */ protected function fetchUsers() { $users = array(); foreach ($this->loadUserBackends('Icinga\\Data\\Selectable') as $backend) { try { foreach ($backend->select(array('user_name')) as $row) { $users[] = $row; } } catch (Exception $e) { Logger::error($e); Notification::warning(sprintf($this->translate('Failed to fetch any users from backend %s. Please check your log'), $backend->getName())); } } return new ArrayDatasource($users); }
/** * Create webserver configuration * * USAGE: * * icingacli setup config webserver <apache|nginx> [options] * * OPTIONS: * * --path=<urlpath> The URL path to Icinga Web 2 [/icingaweb2] * * --root|--document-root=<directory> The directory from which the webserver will serve files [/path/to/icingaweb2/public] * * --config=<directory> Path to Icinga Web 2's configuration files [/etc/icingaweb2] * * --file=<filename> Write configuration to file [stdout] * * EXAMPLES: * * icingacli setup config webserver apache * * icingacli setup config webserver apache --path=/icingaweb2 --document-root=/usr/share/icingaweb2/public --config=/etc/icingaweb2 * * icingacli setup config webserver apache --file=/etc/apache2/conf.d/icingaweb2.conf * * icingacli setup config webserver nginx */ public function webserverAction() { if (($type = $this->params->getStandalone()) === null) { $this->fail($this->translate('Argument type is mandatory.')); } try { $webserver = Webserver::createInstance($type); } catch (ProgrammingError $e) { $this->fail($this->translate('Unknown type') . ': ' . $type); } $urlPath = trim($this->params->get('path', $webserver->getUrlPath())); if (strlen($urlPath) === 0) { $this->fail($this->translate('The argument --path expects a URL path')); } $documentRoot = trim($this->params->get('root', $this->params->get('document-root', $webserver->getDocumentRoot()))); if (strlen($documentRoot) === 0) { $this->fail($this->translate('The argument --root/--document-root expects a directory from which the webserver will serve files')); } $configDir = trim($this->params->get('config', $webserver->getConfigDir())); if (strlen($configDir) === 0) { $this->fail($this->translate('The argument --config expects a path to Icinga Web 2\'s configuration files')); } $webserver->setDocumentRoot($documentRoot)->setConfigDir($configDir)->setUrlPath($urlPath); $config = $webserver->generate() . "\n"; if (($file = $this->params->get('file')) !== null) { if (file_exists($file) === true) { $this->fail(sprintf($this->translate('File %s already exists. Please delete it first.'), $file)); } Logger::info($this->translate('Write %s configuration to file: %s'), $type, $file); $re = file_put_contents($file, $config); if ($re === false) { $this->fail($this->translate('Could not write to file') . ': ' . $file); } Logger::info($this->translate('Successfully written %d bytes to file'), $re); return true; } echo $config; return true; }
/** * Log into the application */ public function loginAction() { $icinga = Icinga::app(); if ($icinga->setupTokenExists() && $icinga->requiresSetup()) { $this->redirectNow(Url::fromPath('setup')); } $triedOnlyExternalAuth = null; $auth = $this->Auth(); $this->view->form = $form = new LoginForm(); $this->view->title = $this->translate('Icingaweb Login'); try { $redirectUrl = $this->view->form->getValue('redirect'); if ($redirectUrl) { $redirectUrl = Url::fromPath($redirectUrl); } else { $redirectUrl = Url::fromPath('dashboard'); } if ($auth->isAuthenticated()) { $this->rerenderLayout()->redirectNow($redirectUrl); } try { $config = Config::app('authentication'); } catch (NotReadableError $e) { throw new ConfigurationError($this->translate('Could not read your authentication.ini, no authentication methods are available.'), 0, $e); } $chain = new AuthChain($config); $request = $this->getRequest(); if ($request->isPost() && $this->view->form->isValid($request->getPost())) { $user = new User($this->view->form->getValue('username')); $password = $this->view->form->getValue('password'); $backendsTried = 0; $backendsWithError = 0; $redirectUrl = $form->getValue('redirect'); if ($redirectUrl) { $redirectUrl = Url::fromPath($redirectUrl); } else { $redirectUrl = Url::fromPath('dashboard'); } foreach ($chain as $backend) { if ($backend instanceof ExternalBackend) { continue; } ++$backendsTried; try { $authenticated = $backend->authenticate($user, $password); } catch (AuthenticationException $e) { Logger::error($e); ++$backendsWithError; continue; } if ($authenticated === true) { $auth->setAuthenticated($user); $this->rerenderLayout()->redirectNow($redirectUrl); } } if ($backendsTried === 0) { $this->view->form->addError($this->translate('No authentication methods available. Did you create' . ' authentication.ini when setting up Icinga Web 2?')); } 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.')); } 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.')); } } 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) { $triedOnlyExternalAuth = $triedOnlyExternalAuth === null; if ($backend instanceof ExternalBackend) { $authenticated = $backend->authenticate($user); if ($authenticated === true) { $auth->setAuthenticated($user); $this->rerenderLayout()->redirectNow(Url::fromPath(Url::fromRequest()->getParam('redirect', 'dashboard'))); } } else { $triedOnlyExternalAuth = false; } } } } catch (Exception $e) { $this->view->form->addError($e->getMessage()); } $this->view->requiresExternalAuth = $triedOnlyExternalAuth && !$auth->isAuthenticated(); $this->view->requiresSetup = Icinga::app()->requiresSetup(); }
/** * 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($locale); } catch (Exception $error) { Logger::error($error); } return $this; }
/** * Return the form for the given type of navigation item * * @param string $type * * @return Form */ protected function getItemForm($type) { $className = StringHelper::cname($type, '-') . 'Form'; $form = null; foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $module) { $classPath = 'Icinga\\Module\\' . ucfirst($module->getName()) . '\\' . static::FORM_NS . '\\' . $className; if (class_exists($classPath)) { $form = new $classPath(); break; } } if ($form === null) { $classPath = 'Icinga\\' . static::FORM_NS . '\\' . $className; if (class_exists($classPath)) { $form = new $classPath(); } } if ($form === null) { Logger::debug('Failed to find custom navigation item form %s for item %s. Using form NavigationItemForm now', $className, $type); $form = new NavigationItemForm(); } elseif (!$form instanceof NavigationItemForm) { throw new ProgrammingError('Class %s must inherit from NavigationItemForm', $classPath); } return $form; }
/** * Return the app's menu * * @return Navigation */ public function getMenu() { if ($this->user !== null) { $menu = array('dashboard' => array('label' => t('Dashboard'), 'url' => 'dashboard', 'icon' => 'dashboard', 'priority' => 10), 'system' => array('label' => t('System'), 'icon' => 'services', 'priority' => 700, 'renderer' => array('SummaryNavigationItemRenderer', 'state' => 'critical'), 'children' => array('about' => array('label' => t('About'), 'url' => 'about', 'priority' => 701))), 'configuration' => array('label' => t('Configuration'), 'icon' => 'wrench', 'permission' => 'config/*', 'priority' => 800, 'children' => array('application' => array('label' => t('Application'), 'url' => 'config/general', 'permission' => 'config/application/*', 'priority' => 810), 'navigation' => array('label' => t('Shared Navigation'), 'url' => 'navigation/shared', 'permission' => 'config/application/navigation', 'priority' => 820), 'authentication' => array('label' => t('Authentication'), 'url' => 'config/userbackend', 'permission' => 'config/authentication/*', 'priority' => 830), 'roles' => array('label' => t('Roles'), 'url' => 'role/list', 'permission' => 'config/authentication/roles/show', 'priority' => 840), 'users' => array('label' => t('Users'), 'url' => 'user/list', 'permission' => 'config/authentication/users/show', 'priority' => 850), 'groups' => array('label' => t('Usergroups'), 'url' => 'group/list', 'permission' => 'config/authentication/groups/show', 'priority' => 860), 'modules' => array('label' => t('Modules'), 'url' => 'config/modules', 'permission' => 'config/modules', 'priority' => 890))), 'user' => array('label' => $this->user->getUsername(), 'icon' => 'user', 'priority' => 900, 'children' => array('preferences' => array('label' => t('Preferences'), 'url' => 'preference', 'priority' => 910), 'navigation' => array('label' => t('Navigation'), 'url' => 'navigation', 'priority' => 920), 'logout' => array('label' => t('Logout'), 'url' => 'authentication/logout', 'priority' => 990, 'renderer' => array('NavigationItemRenderer', 'target' => '_self'))))); if (Logger::writesToFile()) { $menu['system']['children']['application_log'] = array('label' => t('Application Log'), 'url' => 'list/applicationlog', 'priority' => 710); } } else { $menu = array(); } return Navigation::fromArray($menu)->load('menu-item'); }
/** * Check whether the current user backend is valid, i.e. it's enabled, not an external user backend and whether its * config is valid * * @return bool */ public function valid() { if (!$this->config->valid()) { // Stop when there are no more backends to check return false; } $backendConfig = $this->config->current(); if ((bool) $backendConfig->get('disabled', false)) { $this->next(); return $this->valid(); } $name = $this->key(); try { $backend = UserBackend::create($name, $backendConfig); } catch (ConfigurationError $e) { Logger::error(new ConfigurationError('Can\'t create authentication backend "%s". An exception was thrown:', $name, $e)); $this->next(); return $this->valid(); } if ($this->getSkipExternalBackends() && $backend instanceof ExternalBackend) { $this->next(); return $this->valid(); } $this->currentBackend = $backend; return true; }
/** * Adjust preferences and persist them * * @see Form::onSuccess() */ public function onSuccess() { $this->preferences = new Preferences($this->store ? $this->store->load() : array()); $webPreferences = $this->preferences->get('icingaweb', array()); foreach ($this->getValues() as $key => $value) { if ($value === null || $value === 'autodetect') { if (isset($webPreferences[$key])) { unset($webPreferences[$key]); } } else { $webPreferences[$key] = $value; } } $this->preferences->icingaweb = $webPreferences; Session::getSession()->user->setPreferences($this->preferences); try { if ($this->store && $this->getElement('btn_submit_preferences')->isChecked()) { $this->save(); Notification::success($this->translate('Preferences successfully saved')); } else { Notification::success($this->translate('Preferences successfully saved for the current session')); } } catch (Exception $e) { Logger::error($e); Notification::error($e->getMessage()); } }
/** * Order the result by the given column * * @param string $columnOrAlias The column or column alias to order by * @param int $dir The sort direction or null to use default direction * * @return $this Fluent interface */ public function order($columnOrAlias, $dir = null) { $this->requireColumn($columnOrAlias); $this->orderColumns[$columnOrAlias] = $columnOrAlias; if ($this->isCustomvar($columnOrAlias)) { $columnOrAlias = $this->getCustomvarColumnName($columnOrAlias); } elseif ($this->hasAliasName($columnOrAlias)) { $columnOrAlias = $this->aliasToColumnName($columnOrAlias); } else { Logger::info('Can\'t order by column ' . $columnOrAlias); return $this; } return parent::order($columnOrAlias, $dir); }
/** * Write the command to the local Icinga command file * * @param IcingaCommand $command * @param int|null $now * * @throws ConfigurationError * @throws CommandTransportException */ public function send(IcingaCommand $command, $now = null) { if (!isset($this->path)) { throw new ConfigurationError('Can\'t send external Icinga Command. Path to the local command file is missing'); } $commandString = $this->renderer->render($command, $now); Logger::debug('Sending external Icinga command "%s" to the local command file "%s"', $commandString, $this->path); try { $file = new File($this->path, $this->openMode); $file->fwrite($commandString . "\n"); } catch (Exception $e) { $message = $e->getMessage(); if ($e instanceof RuntimeException && ($pos = strrpos($message, ':')) !== false) { // Assume RuntimeException thrown by SplFileObject in the format: __METHOD__ . "({$filename}): Message" $message = substr($message, $pos + 1); } throw new CommandTransportException('Can\'t send external Icinga command to the local command file "%s": %s', $this->path, $message); } }
/** * Perform a LDAP search and return the result * * @param LdapQuery $query * @param array $attributes An array of the required attributes * @param int $attrsonly Should be set to 1 if only attribute types are wanted * @param int $sizelimit Enables you to limit the count of entries fetched * @param int $timelimit Sets the number of seconds how long is spend on the search * @param int $deref * * @return resource|bool A search result identifier or false on error * * @throws LogicException If the LDAP query search scope is unsupported */ public function ldapSearch(LdapQuery $query, array $attributes = null, $attrsonly = 0, $sizelimit = 0, $timelimit = 0, $deref = LDAP_DEREF_NEVER) { $queryString = (string) $query; $baseDn = $query->getBase() ?: $this->getDn(); $scope = $query->getScope(); if (Logger::getInstance()->getLevel() === Logger::DEBUG) { // We're checking the level by ourself to avoid rendering the ldapsearch commandline for nothing $starttlsParam = $this->encryption === static::STARTTLS ? ' -ZZ' : ''; $ldapUrl = ($this->encryption === static::LDAPS ? 'ldaps://' : 'ldap://') . $this->hostname . ($this->port ? ':' . $this->port : ''); if ($this->bound) { $bindParams = ' -D "' . $this->bindDn . '"' . ($this->bindPw ? ' -W' : ''); } if ($deref === LDAP_DEREF_NEVER) { $derefName = 'never'; } elseif ($deref === LDAP_DEREF_ALWAYS) { $derefName = 'always'; } elseif ($deref === LDAP_DEREF_SEARCHING) { $derefName = 'search'; } else { // $deref === LDAP_DEREF_FINDING $derefName = 'find'; } Logger::debug("Issueing LDAP search. Use '%s' to reproduce.", sprintf('ldapsearch -P 3%s -H "%s"%s -b "%s" -s "%s" -z %u -l %u -a "%s"%s%s%s', $starttlsParam, $ldapUrl, $bindParams, $baseDn, $scope, $sizelimit, $timelimit, $derefName, $attrsonly ? ' -A' : '', $queryString ? ' "' . $queryString . '"' : '', $attributes ? ' "' . join('" "', $attributes) . '"' : '')); } switch ($scope) { case LdapQuery::SCOPE_SUB: $function = 'ldap_search'; break; case LdapQuery::SCOPE_ONE: $function = 'ldap_list'; break; case LdapQuery::SCOPE_BASE: $function = 'ldap_read'; break; default: throw new LogicException('LDAP scope %s not supported by ldapSearch', $scope); } return @$function($this->getConnection(), $baseDn, $queryString, $attributes, $attrsonly, $sizelimit, $timelimit, $deref); }
/** * Create and return a new navigation item for the given configuration * * @param string $name * @param array|ConfigObject $properties * * @return NavigationItem * * @throws InvalidArgumentException If the $properties argument is neither an array nor a ConfigObject */ public function createItem($name, $properties) { if ($properties instanceof ConfigObject) { $properties = $properties->toArray(); } elseif (!is_array($properties)) { throw new InvalidArgumentException('Argument $properties must be of type array or ConfigObject'); } $itemType = isset($properties['type']) ? String::cname($properties['type'], '-') : 'NavigationItem'; if (!empty(static::$types) && isset(static::$types[$itemType])) { return new static::$types[$itemType]($name, $properties); } $item = null; foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $module) { $classPath = 'Icinga\\Module\\' . ucfirst($module->getName()) . '\\' . static::NAVIGATION_NS . '\\' . $itemType; if (class_exists($classPath)) { $item = new $classPath($name, $properties); break; } } if ($item === null) { $classPath = 'Icinga\\' . static::NAVIGATION_NS . '\\' . $itemType; if (class_exists($classPath)) { $item = new $classPath($name, $properties); } } if ($item === null) { Logger::debug('Failed to find custom navigation item class %s for item %s. Using base class NavigationItem now', $itemType, $name); $item = new NavigationItem($name, $properties); static::$types[$itemType] = 'Icinga\\Web\\Navigation\\NavigationItem'; } elseif (!$item instanceof NavigationItem) { throw new ProgrammingError('Class %s must inherit from NavigationItem', $classPath); } else { static::$types[$itemType] = $classPath; } return $item; }
/** * Return the app's menu * * @return Navigation */ public function getMenu() { if ($this->user !== null) { $menu = array('dashboard' => array('label' => t('Dashboard'), 'url' => 'dashboard', 'icon' => 'dashboard', 'priority' => 10), 'system' => array('label' => t('System'), 'icon' => 'services', 'priority' => 700, 'renderer' => array('SummaryNavigationItemRenderer', 'state' => 'critical'), 'children' => array('about' => array('label' => t('About'), 'url' => 'about', 'priority' => 700), 'announcements' => array('label' => t('Announcements'), 'url' => 'announcements', 'priority' => 710))), 'configuration' => array('label' => t('Configuration'), 'icon' => 'wrench', 'permission' => 'config/*', 'priority' => 800, 'children' => array('application' => array('label' => t('Application'), 'url' => 'config/general', 'permission' => 'config/application/*', 'priority' => 810), 'authentication' => array('label' => t('Authentication'), 'permission' => 'config/authentication/*', 'priority' => 830, 'url' => 'role/list'), 'navigation' => array('label' => t('Shared Navigation'), 'url' => 'navigation/shared', 'permission' => 'config/application/navigation', 'priority' => 840), 'modules' => array('label' => t('Modules'), 'url' => 'config/modules', 'permission' => 'config/modules', 'priority' => 890))), 'user' => array('cssClass' => 'user-nav-item', 'label' => $this->user->getUsername(), 'icon' => 'user', 'priority' => 900, 'children' => array('account' => array('label' => t('My Account'), 'priority' => 100, 'url' => 'account'), 'logout' => array('label' => t('Logout'), 'priority' => 200, 'attributes' => array('target' => '_self'), 'url' => 'authentication/logout')))); if (Logger::writesToFile()) { $menu['system']['children']['application_log'] = array('label' => t('Application Log'), 'url' => 'list/applicationlog', 'permission' => 'application/log', 'priority' => 900); } } else { $menu = array(); } return Navigation::fromArray($menu)->load('menu-item'); }
/** * Return this item rendered to HTML * * @return string */ public function render() { try { return $this->getRenderer()->setItem($this)->render(); } catch (Exception $e) { Logger::error('Could not invoke custom navigation item renderer. %s in %s:%d with message: %s', get_class($e), $e->getFile(), $e->getLine(), $e->getMessage()); $renderer = new NavigationItemRenderer(); return $renderer->render($this); } }
/** * Send the given command over an appropriate Icinga command transport * * This will try one configured transport after another until the command has been successfully sent. * * @param IcingaCommand $command The command to send * @param int|null $now Timestamp of the command or null for now * * @throws CommandTransportException If sending the Icinga command failed */ public function send(IcingaCommand $command, $now = null) { $tries = 0; foreach (static::getConfig() as $transportConfig) { $transport = static::createTransport($transportConfig); if ($this->transferPossible($command, $transport)) { try { $transport->send($command, $now); } catch (CommandTransportException $e) { Logger::error($e); $tries += 1; continue; // Try the next transport } return; // The command was successfully sent } } if ($tries > 0) { throw new CommandTransportException(mt('monitoring', 'Failed to send external Icinga command. None of the configured transports' . ' was able to transfer the command. Please see the log for more details.')); } throw new CommandTransportException(mt('monitoring', 'Failed to send external Icinga command. No transport has been configured' . ' for this instance. Please contact your Icinga Web administrator.')); }
/** * Extract and return one or more objects from the given data * * @param array $objectPath * @param array $fields * @param array $data * * @param object|array */ protected function extractObject(array $objectPath, array $fields, array $data) { if (!$this->isAssociative($data)) { $values = array(); foreach ($data as $value) { if (is_array($value)) { $objectValue = $this->extractObject($objectPath, $fields, $value); if (is_array($objectValue)) { $values = array_merge($values, $objectValue); } elseif ($objectValue !== null) { $values[] = $objectValue; } } else { Logger::debug('Expected non-scalar value but got "%s" instead', $value); } } return $values; } $object = array_shift($objectPath); if (isset($data[$object])) { if (!is_array($data[$object])) { Logger::debug('Expected non-scalar value but got "%s" instead', $data[$object]); } elseif (!empty($objectPath)) { return $this->extractObject($objectPath, $fields, $data[$object]); } elseif ($this->isAssociative($data[$object])) { $properties = array(); foreach ($fields as $alias => $field) { if (isset($field['object_path'])) { $properties[$alias] = $this->extractObject($field['object_path'], $field['fields'], $data[$object]); } else { $properties[$alias] = $this->extractScalar($field, $data[$object]); } } return (object) $properties; } else { $objects = array(); foreach ($data[$object] as $objectData) { $properties = array(); foreach ($fields as $alias => $field) { if (isset($field['object_path'])) { $properties[$alias] = $this->extractObject($field['object_path'], $field['fields'], $objectData); } else { $properties[$alias] = $this->extractScalar($field, $objectData); } } $objects[] = (object) $properties; } return $objects; } } }
/** * Create and return a data source to fetch all groups from all backends where the user is not already a member of * * @return ArrayDatasource */ protected function createDataSource() { $groups = $failures = array(); foreach ($this->backends as $backend) { try { $memberships = $backend->select()->from('group_membership', array('group_name'))->where('user_name', $this->userName)->fetchColumn(); foreach ($backend->select(array('group_name')) as $row) { if (!in_array($row->group_name, $memberships)) { // TODO(jom): Apply this as native query filter $row->backend_name = $backend->getName(); $groups[] = $row; } } } catch (Exception $e) { $failures[] = array($backend->getName(), $e); } } if (empty($groups) && !empty($failures)) { // In case there are only failures, throw the very first exception again throw $failures[0][1]; } elseif (!empty($failures)) { foreach ($failures as $failure) { Logger::error($failure[1]); Notification::warning(sprintf($this->translate('Failed to fetch any groups from backend %s. Please check your log'), $failure[0])); } } return new ArrayDatasource($groups); }