Example #1
0
 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;
     }
 }
Example #2
0
    $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);
Example #3
0
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;
Example #4
0
<?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 
Example #5
0
 /**
  * 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;
 }
Example #6
0
<?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'];
Example #7
0
 /**
  * Настройки по умолчанию для всех шестеренок
  *
  * @return Config
  */
 public static function getDefaultSettings()
 {
     return self::$defaults ? self::$defaults : (self::$defaults = new Config(GEARS . DS . 'Core' . DS . 'defaults' . EXT));
 }
Example #8
0
<?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);
Example #9
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'];
                }
Example #10
0
 /**
  * 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);
 }
Example #11
0
<?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
}
Example #12
0
/**
 * 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);
}
Example #13
0
 /**
  * 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;
 }
Example #14
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) {
Example #15
0
<?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
        {
        }
    }
}
Example #16
0
<?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
        {
        }
    }
}
Example #17
0
 /**
  * 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;
 }