3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
11 namespace Civi\API\Subscriber
;
14 use Civi\API\Event\AuthorizeEvent
;
15 use Civi\API\Event\RespondEvent
;
16 use Symfony\Component\EventDispatcher\EventSubscriberInterface
;
19 * The WhitelistSubscriber listens to API requests and matches them against
20 * a whitelist of allowed API calls. If an API call does NOT appear in the
21 * whitelist, then it generates an error.
24 * @copyright CiviCRM LLC https://civicrm.org/licensing
26 class WhitelistSubscriber
implements EventSubscriberInterface
{
31 public static function getSubscribedEvents() {
33 Events
::AUTHORIZE
=> ['onApiAuthorize', Events
::W_EARLY
],
34 Events
::RESPOND
=> ['onApiRespond', Events
::W_MIDDLE
],
39 * Array(WhitelistRule).
46 * Array (scalar $reqId => WhitelistRule $rule).
50 protected $activeRules;
54 * Array of WhitelistRule.
56 * @throws \CRM_Core_Exception
58 public function __construct($rules) {
60 foreach ($rules as $rule) {
61 /** @var \Civi\API\WhitelistRule $rule */
62 if ($rule->isValid()) {
63 $this->rules
[] = $rule;
66 throw new \
CRM_Core_Exception("Invalid rule");
72 * Determine which, if any, whitelist rules apply this request.
73 * Reject unauthorized requests.
75 * @param \Civi\API\Event\AuthorizeEvent $event
76 * @throws \CRM_Core_Exception
78 public function onApiAuthorize(AuthorizeEvent
$event) {
79 $apiRequest = $event->getApiRequest();
80 if (empty($apiRequest['params']['check_permissions']) ||
$apiRequest['params']['check_permissions'] !== 'whitelist') {
83 foreach ($this->rules
as $rule) {
84 if (TRUE === $rule->matches($apiRequest)) {
85 $this->activeRules
[$apiRequest['id']] = $rule;
89 throw new \
CRM_Core_Exception('The request does not match any active API authorizations.');
93 * Apply any filtering rules based on the chosen whitelist rule.
94 * @param \Civi\API\Event\RespondEvent $event
96 public function onApiRespond(RespondEvent
$event) {
97 $apiRequest = $event->getApiRequest();
98 $id = $apiRequest['id'];
99 if (isset($this->activeRules
[$id])) {
100 $event->setResponse($this->activeRules
[$id]->filter($apiRequest, $event->getResponse()));
101 unset($this->activeRules
[$id]);