PageRenderTime 51ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/motifs.php

https://gitlab.com/freesoftware/paragonie-airship
PHP | 120 lines | 92 code | 11 blank | 17 comment | 22 complexity | 4f8f492ebc05f72fed57009b25675920 MD5 | raw file
  1. <?php
  2. declare(strict_types=1);
  3. use Airship\Engine\{
  4. View,
  5. State
  6. };
  7. /**
  8. * @global View $lens
  9. * @global array $_settings
  10. * @global array $active
  11. * @global State $state
  12. *
  13. * Load this in index.php, or anywhere /AFTER/ the CABIN_DIR constant exists
  14. */
  15. if (\defined('CABIN_DIR')) {
  16. $motifCacheFile = ROOT . '/tmp/cache/' . CABIN_NAME . '.motifs.json';
  17. if (\file_exists($motifCacheFile) && \filesize($motifCacheFile) > 0) {
  18. // Load from this cabin's motif cache.
  19. $motifs = \Airship\loadJSON($motifCacheFile);
  20. $state->motifs = $motifs;
  21. } else {
  22. // Let's make sure our directories exist:
  23. if (!\is_dir(CABIN_DIR . '/View/motif')) {
  24. \mkdir(CABIN_DIR . '/View/motif', 0775);
  25. } else {
  26. @\chmod(CABIN_DIR . '/View/motif', 0775);
  27. }
  28. if (!\is_dir(CABIN_DIR . '/public/motif')) {
  29. \mkdir(CABIN_DIR . '/public/motif', 0775);
  30. } else {
  31. @\chmod(CABIN_DIR . '/public/motif', 0775);
  32. }
  33. // Parse the Cabin's Motifs configuration file:
  34. $motifsJSONFile = ROOT . '/Cabin/' . CABIN_NAME . '/config/motifs.json';
  35. if (\is_dir(CABIN_DIR . '/View/motif') && \is_readable($motifsJSONFile)) {
  36. $motifs = [];
  37. $motifsJSONData = \Airship\loadJSON($motifsJSONFile);
  38. // Parse a particular motif:
  39. foreach ($motifsJSONData as $motif => $motifConfig) {
  40. if (empty($motifConfig['enabled'])) {
  41. continue;
  42. }
  43. if (isset($motifConfig['path'])) {
  44. $motifStart = CABIN_DIR . '/View/motif/' . $motif;
  45. $motifEnd = ROOT . '/Motifs/' . $motifConfig['path'];
  46. // If the Motif is malicious, alert.
  47. if (\strpos($motifStart, CABIN_DIR . '/View/motif') === false) {
  48. $state->logger->alert(
  49. 'Potential directory traversal in Motif config.',
  50. [
  51. 'cabin' => $active['name'],
  52. 'motif' => $motif,
  53. 'path' => $motifStart
  54. ]
  55. );
  56. // SKIP! We have a potential directory traversal
  57. continue;
  58. }
  59. if (\strpos($motifEnd, ROOT . '/Motifs') === false) {
  60. $state->logger->alert(
  61. 'Potential directory traversal in Motif config.',
  62. [
  63. 'cabin' => $active['name'],
  64. 'motif' => $motif,
  65. 'path' => $motifEnd
  66. ]
  67. );
  68. // SKIP! We have a potential directory traversal
  69. continue;
  70. }
  71. // Create the necessary symlinks if they do not already exist:
  72. if (!\is_link($motifStart)) {
  73. \symlink($motifEnd . '/lens', $motifStart);
  74. }
  75. if (\is_dir($motifEnd . '/public')) {
  76. $motifPublic = CABIN_DIR . '/public/motif/' . $motif;
  77. if (!\is_link($motifPublic)) {
  78. \symlink($motifEnd . '/public', $motifPublic);
  79. }
  80. }
  81. // Finally, load the configuration:
  82. if (\file_exists($motifEnd . '/motif.json')) {
  83. $motifConfig['config'] = \Airship\loadJSON($motifEnd . '/motif.json');
  84. } else {
  85. $motifConfig['config'] = [];
  86. }
  87. $motifs[$motif] = $motifConfig;
  88. }
  89. }
  90. \Airship\saveJSON($motifCacheFile, $motifs);
  91. $state->motifs = $motifs;
  92. } else {
  93. die(\__("FATAL ERROR: Motifs file is not readable"));
  94. }
  95. }
  96. }
  97. $userMotif = \Airship\ViewFunctions\user_motif();
  98. if (!empty($userMotif)) {
  99. $activeMotif = $userMotif['name'];
  100. } elseif (isset($_settings['active-motif'])) {
  101. $activeMotif = $_settings['active-motif'];
  102. }
  103. if (isset($activeMotif)) {
  104. $lens
  105. ->setBaseTemplate($activeMotif)
  106. ->loadMotifCargo($activeMotif)
  107. ->loadMotifConfig($activeMotif)
  108. ->addGlobal('MOTIF', $state->motif_config);
  109. }