public function hookAdminMenu($type = 1) { switch ($type) { case 1: $gears = new Gears(GEARS, array('remove' => FALSE, 'charge' => TRUE)); new Menu_Tabs(array('name' => 'gears', 'elements' => array(array('label' => t('Все') . ' (' . $gears->count() . ')', 'link' => l('/admin/gears/')), array('label' => t('Активные') . ' (' . $gears->filter(Gears::ENABLED)->count() . ')', 'link' => l('/admin/gears/enabled')), array('label' => t('Неактивные') . ' (' . $gears->filter(Gears::DISABLED)->count() . ')', 'link' => l('/admin/gears/disabled')), array('label' => t('Ядро') . ' (' . $gears->filter(Gears::CORE)->count() . ')', 'link' => l('/admin/gears/core')), array('label' => icon('plus') . ' ' . t('Добавить'), 'class' => 'fl_r', 'link' => l('/admin/gears/add'))))); return $gears; break; case 2: new Menu_Pills(array('name' => 'gears.add', 'elements' => array(array('label' => icon('upload') . ' ' . t('Загрузить'), 'link' => l('/admin/gears/add'))))); break; } }
$script = ROOT . '/CommandLine/continuum.php'; /** * @security Make sure this is never compromised: */ \shell_exec('php -dphar.readonly=0 ' . \escapeshellarg($script) . ' >/dev/null 2>&1 &'); \file_put_contents(ROOT . '/tmp/last_update_check.txt', time()); } /** * Let's load the latest gear for our autoloader */ define('CABIN_NAME', $active['name']); define('CABIN_DIR', ROOT . '/Cabin/' . $active['name']); // Turn all of this cabins' Landings and Blueprints into gears: require ROOT . '/cabin_gears.php'; $lens->addGlobal('ACTIVE_CABIN', \CABIN_NAME); $autoPilot = Gears::get('AutoPilot', $active, $lens, $dbPool); if ($autoPilot instanceof AutoPilot) { $autoPilot->setActiveCabin($active, $state->active_cabin); } // Load everything else: require ROOT . '/symlinks.php'; require ROOT . '/motifs.php'; require ROOT . '/security.php'; require ROOT . '/email.php'; $state->autoPilot = $autoPilot; /** * Final step: Let's turn on the autopilot */ if (!empty($state->universal['debug'])) { try { \error_reporting(E_ALL);
if (\file_exists(ROOT . '/config/Cabin/' . $active['name'] . '/twig_vars.json')) { $_settings = \Airship\loadJSON(ROOT . '/config/Cabin/' . $active['name'] . '/twig_vars.json'); $lens->addGlobal('SETTINGS', $_settings); } // Now let's load all the lens.php files, which are added by Gadgets: foreach ($lensLoad as $incl) { include $incl; } /** * Let's load up the databases */ $dbPool = []; require ROOT . '/database.php'; // Airship manifest: $manifest = \Airship\loadJSON(ROOT . '/config/manifest.json'); $state->manifest = $manifest; $htmlpurifier = new \HTMLPurifier(\HTMLPurifier_Config::createDefault()); $state->HTMLPurifier = $htmlpurifier; /** * Load up all of the keys used by the application: */ require_once ROOT . '/keys.php'; /** * Set up the logger */ require_once ROOT . '/config/logger.php'; /** * Automatic security updates */ $hail = Gears::get('Hail', new HTTPClient($state->universal['guzzle'])); $state->hail = $hail;
<?php $gears = new Gears(GEARS, array('remove' => FALSE, 'charge' => TRUE)); ?> <div id="system"> <b><?php echo t('Версия системы: '); ?> </b> <?php echo COGEAR; ?> <br/> <b><?php echo t('Последнее обновление: '); ?> </b> <?php echo date('H:i d.m.Y', filemtime(ROOT . DS . 'index' . EXT)); ?> <br/> <div class="well"> <span class="left"><b><?php echo t('Всего шестерёнок: '); ?> </b></span><span class="right"><?php echo HTML::a(l('/admin/gears/'), $gears->count(), array('class' => 'label')); ?> </span> <span class="left"><b><?php echo t('Активных: '); ?> </b></span><span class="right"><?php
/** * Process account recovery * * @param array $post * @return bool */ protected function processRecoverAccount(array $post) : bool { $username = $post['forgot_passphrase_for']; $airBrake = Gears::get('AirBrake'); if (IDE_HACKS) { $airBrake = new AirBrake(); } $failFast = $airBrake->failFast($username, $_SERVER['REMOTE_ADDR'], $airBrake::ACTION_RECOVER); if ($failFast) { $this->lens('recover_account', ['form_message' => \__('You are doing that too fast. Please wait a few seconds and try again.')]); } elseif (!$airBrake->getFastExit()) { $delay = $airBrake->getDelay($username, $_SERVER['REMOTE_ADDR'], $airBrake::ACTION_RECOVER); if ($delay > 0) { \usleep($delay * 1000); } } try { $recoverInfo = $this->acct->getRecoveryInfo($username); } catch (UserNotFound $ex) { // Username not found. Is this a harvester? $airBrake->registerAccountRecoveryAttempt($username, $_SERVER['REMOTE_ADDR']); $this->log('Password reset attempt for nonexistent user.', LogLevel::NOTICE, ['username' => $username]); return false; } if (!$recoverInfo['allow_reset'] || empty($recoverInfo['email'])) { // Opted out or no email address? Act like the user doesn't exist. $airBrake->registerAccountRecoveryAttempt($username, $_SERVER['REMOTE_ADDR']); return false; } $token = $this->acct->createRecoveryToken((int) $recoverInfo['userid']); if (empty($token)) { return false; } $state = State::instance(); if (IDE_HACKS) { $state->mailer = new Sendmail(); $state->gpgMailer = new GPGMailer($state->mailer); } $message = (new Message())->addTo($recoverInfo['email'], $username)->setSubject('Password Reset')->setFrom($state->universal['email']['from'] ?? 'no-reply@' . $_SERVER['HTTP_HOST'])->setBody($this->recoveryMessage($token)); try { if (!empty($recoverInfo['gpg_public_key'])) { // This will be encrypted with the user's public key: $state->gpgMailer->send($message, $recoverInfo['gpg_public_key']); } else { // This will be sent as-is: $state->mailer->send($message); } } catch (InvalidArgumentException $ex) { return false; } return true; }
<?php declare (strict_types=1); use Airship\Engine\{AutoPilot, Gears, State}; /** * This loads the Cabin configuration, and selects the active cabin. * * @global State $state */ $ap = Gears::getName('AutoPilot'); // Needed for IDE code completion: if (IDE_HACKS) { $ap = new AutoPilot(); } /** * Cache the cabin configuration */ $cabinDisabled = false; if (\file_exists(ROOT . '/tmp/cache/cabin_data.json')) { // Load the cabins from cache $config = \Airship\loadJSON(ROOT . '/tmp/cache/cabin_data.json'); foreach ($config['cabins'] as $key => $cabin) { if ($ap::isActiveCabinKey($key, !empty($cabin['https']))) { $state->active_cabin = $key; if ($cabin['enabled']) { $cabinDisabled = true; } break; } } $state->cabins = $config['cabins'];
/** * Настройки по умолчанию для всех шестеренок * * @return Config */ public static function getDefaultSettings() { return self::$defaults ? self::$defaults : (self::$defaults = new Config(GEARS . DS . 'Core' . DS . 'defaults' . EXT)); }
<?php declare (strict_types=1); use Airship\Engine\{Gears, Hail, State}; /** * @global State $state * @global Hail $hail */ // Always check for changes to channel keys before initiating update require_once __DIR__ . '/channel.php'; /** * Initialize the automatic updater service * @var \Airship\Engine\Continuum */ $autoUpdater = Gears::get('AutoUpdater', $hail); if (IDE_HACKS) { // Just for the sake of auto-completion: $autoUpdater = new \Airship\Engine\Continuum($hail); } $state->logger->info('Automatic update started'); try { $autoUpdater->doUpdateCheck(); } catch (\Throwable $ex) { $state->logger->critical('Tree update failed: ' . \get_class($ex), \Airship\throwableToArray($ex)); exit(255); } $state->logger->info('Automatic update concluded'); \Airship\clear_cache(); exit(0);
<?php declare (strict_types=1); use Airship\Engine\{Database, Gears, State}; /** * Set up the Database objects from our database.json file * * @global State $state */ $dbgear = Gears::getName('Database'); $databases = \Airship\loadJSON(ROOT . '/config/databases.json'); $dbPool = []; $dbCount = 0; // Needed for IDE code completion: if (IDE_HACKS) { $dbgear = new Database(new \PDO('sqlite::memory:')); } /** * Initialize all of our database connections: */ foreach ($databases as $label => $dbs) { $dbPool[$label] = []; foreach ($dbs as $dbConf) { if (isset($dbConf['driver']) || isset($dbConf['dsn'])) { $conf = [isset($dbConf['dsn']) ? $dbConf['dsn'] : $dbConf]; if (isset($dbConf['username']) && isset($dbConf['password'])) { $conf[] = $dbConf['username']; $conf[] = $dbConf['password']; if (isset($dbConf['options'])) { $conf[] = $dbConf['options']; }
/** * Translation (lookup table based on a key) * * @param string $key * @param mixed ...$params * @return string */ function trk(string $key, ...$params) : string { static $gear = null; if ($gear === null) { $gear = Gears::get('Translation'); } if (!empty($params)) { \array_walk($params, '\\Airship\\LensFunctions\\get_purified'); } $state = State::instance(); return $gear->lookup($key, (string) ($state->lang ?? 'en-us'), ...$params); }
<?php declare (strict_types=1); use Airship\Engine\{Gears, Hail, Keyggdrasil, State}; /** * Keyggdrasil updater -- either throw this in a cronjob or let it get * triggered every time a page loads after enough time has elapsed * * @global State $state * @global Hail $hail */ \ignore_user_abort(true); \set_time_limit(0); require_once \dirname(__DIR__) . '/bootstrap.php'; if (\is_readable(ROOT . '/config/databases.json')) { /** * Initialize the channel updater service */ $channels = \Airship\loadJSON(ROOT . '/config/channels.json'); $database = \Airship\get_database(); $state->logger->info('Keyggdrasil started'); $keyUpdater = Gears::get('TreeUpdater', $hail, $database, $channels); if (IDE_HACKS) { $keyUpdater = new Keyggdrasil($hail, $database, $channels); } $keyUpdater->doUpdate(); $state->logger->info('Keyggdrasil concluded'); } else { // We can't update keys without a place to persist the changes }
/** * Is this user an administrator? * * @param int $userID * @return bool * @throws \Airship\Alerts\Database\DBException */ function is_admin(int $userID = 0) : bool { static $perm = null; if ($perm === null) { $perm = Gears::get('Permissions', \Airship\get_database()); if (!$perm instanceof Permissions) { return false; } } if ($userID < 1) { $userID = \Airship\LensFunctions\userid(); } return $perm->isSuperUser($userID); }
/** * Find probable collisions between patterns and cabin names, as well as hard-coded paths * in the current cabin. It does NOT look for collisions in custom pages, nor in page collisions * in foreign Cabins (outside of the Cabin itself). * * @param string $uri * @param string $cabin * @return bool * @throws \Airship\Alerts\GearNotFound * @throws \TypeError */ protected function detectCollisions(string $uri, string $cabin) : bool { $state = State::instance(); $ap = Gears::getName('AutoPilot'); if (!$ap instanceof AutoPilot) { throw new \TypeError(\__('AutoPilot Blueprint')); } $nop = []; foreach ($state->cabins as $pattern => $cab) { if ($cab === $cabin) { // Let's check each existing route in the current cabin for a collision foreach ($cab['data']['routes'] as $route => $landing) { $test = $ap::testLanding($ap::$patternPrefix . $route . '$', $uri, $nop, true); if ($test) { return true; } } } else { // Let's check each cabin route for a pattern $test = $ap::testLanding($ap::$patternPrefix . $pattern, $uri, $nop, true); if ($test) { return true; } } } return \preg_match('#^(static|js|img|fonts|css)/#', $uri) === 0; }
<?php declare (strict_types=1); use Airship\Engine\LedgerStorage\{DBStore, FileStore}; use Airship\Engine\{Gears, State}; use ParagonIE\ConstantTime\Binary; /** * Configure the application event logger here */ $log_setup_closure = function () { $state = State::instance(); $loggerClass = Gears::getName('Ledger'); $args = []; /** * Here we build our logger storage class */ switch ($state->universal['ledger']['driver']) { case 'file': $path = $state->universal['ledger']['path']; if (Binary::safeStrlen($path) >= 2) { if ($path[0] === '~' && $path[1] === '/') { $path = ROOT . '/' . Binary::safeSubstr($path, 2); } } $storage = new FileStore($path, $state->universal['ledger']['file-format'] ?? FileStore::FILE_FORMAT, $state->universal['ledger']['time-format'] ?? FileStore::TIME_FORMAT); break; case 'database': $path = $state->universal['ledger']['connection']; try { $storage = new DBStore($path, $state->universal['ledger']['table'] ?? DBStore::DEFAULT_TABLE); } catch (\Throwable $ex) {
<?php declare (strict_types=1); namespace Airship\Cabin\Bridge\Blueprint; use Airship\Engine\{Blueprint, Gears}; if (!\class_exists('BlueprintGear')) { Gears::extract('Blueprint', 'BlueprintGear', __NAMESPACE__); // Make autocomplete work with existing IDEs: if (IDE_HACKS) { /** * Class BlueprintGear * @package Airship\Cabin\Bridge\Blueprint */ class BlueprintGear extends Blueprint { } } }
<?php declare (strict_types=1); namespace Airship\Cabin\Hull\Landing; use Airship\Engine\{Landing, Gears}; if (!\class_exists('LandingGear')) { Gears::extract('Landing', 'LandingGear', __NAMESPACE__); // Make autocomplete work with existing IDEs: if (IDE_HACKS) { /** * Class LandingGear * @package Airship\Cabin\Hull\Landing */ class LandingGear extends Landing { } } }
/** * Let's do an automatic login * * @param string $token * @param string $uid_idx * @param string $token_idx * @return bool * @throws LongTermAuthAlert (only in debug mode) * @throws \TypeError */ protected function doAutoLogin(string $token, string $uid_idx, string $token_idx) : bool { if (!$this->airship_auth instanceof Authentication) { $this->tightenSecurityBolt(); } $state = State::instance(); try { $userId = $this->airship_auth->loginByToken($token); \Sodium\memzero($token); if (!$this->verifySessionCanary($userId, false)) { return false; } // Regenerate session ID: Session::regenerate(true); // Set session variable $_SESSION[$uid_idx] = $userId; $autoPilot = Gears::getName('AutoPilot'); if (IDE_HACKS) { // We're using getName(), this is just to fool IDEs. $autoPilot = new AutoPilot(); } $httpsOnly = (bool) $autoPilot::isHTTPSConnection(); // Rotate the authentication token: Cookie::setcookie($token_idx, Symmetric::encrypt($this->airship_auth->rotateToken($token, $userId), $state->keyring['cookie.encrypt_key']), \time() + ($state->universal['long-term-auth-expire'] ?? self::DEFAULT_LONGTERMAUTH_EXPIRE), '/', '', $httpsOnly ?? false, true); return true; } catch (LongTermAuthAlert $e) { $state = State::instance(); // Let's wipe our long-term authentication cookies Cookie::setcookie($token_idx, null, 0, '/', '', $httpsOnly ?? false, true); // Let's log this incident if (\property_exists($this, 'log')) { $this->log($e->getMessage(), LogLevel::CRITICAL, ['exception' => \Airship\throwableToArray($e)]); } else { $state->logger->log(LogLevel::CRITICAL, $e->getMessage(), ['exception' => \Airship\throwableToArray($e)]); } // In debug mode, re-throw the exception: if ($state->universal['debug']) { throw $e; } } return false; }