ActionController.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * MINZ - Copyright 2011 Marien Fressinaud
  5. * Sous licence AGPL3 <http://www.gnu.org/licenses/>
  6. */
  7. /**
  8. * The Minz_ActionController class is a controller in the MVC paradigm
  9. */
  10. abstract class Minz_ActionController {
  11. /** @var array<string,string> */
  12. private static array $csp_default = [
  13. 'default-src' => "'self'",
  14. 'frame-ancestors' => "'none'",
  15. ];
  16. /** @var array<string,string> */
  17. private array $csp_policies;
  18. /** @var Minz_View */
  19. protected $view;
  20. /**
  21. * Gives the possibility to override the default view model type.
  22. * @var class-string
  23. * @deprecated Use constructor with view type instead
  24. */
  25. public static string $defaultViewType = Minz_View::class;
  26. /**
  27. * @phpstan-param class-string|'' $viewType
  28. * @param string $viewType Name of the class (inheriting from Minz_View) to use for the view model
  29. */
  30. public function __construct(string $viewType = '') {
  31. $this->csp_policies = self::$csp_default;
  32. $view = null;
  33. if ($viewType !== '' && class_exists($viewType)) {
  34. $view = new $viewType();
  35. if (!($view instanceof Minz_View)) {
  36. $view = null;
  37. }
  38. }
  39. if ($view === null && class_exists(self::$defaultViewType)) {
  40. $view = new self::$defaultViewType();
  41. if (!($view instanceof Minz_View)) {
  42. $view = null;
  43. }
  44. }
  45. $this->view = $view ?? new Minz_View();
  46. $view_path = Minz_Request::controllerName() . '/' . Minz_Request::actionName() . '.phtml';
  47. $this->view->_path($view_path);
  48. $this->view->attributeParams();
  49. }
  50. /**
  51. * Getteur
  52. */
  53. public function view(): Minz_View {
  54. return $this->view;
  55. }
  56. /**
  57. * Set default CSP policies.
  58. * @param array<string,string> $policies An array where keys are directives and values are sources.
  59. */
  60. public static function _defaultCsp(array $policies): void {
  61. if (!isset($policies['default-src']) || !isset($policies['frame-ancestors'])) {
  62. Minz_Log::warning('Default CSP policy is not declared', ADMIN_LOG);
  63. }
  64. self::$csp_default = $policies;
  65. }
  66. /**
  67. * Set CSP policies.
  68. *
  69. * A default-src directive should always be given.
  70. *
  71. * References:
  72. * - https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
  73. * - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src
  74. *
  75. * @param array<string,string> $policies An array where keys are directives and values are sources.
  76. */
  77. protected function _csp(array $policies): void {
  78. if (!isset($policies['default-src'])) {
  79. $action = Minz_Request::controllerName() . '#' . Minz_Request::actionName();
  80. Minz_Log::warning(
  81. "Default CSP policy is not declared for action {$action}.",
  82. ADMIN_LOG
  83. );
  84. }
  85. $this->csp_policies = $policies;
  86. }
  87. /**
  88. * Send HTTP Content-Security-Policy header based on declared policies.
  89. */
  90. public function declareCspHeader(): void {
  91. $policies = [];
  92. foreach (Minz_ExtensionManager::listExtensions(true) as $extension) {
  93. $extension->amendCsp($this->csp_policies);
  94. }
  95. foreach ($this->csp_policies as $directive => $sources) {
  96. $policies[] = $directive . ' ' . $sources;
  97. }
  98. header('Content-Security-Policy: ' . implode('; ', $policies));
  99. }
  100. /**
  101. * Méthodes à redéfinir (ou non) par héritage
  102. * firstAction est la première méthode exécutée par le Dispatcher
  103. * lastAction est la dernière
  104. */
  105. public function init(): void { }
  106. public function firstAction(): void { }
  107. public function lastAction(): void { }
  108. }