src/Entity/Core/AppSettings.php line 32

Open in your IDE?
  1. <?php
  2. namespace App\Entity\Core;
  3. use Doctrine\ORM\Mapping as ORM;
  4. /**
  5. * ══════════════════════════════════════════════════════════════════════════
  6. * RÉGLAGES DE L'APPLICATION — clé / valeur
  7. * ══════════════════════════════════════════════════════════════════════════
  8. *
  9. * Table générique, pour tout ce qui doit se changer depuis le backoffice
  10. * sans déploiement. Premier usage : la configuration Stripe.
  11. *
  12. * ── `secret` : LA COLONNE QUI COMPTE ───────────────────────────────────
  13. *
  14. * Une valeur marquée `secret` n'est JAMAIS renvoyée au navigateur. Le
  15. * formulaire affiche `sk_live_••••4242` et poste une chaîne vide quand on
  16. * n'y touche pas.
  17. *
  18. * Sans ça, la clé secrète Stripe se retrouverait dans le HTML du
  19. * backoffice — donc dans le cache du navigateur, dans les captures
  20. * d'écran, dans les journaux de tout proxy sur le trajet. Une clé
  21. * `sk_live_` permet d'émettre des remboursements et de lire la totalité
  22. * des paiements du compte.
  23. *
  24. * @ORM\Entity(repositoryClass="App\Repository\Core\AppSettingsRepository")
  25. * @ORM\Table(name="app_settings", uniqueConstraints={
  26. * @ORM\UniqueConstraint(name="uniq_app_settings_key", columns={"setting_key"})
  27. * })
  28. */
  29. class AppSettings
  30. {
  31. /**
  32. * @ORM\Id
  33. * @ORM\GeneratedValue
  34. * @ORM\Column(type="integer")
  35. */
  36. private $id;
  37. /**
  38. * @ORM\Column(name="setting_key", type="string", length=100)
  39. */
  40. private $settingKey;
  41. /**
  42. * `text` et pas `string` : une clé de webhook ou un JSON de
  43. * configuration dépasse vite 255 caractères.
  44. *
  45. * @ORM\Column(name="setting_value", type="text", nullable=true)
  46. */
  47. private $settingValue;
  48. /**
  49. * Regroupement d'affichage dans le backoffice (`stripe`, `mail`, …).
  50. *
  51. * @ORM\Column(name="setting_group", type="string", length=50)
  52. */
  53. private $settingGroup = 'general';
  54. /**
  55. * Valeur sensible : masquée à l'affichage, jamais renvoyée en clair.
  56. *
  57. * @ORM\Column(name="is_secret", type="boolean")
  58. */
  59. private $isSecret = false;
  60. /**
  61. * @ORM\Column(name="updated_at", type="datetime", nullable=true)
  62. */
  63. private $updatedAt;
  64. /**
  65. * Qui a modifié, et quand. Une clé d'API qui change sans trace, c'est
  66. * une panne de paiement qu'on met une journée à expliquer.
  67. *
  68. * @ORM\Column(name="updated_by", type="string", length=180, nullable=true)
  69. */
  70. private $updatedBy;
  71. public function getId(): ?int
  72. {
  73. return $this->id;
  74. }
  75. public function getSettingKey(): ?string
  76. {
  77. return $this->settingKey;
  78. }
  79. public function setSettingKey(string $k): self
  80. {
  81. $this->settingKey = $k;
  82. return $this;
  83. }
  84. public function getSettingValue(): ?string
  85. {
  86. return $this->settingValue;
  87. }
  88. public function setSettingValue(?string $v): self
  89. {
  90. $this->settingValue = $v;
  91. return $this;
  92. }
  93. public function getSettingGroup(): ?string
  94. {
  95. return $this->settingGroup;
  96. }
  97. public function setSettingGroup(string $g): self
  98. {
  99. $this->settingGroup = $g;
  100. return $this;
  101. }
  102. public function isSecret(): bool
  103. {
  104. return (bool) $this->isSecret;
  105. }
  106. public function setIsSecret(bool $s): self
  107. {
  108. $this->isSecret = $s;
  109. return $this;
  110. }
  111. public function getUpdatedAt(): ?\DateTimeInterface
  112. {
  113. return $this->updatedAt;
  114. }
  115. public function setUpdatedAt(?\DateTimeInterface $d): self
  116. {
  117. $this->updatedAt = $d;
  118. return $this;
  119. }
  120. public function getUpdatedBy(): ?string
  121. {
  122. return $this->updatedBy;
  123. }
  124. public function setUpdatedBy(?string $u): self
  125. {
  126. $this->updatedBy = $u;
  127. return $this;
  128. }
  129. /**
  130. * La valeur telle qu'on peut l'afficher : masquée si elle est secrète.
  131. *
  132. * On garde les 4 derniers caractères — c'est ce qui permet de vérifier
  133. * d'un coup d'œil qu'on a bien la bonne clé, sans la révéler. Même
  134. * convention que les numéros de carte.
  135. */
  136. public function getMaskedValue(): ?string
  137. {
  138. if (!$this->settingValue) {
  139. return null;
  140. }
  141. if (!$this->isSecret()) {
  142. return $this->settingValue;
  143. }
  144. $v = $this->settingValue;
  145. $len = strlen($v);
  146. /* Trop courte pour être masquée utilement : on ne montre rien. */
  147. if ($len <= 8) {
  148. return str_repeat('•', 8);
  149. }
  150. /* Le préfixe Stripe (`sk_live_`, `whsec_`) est public et permet de
  151. voir immédiatement si on est en test ou en production. */
  152. $prefixe = '';
  153. if (preg_match('/^(sk_live_|sk_test_|pk_live_|pk_test_|whsec_|price_|prod_)/', $v, $m)) {
  154. $prefixe = $m[1];
  155. }
  156. return $prefixe . str_repeat('•', 8) . substr($v, -4);
  157. }
  158. }