示例#1
0
 /**
  * Blueprint constructor.
  * @param Database|null $db
  */
 public function __construct(Database $db = null)
 {
     if (!$db) {
         $db = \Airship\get_database();
     }
     $this->db = $db;
 }
示例#2
0
文件: Log.php 项目: paragonie/airship
 /**
  * ContinuumLog constructor.
  * @param Database|null $db
  * @param string $component
  */
 public function __construct(Database $db = null, string $component = 'continuum')
 {
     if (!$db) {
         $db = \Airship\get_database();
     }
     $this->db = $db;
     $this->component = $component;
 }
示例#3
0
 /**
  * DBStore constructor.
  * @param DBInterface|null $db
  * @param string $table
  */
 public function __construct(DBInterface $db = null, string $table = self::DEFAULT_TABLE)
 {
     $this->db = $db ?? \Airship\get_database();
     if (empty($table)) {
         $table = self::DEFAULT_TABLE;
     }
     $this->table = $table;
 }
示例#4
0
 /**
  * Run a SQL file
  *
  * @param string $file
  * @param string $type
  * @return array
  * @throws \Airship\Alerts\Database\DBException
  */
 public static function runSQLFile(string $file, string $type) : array
 {
     $db = \Airship\get_database();
     if ($db->getDriver() !== $type) {
         // Wrong type. Abort!
         return [];
     }
     return $db->safeQuery(\file_get_contents($file));
 }
示例#5
0
 /**
  * AirBrake constructor.
  * @param Database|null $db
  * @param array $config
  */
 public function __construct(Database $db = null, array $config = [])
 {
     if (!$db) {
         $db = \Airship\get_database();
     }
     if (empty($config)) {
         $state = State::instance();
         $config = $state->universal['rate-limiting'];
     }
     $this->db = $db;
     $this->config = $config;
 }
示例#6
0
 /**
  * Make a generic slug for most tables
  *
  * @param string $title What are we basing the URL off of?
  * @param string $table Which table to check for duplicates?
  * @param string $column Which column to check for duplicates?
  * @return string
  */
 protected function makeGenericSlug(string $title, string $table, string $column = 'slug') : string
 {
     if (IDE_HACKS) {
         $this->db = \Airship\get_database();
     }
     $query = 'SELECT count(*) FROM ' . $this->db->escapeIdentifier($table) . ' WHERE ' . $this->db->escapeIdentifier($column) . ' = ?';
     $slug = $base_slug = \Airship\slugFromTitle($title);
     $i = 1;
     while ($this->db->cell($query, $slug) > 0) {
         $slug = $base_slug . '-' . ++$i;
     }
     return $slug;
 }
示例#7
0
 /**
  * Keyggdrasil constructor.
  *
  * @param Hail|null $hail
  * @param DBInterface|null $db
  * @param array $channels
  */
 public function __construct(Hail $hail = null, DBInterface $db = null, array $channels = [])
 {
     $config = State::instance();
     if (empty($hail)) {
         $this->hail = $config->hail;
     } else {
         $this->hail = $hail;
     }
     if (empty($db)) {
         $db = \Airship\get_database();
     }
     $this->db = $db;
     foreach ($channels as $ch => $config) {
         $this->channelCache[$ch] = new Channel($this, $ch, $config);
     }
     if (!self::$continuumLogger) {
         self::$continuumLogger = new Log($this->db, 'keyggdrasil');
     }
 }
示例#8
0
 /**
  * @route /
  */
 public function index()
 {
     if ($this->isLoggedIn()) {
         $this->storeLensVar('showmenu', true);
         $author_bp = $this->blueprint('Author');
         $announce_bp = $this->blueprint('Announcements');
         $blog_bp = $this->blueprint('Blog');
         $page_bp = $this->blueprint('CustomPages');
         if (IDE_HACKS) {
             $db = \Airship\get_database();
             $author_bp = new Author($db);
             $announce_bp = new Announcements($db);
             $blog_bp = new Blog($db);
             $page_bp = new CustomPages($db);
         }
         $this->lens('index', ['announcements' => $announce_bp->getForUser($this->getActiveUserId()), 'stats' => ['num_authors' => $author_bp->numAuthors(), 'num_comments' => $blog_bp->numComments(true), 'num_pages' => $page_bp->numCustomPages(true), 'num_posts' => $blog_bp->numPosts(true)], 'title' => \__('Dashboard')]);
     } else {
         $this->storeLensVar('showmenu', false);
         $this->lens('login');
     }
 }
示例#9
0
<?php

declare (strict_types=1);
/**
 * This nukes the local Keyggdrasil cache.
 */
\ignore_user_abort(true);
\set_time_limit(0);
require_once \dirname(__DIR__) . '/bootstrap.php';
$db = \Airship\get_database();
$db->beginTransaction();
$db->exec("DROP TABLE airship_package_versions;");
$db->exec("DROP TABLE airship_package_cache;");
$db->exec("DROP TABLE airship_tree_updates;");
$db->exec("CREATE TABLE IF NOT EXISTS airship_tree_updates (\n  treeupdateid BIGSERIAL PRIMARY KEY,\n  channel TEXT,\n  channelupdateid BIGINT,\n  data TEXT,\n  merkleroot TEXT,\n  created TIMESTAMP DEFAULT NOW(),\n  modified TIMESTAMP DEFAULT NOW()\n);");
$db->exec("CREATE INDEX ON airship_tree_updates (channel);");
$db->exec("CREATE INDEX ON airship_tree_updates (channelupdateid);");
$db->exec("CREATE UNIQUE INDEX ON airship_tree_updates (channel, channelupdateid);");
$db->exec("CREATE INDEX ON airship_tree_updates (merkleroot);");
$db->exec("DROP TRIGGER IF EXISTS update_airship_tree_updates_modtime ON airship_tree_updates;");
$db->exec("CREATE TRIGGER update_airship_tree_updates_modtime\n  BEFORE UPDATE ON airship_tree_updates\n  FOR EACH ROW EXECUTE PROCEDURE update_modtime();");
$db->exec("CREATE TABLE IF NOT EXISTS airship_package_cache (\n    packageid BIGSERIAL PRIMARY KEY,\n    packagetype type_airship_package,\n    supplier TEXT,\n    name TEXT,\n    installed BOOLEAN DEFAULT FALSE,\n    current_version TEXT,\n    skyport_metadata JSONB,\n    created TIMESTAMP DEFAULT NOW(),\n    modified TIMESTAMP DEFAULT NOW()\n);");
$db->exec("CREATE INDEX ON airship_package_cache (packagetype);");
$db->exec("CREATE INDEX ON airship_package_cache (supplier);");
$db->exec("CREATE INDEX ON airship_package_cache (name);");
$db->exec("CREATE UNIQUE INDEX ON airship_package_cache(packagetype, supplier, name);");
$db->exec("CREATE TABLE IF NOT EXISTS airship_package_versions (\n    versionid BIGSERIAL PRIMARY KEY,\n    package BIGINT REFERENCES airship_package_cache(packageid),\n    version TEXT,\n    checksum TEXT,\n    commithash TEXT,\n    date_released TIMESTAMP,\n    treeupdateid BIGINT REFERENCES airship_tree_updates(treeupdateid),\n    created TIMESTAMP DEFAULT NOW(),\n    modified TIMESTAMP DEFAULT NOW()\n);");
$db->exec("CREATE INDEX ON airship_package_versions (version);");
$db->exec("CREATE INDEX ON airship_package_versions (checksum);");
$db->exec("CREATE UNIQUE INDEX ON airship_package_versions (package, version);");
$db->exec("DROP TRIGGER IF EXISTS update_airship_package_versions_modtime ON airship_package_versions;");
示例#10
0
/**
 * Fetch a query string from the stored queries file
 *
 * @param string $index Which index to replace
 * @param array $params Parameters to be replaced in the query string
 * @param string $cabin Which Cabin are we loading?
 * @param string $driver Which database driver?
 * @return string
 * @throws NotImplementedException
 */
function queryString(string $index, array $params = [], string $cabin = \CABIN_NAME, string $driver = '') : string
{
    static $_cache = [];
    if (empty($driver)) {
        $db = \Airship\get_database();
        $driver = $db->getDriver();
    }
    $cacheKey = Util::hash($cabin . '/' . $driver, \Sodium\CRYPTO_GENERICHASH_BYTES_MIN);
    if (empty($_cache[$cacheKey])) {
        $driver = \preg_replace('/[^a-z]/', '', \strtolower($driver));
        $path = !empty($cabin) ? ROOT . '/Cabin/' . $cabin . '/Queries/' . $driver . '.json' : ROOT . '/Engine/Queries/' . $driver . '.json';
        $_cache[$cacheKey] = \Airship\loadJSON($path);
    }
    $split_key = \explode('.', $index);
    $v = $_cache[$cacheKey];
    foreach ($split_key as $k) {
        if (!\array_key_exists($k, $v)) {
            throw new NotImplementedException(\trk('errors.database.query_not_found', $index));
        }
        $v = $v[$k];
    }
    if (\is_array($v)) {
        throw new NotImplementedException(\trk('errors.database.multiple_candidates', $index));
    }
    $str = $v;
    foreach ($params as $token => $replacement) {
        $str = \str_replace('{{' . $token . '}}', $replacement, $str);
    }
    return $str;
}
示例#11
0
 /**
  * Verifies that the Merkle root exists, matches this package and version,
  * and has the same checksum as the one we calculated.
  *
  * @param InstallFile $file
  * @return bool
  */
 public function verifyMerkleRoot(InstallFile $file) : bool
 {
     $debugArgs = ['supplier' => $this->supplier->getName(), 'name' => $this->package];
     $db = \Airship\get_database();
     $merkle = $db->row('SELECT * FROM airship_tree_updates WHERE merkleroot = ?', $file->getMerkleRoot());
     if (empty($merkle)) {
         $this->log('Merkle root not found in tree', LogLevel::DEBUG, $debugArgs);
         // Not found in Keyggdrasil
         return false;
     }
     $data = \Airship\parseJSON($merkle['data'], true);
     $instType = \strtolower($this->type);
     $keyggdrasilType = \strtolower($data['pkg_type']);
     if (!\hash_equals($instType, $keyggdrasilType)) {
         $this->log('Wrong package type', LogLevel::DEBUG, $debugArgs);
         // Wrong package type
         return false;
     }
     if (!\hash_equals($this->supplier->getName(), $data['supplier'])) {
         $this->log('Wrong supplier', LogLevel::DEBUG, $debugArgs);
         // Wrong supplier
         return false;
     }
     if (!\hash_equals($this->package, $data['name'])) {
         $this->log('Wrong package', LogLevel::DEBUG, $debugArgs);
         // Wrong package
         return false;
     }
     // Finally, we verify that the checksum matches the entry in our Merkle tree:
     return \hash_equals($file->getHash(), $data['checksum']);
 }
示例#12
0
 /**
  * Set the database of this authentication library to match this 
  * 
  * @param string $dbIndex
  * @return Authentication ($this)
  */
 public function setDatabaseByKey(string $dbIndex = '') : self
 {
     $this->db = \Airship\get_database($dbIndex);
     return $this;
 }
示例#13
0
 /**
  * @route ajax/authors_save_photo
  */
 public function saveAuthorsPhoto()
 {
     $auth_bp = $this->blueprint('Author');
     if (IDE_HACKS) {
         $db = \Airship\get_database();
         $auth_bp = new Author($db);
     }
     $authorId = (int) $_POST['author'];
     if (!$this->isSuperUser()) {
         $authors = $auth_bp->getAuthorIdsForUser($this->getActiveUserId());
         if (!\in_array($authorId, $authors)) {
             \Airship\json_response(['status' => 'ERROR', 'message' => \__('You do not have permission to access this author\'s posts.')]);
         }
     }
     if (!\Airship\all_keys_exist(['cabin', 'context', 'author', 'filename'], $_POST)) {
         \Airship\json_response(['keys' => array_keys($_POST), 'status' => 'ERROR', 'message' => 'Insufficient parameters']);
     }
     $result = $auth_bp->savePhotoChoice($authorId, $_POST['context'], $_POST['cabin'], $_POST['filename']);
     if (!$result) {
         \Airship\json_response(['status' => 'ERROR', 'message' => 'Could not save photo choice.', 'photo' => null]);
     }
     \Airship\json_response(['status' => 'OK', 'message' => 'Saved!']);
 }
示例#14
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
}
示例#15
0
/**
 * Get the user's public display name.
 *
 * @param int|null $userId
 * @return string
 * @throws \Airship\Alerts\Database\DBException
 */
function user_unique_id(int $userId = null) : string
{
    if (empty($userId)) {
        $userId = \Airship\LensFunctions\userid();
    }
    $db = \Airship\get_database();
    return $db->cell('SELECT uniqueid FROM airship_users WHERE userid = ?', $userId);
}
示例#16
0
 /**
  * Choose a database. We don't do anything fancy, but a Gear
  * might decide to do something different.
  *
  * @return Contract\DBInterface
  */
 protected function airshipChooseDB() : DBInterface
 {
     return \Airship\get_database();
 }
示例#17
0
 /**
  * Update the version string in airship_package_cache
  *
  * @param string $type
  * @param UpdateInfo $info
  * @return bool
  */
 public function updateDBRecord(string $type, UpdateInfo $info) : bool
 {
     $db = \Airship\get_database();
     $db->beginTransaction();
     $db->update('airship_package_cache', ['current_version' => $info->getVersion()], ['packagetype' => $type, 'supplier' => $info->getSupplierName(), 'name' => $info->getPackageName()]);
     return $db->commit();
 }
示例#18
0
 /**
  * If another session triggered a password reset, we should be logged out
  * as per the Bridge configuration. (This /is/ an optional feature.)
  *
  * @param int $userID
  * @param bool $logOut
  * @return bool
  */
 public function verifySessionCanary(int $userID, bool $logOut = true) : bool
 {
     if (empty($_SESSION['session_canary'])) {
         return false;
     }
     $db = \Airship\get_database();
     $canary = $db->cell('SELECT session_canary FROM airship_users WHERE userid = ?', $userID);
     if (empty($canary)) {
         $this->log('No session canary was registered with this user in the database.', LogLevel::DEBUG, ['database' => $canary, 'session' => $_SESSION['session_canary']]);
         $this->completeLogOut();
         return false;
     }
     if (!\hash_equals($canary, $_SESSION['session_canary'])) {
         $this->log('User was logged out for having the wrong canary.', LogLevel::DEBUG, ['expected' => $canary, 'possessed' => $_SESSION['session_canary']]);
         if ($logOut) {
             $this->completeLogOut();
         }
         return false;
     }
     return true;
 }