Пример #1
0
 /**
  * Remove a cabin
  *
  * @param array $info
  * @return string
  */
 protected function removeCabin(array $info) : string
 {
     $ret = '';
     $cabins = \Airship\loadJSON(ROOT . '/config/cabins.json');
     $search = $this->makeNamespace($info['supplier'], $info['name']);
     foreach ($cabins as $i => $cabin) {
         if ($cabin['name'] === $search) {
             $ret .= "Removed {$search} from config/cabins.json\n";
             $symlink = ROOT . '/Cabin/Bridge/Lens/cabin_links/' . $search;
             if (\is_link($symlink)) {
                 \unlink($symlink);
             }
             unset($cabins[$i]);
         }
     }
     if (empty($ret)) {
         return 'Cabin not configured or missing.';
     }
     $twigEnv = \Airship\configWriter(ROOT . 'config/templates');
     // Save cabins.json
     \file_put_contents(ROOT . '/config/cabins.json', $twigEnv->render('cabins.twig', ['cabins' => $cabins]));
     /**
      * @security Watch this carefully:
      */
     $ret .= \shell_exec('rm -rf ' . \escapeshellarg(ROOT . '/Cabin/' . $search));
     return $ret;
 }
Пример #2
0
 /**
  * Attempt to save the user-provided cabin configuration
  *
  * @param string $cabinName
  * @param array $cabins
  * @param array $post
  * @return bool
  */
 protected function saveSettings(string $cabinName, array $cabins = [], array $post = []) : bool
 {
     $ds = DIRECTORY_SEPARATOR;
     $twigEnv = \Airship\configWriter(ROOT . $ds . 'config' . $ds . 'templates');
     // Content-Security-Policy
     $csp = [];
     foreach ($post['content_security_policy'] as $dir => $rules) {
         if ($dir === 'upgrade-insecure-requests' || $dir === 'inherit') {
             continue;
         }
         if (empty($rules['allow'])) {
             $csp[$dir]['allow'] = [];
         } else {
             $csp[$dir]['allow'] = [];
             foreach ($rules['allow'] as $url) {
                 if (!empty($url) && \is_string($url)) {
                     $csp[$dir]['allow'][] = $url;
                 }
             }
         }
         if (isset($rules['disable-security'])) {
             $csp[$dir]['allow'][] = '*';
         }
         if ($dir === 'script-src') {
             $csp[$dir]['unsafe-inline'] = !empty($rules['unsafe-inline']);
             $csp[$dir]['unsafe-eval'] = !empty($rules['unsafe-eval']);
             $csp[$dir]['self'] = !empty($rules['self']);
         } elseif ($dir === 'style-src') {
             $csp[$dir]['unsafe-inline'] = !empty($rules['unsafe-inline']);
             $csp[$dir]['self'] = !empty($rules['self']);
         } elseif ($dir !== 'plugin-types') {
             $csp[$dir]['self'] = !empty($rules['self']);
             $csp[$dir]['data'] = !empty($rules['data']);
         }
     }
     $csp['inherit'] = !empty($post['content_security_policy']['inherit']);
     $csp['upgrade-insecure-requests'] = !empty($post['content_security_policy']['upgrade-insecure-requests']);
     $saveCabins = [];
     foreach ($cabins as $cab => $cab_data) {
         if ($cab_data['name'] !== $cabinName) {
             // Pass-through
             $saveCabins[$cab] = $cab_data;
         } else {
             $saveCabins[$post['config']['path']] = $post['config'];
             if (isset($cab_data['namespace'])) {
                 // This should be immutable.
                 $saveCabins[$post['config']['path']]['namespace'] = $cab_data['namespace'];
             }
             unset($saveCabins['path']);
         }
     }
     // Save CSP
     \file_put_contents(ROOT . $ds . 'config' . $ds . 'Cabin' . $ds . $cabinName . $ds . 'content_security_policy.json', \json_encode($csp, JSON_PRETTY_PRINT));
     // Configuration
     if (!empty($post['cabin_manage_fallback'])) {
         $config_extra = \json_decode($post['config_extra'], true);
         $twig_vars = \json_decode($post['twig_vars'], true);
     } else {
         $config_extra = $post['config_extra'];
         $twig_vars = $post['twig_vars'];
     }
     if (!empty($config_extra)) {
         \Airship\saveJSON(ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'Cabin' . DIRECTORY_SEPARATOR . $cabinName . DIRECTORY_SEPARATOR . 'config.json', $config_extra);
     }
     if (!empty($twig_vars)) {
         \Airship\saveJSON(ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'Cabin' . DIRECTORY_SEPARATOR . $cabinName . DIRECTORY_SEPARATOR . 'twig_vars.json', $twig_vars);
     }
     // Clear the cache
     \unlink(ROOT . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'csp.' . $cabinName . '.json');
     if (\extension_loaded('apcu')) {
         \apcu_clear_cache();
     }
     // Save cabins.json
     \file_put_contents(ROOT . $ds . 'config' . $ds . 'cabins.json', $twigEnv->render('cabins.twig', ['cabins' => $saveCabins]));
     // Delete the cabin cache
     if (\file_exists(ROOT . 'tmp' . $ds . 'cache' . $ds . 'cabin_data.json')) {
         \unlink(ROOT . 'tmp' . $ds . 'cache' . $ds . 'cabin_data.json');
     }
     return true;
 }
Пример #3
0
 /**
  * Add the new cabin to config/cabins.json
  *
  * @param string $nameSpace
  * @param array $metadata
  * @return bool
  */
 protected function updateCabinsRegistry(string $nameSpace, array $metadata) : bool
 {
     // Default route
     $defaultPath = ($metadata['default_path'] ?? '*/') . $this->supplier->getName() . '/' . $this->package;
     $twigEnv = \Airship\configWriter(ROOT . '/config/templates');
     $cabins = \Airship\loadJSON(ROOT . '/config/cabins.json');
     // We want to load everything before the wildcard entry:
     if (isset($cabins['*'])) {
         $newCabins = [];
         foreach (\array_keys($cabins) as $k) {
             if ($k !== '*') {
                 $newCabins[$k] = $cabins[$k];
             }
         }
         $newCabins[$defaultPath] = ['https' => false, 'canon_url' => '/' . $this->supplier->getName() . '/' . $this->package, 'language' => (string) ($metadata['lang'] ?? 'en-us'), 'name' => $nameSpace];
         $newCabins['*'] = $cabins['*'];
     } else {
         $newCabins = $cabins;
         $newCabins[$defaultPath] = ['https' => false, 'canon_url' => '/' . $this->supplier->getName() . '/' . $this->package, 'language' => (string) ($metadata['lang'] ?? 'en-us'), 'name' => $nameSpace];
     }
     return \file_put_contents(ROOT . '/config/cabins.json', $twigEnv->render('cabins.twig', ['cabins' => $newCabins])) !== false;
 }
Пример #4
0
 /**
  * Save universal settings
  *
  * @param array $post
  * @return bool
  */
 protected function saveSettings(array $post = []) : bool
 {
     $filterName = '\\Airship\\Cabin\\' . CABIN_NAME . '\\AirshipFilter';
     if (\class_exists($filterName)) {
         $filter = new $filterName();
         $post = $filter($post);
     }
     $twigEnv = \Airship\configWriter(ROOT . '/config/templates');
     $csp = [];
     foreach ($post['content_security_policy'] as $dir => $rules) {
         if ($dir === 'upgrade-insecure-requests') {
             continue;
         }
         if (empty($rules['allow'])) {
             $csp[$dir]['allow'] = [];
         } else {
             $csp[$dir]['allow'] = [];
             foreach ($rules['allow'] as $url) {
                 if (!empty($url) && \is_string($url)) {
                     $csp[$dir]['allow'][] = $url;
                 }
             }
         }
         if (isset($rules['disable-security'])) {
             $csp[$dir]['allow'][] = '*';
         }
         if ($dir === 'script-src') {
             $csp[$dir]['unsafe-inline'] = !empty($rules['unsafe-inline']);
             $csp[$dir]['unsafe-eval'] = !empty($rules['unsafe-eval']);
         } elseif ($dir === 'style-src') {
             $csp[$dir]['unsafe-inline'] = !empty($rules['unsafe-inline']);
         } elseif ($dir !== 'plugin-types') {
             $csp[$dir]['self'] = !empty($rules['self']);
             $csp[$dir]['data'] = !empty($rules['data']);
         }
     }
     $csp['upgrade-insecure-requests'] = !empty($post['content_security_policy']['upgrade-insecure-requests']);
     if (isset($csp['inherit'])) {
         unset($csp['inherit']);
     }
     if ($post['universal']['ledger']['driver'] === 'database') {
         if (empty($post['universal']['ledger']['table'])) {
             // Table name must be provided.
             return false;
         }
     }
     // Save CSP
     \Airship\saveJSON(ROOT . '/config/content_security_policy.json', $csp);
     if (empty($post['universal']['guest_groups'])) {
         $post['universal']['guest_groups'] = [];
     } else {
         foreach ($post['universal']['guest_groups'] as $i => $g) {
             $post['universal']['guest_groups'][$i] = (int) $g;
         }
     }
     // Save universal config
     return \file_put_contents(ROOT . '/config/universal.json', $twigEnv->render('universal.twig', ['universal' => $post['universal']])) !== false;
 }
Пример #5
0
 /**
  * Save all of the necessary configuration files
  */
 protected function finalConfiguration()
 {
     $twigEnv = \Airship\configWriter(ROOT . '/config/templates');
     \file_put_contents(ROOT . '/config/cabins.json', $this->finalConfigCabins($twigEnv));
     \file_put_contents(ROOT . '/config/databases.json', $this->finalConfigDatabases($twigEnv));
     \file_put_contents(ROOT . '/config/gadgets.json', '[]');
     \file_put_contents(ROOT . '/config/universal.json', $this->finalConfigUniversal($twigEnv));
     \chmod(ROOT . '/config/cabins.json', 0664);
     \chmod(ROOT . '/config/databases.json', 0664);
     \chmod(ROOT . '/config/gadgets.json', 0664);
     \chmod(ROOT . '/config/universal.json', 0664);
 }