DotenvVault.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\FrameworkBundle\Secrets;
  11. /**
  12. * @author Nicolas Grekas <p@tchwork.com>
  13. *
  14. * @internal
  15. */
  16. class DotenvVault extends AbstractVault
  17. {
  18. private $dotenvFile;
  19. public function __construct(string $dotenvFile)
  20. {
  21. $this->dotenvFile = strtr($dotenvFile, '/', \DIRECTORY_SEPARATOR);
  22. }
  23. public function generateKeys(bool $override = false): bool
  24. {
  25. $this->lastMessage = 'The dotenv vault doesn\'t encrypt secrets thus doesn\'t need keys.';
  26. return false;
  27. }
  28. public function seal(string $name, string $value): void
  29. {
  30. $this->lastMessage = null;
  31. $this->validateName($name);
  32. $v = str_replace("'", "'\\''", $value);
  33. $content = is_file($this->dotenvFile) ? file_get_contents($this->dotenvFile) : '';
  34. $content = preg_replace("/^$name=((\\\\'|'[^']++')++|.*)/m", "$name='$v'", $content, -1, $count);
  35. if (!$count) {
  36. $content .= "$name='$v'\n";
  37. }
  38. file_put_contents($this->dotenvFile, $content);
  39. $this->lastMessage = sprintf('Secret "%s" %s in "%s".', $name, $count ? 'added' : 'updated', $this->getPrettyPath($this->dotenvFile));
  40. }
  41. public function reveal(string $name): ?string
  42. {
  43. $this->lastMessage = null;
  44. $this->validateName($name);
  45. $v = \is_string($_SERVER[$name] ?? null) && 0 !== strpos($name, 'HTTP_') ? $_SERVER[$name] : ($_ENV[$name] ?? null);
  46. if (null === $v) {
  47. $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile));
  48. return null;
  49. }
  50. return $v;
  51. }
  52. public function remove(string $name): bool
  53. {
  54. $this->lastMessage = null;
  55. $this->validateName($name);
  56. $content = is_file($this->dotenvFile) ? file_get_contents($this->dotenvFile) : '';
  57. $content = preg_replace("/^$name=((\\\\'|'[^']++')++|.*)\n?/m", '', $content, -1, $count);
  58. if ($count) {
  59. file_put_contents($this->dotenvFile, $content);
  60. $this->lastMessage = sprintf('Secret "%s" removed from file "%s".', $name, $this->getPrettyPath($this->dotenvFile));
  61. return true;
  62. }
  63. $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile));
  64. return false;
  65. }
  66. public function list(bool $reveal = false): array
  67. {
  68. $this->lastMessage = null;
  69. $secrets = [];
  70. foreach ($_ENV as $k => $v) {
  71. if (preg_match('/^\w+$/D', $k)) {
  72. $secrets[$k] = $reveal ? $v : null;
  73. }
  74. }
  75. foreach ($_SERVER as $k => $v) {
  76. if (\is_string($v) && preg_match('/^\w+$/D', $k)) {
  77. $secrets[$k] = $reveal ? $v : null;
  78. }
  79. }
  80. return $secrets;
  81. }
  82. }