(dev/core#2258) Add System.rotateKey API
[civicrm-core.git] / Civi / Api4 / Action / System / RotateKey.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
11 */
12
13 namespace Civi\Api4\Action\System;
14
15 use Civi\Api4\Generic\AbstractAction;
16 use Civi\Api4\Generic\Result;
17
18 /**
19 * Rotate the keys used for encrypted database content.
20 *
21 * Crypto keys are loaded from the CryptoRegistry based on tag name. Each tag will
22 * have one preferred key and 0+ legacy keys. They rekey operation finds any
23 * old content (based on legacy keys) and rewrites it (using the preferred key).
24 *
25 * @method string getTag()
26 * @method $this setTag(string $tag)
27 */
28 class RotateKey extends AbstractAction {
29
30 /**
31 * Tag name (e.g. "CRED")
32 *
33 * @var string
34 */
35 protected $tag;
36
37 /**
38 * @param \Civi\Api4\Generic\Result $result
39 *
40 * @throws \API_Exception
41 * @throws \Civi\Crypto\Exception\CryptoException
42 */
43 public function _run(Result $result) {
44 if (empty($this->tag)) {
45 throw new \API_Exception("Missing required argument: tag");
46 }
47
48 // Track log of changes in memory.
49 $logger = new class() extends \Psr\Log\AbstractLogger {
50
51 /**
52 * @var array
53 */
54 public $log = [];
55
56 /**
57 * Logs with an arbitrary level.
58 *
59 * @param mixed $level
60 * @param string $message
61 * @param array $context
62 */
63 public function log($level, $message, array $context = []) {
64 $evalVar = function($m) use ($context) {
65 return $context[$m[1]] ?? '';
66 };
67
68 $this->log[] = [
69 'level' => $level,
70 'message' => preg_replace_callback('/\{([a-zA-Z0-9\.]+)\}/', $evalVar, $message),
71 ];
72 }
73
74 };
75
76 \CRM_Utils_Hook::cryptoRotateKey($this->tag, $logger);
77
78 $result->exchangeArray($logger->log);
79 }
80
81 }