Afform - support file uploads
[civicrm-core.git] / Civi / API / Subscriber / WhitelistSubscriber.php
CommitLineData
66ea2662
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
41498ac5 4 | Copyright CiviCRM LLC. All rights reserved. |
66ea2662 5 | |
41498ac5
TO
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 |
66ea2662
TO
9 +--------------------------------------------------------------------+
10 */
11namespace Civi\API\Subscriber;
12
13use Civi\API\Events;
14use Civi\API\Event\AuthorizeEvent;
15use Civi\API\Event\RespondEvent;
66ea2662
TO
16use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17
18/**
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.
22 *
23 * @package Civi
ca5cec67 24 * @copyright CiviCRM LLC https://civicrm.org/licensing
66ea2662
TO
25 */
26class WhitelistSubscriber implements EventSubscriberInterface {
27
28 /**
29 * @return array
30 */
31 public static function getSubscribedEvents() {
c64f69d9 32 return [
39b870b8
TO
33 'civi.api.authorize' => ['onApiAuthorize', Events::W_EARLY],
34 'civi.api.respond' => ['onApiRespond', Events::W_MIDDLE],
c64f69d9 35 ];
66ea2662
TO
36 }
37
38 /**
39 * Array(WhitelistRule).
40 *
41 * @var array
42 */
43 protected $rules;
44
45 /**
46 * Array (scalar $reqId => WhitelistRule $rule).
47 *
48 * @var array
49 */
50 protected $activeRules;
51
52 /**
53 * @param array $rules
54 * Array of WhitelistRule.
55 * @see WhitelistRule
066c4638 56 * @throws \CRM_Core_Exception
66ea2662
TO
57 */
58 public function __construct($rules) {
c64f69d9 59 $this->rules = [];
66ea2662 60 foreach ($rules as $rule) {
34f3bbd9 61 /** @var \Civi\API\WhitelistRule $rule */
66ea2662
TO
62 if ($rule->isValid()) {
63 $this->rules[] = $rule;
64 }
65 else {
66 throw new \CRM_Core_Exception("Invalid rule");
67 }
68 }
69 }
70
71 /**
72 * Determine which, if any, whitelist rules apply this request.
73 * Reject unauthorized requests.
74 *
34f3bbd9 75 * @param \Civi\API\Event\AuthorizeEvent $event
66ea2662
TO
76 * @throws \CRM_Core_Exception
77 */
78 public function onApiAuthorize(AuthorizeEvent $event) {
79 $apiRequest = $event->getApiRequest();
80 if (empty($apiRequest['params']['check_permissions']) || $apiRequest['params']['check_permissions'] !== 'whitelist') {
81 return;
82 }
83 foreach ($this->rules as $rule) {
84 if (TRUE === $rule->matches($apiRequest)) {
85 $this->activeRules[$apiRequest['id']] = $rule;
86 return;
87 }
88 }
89 throw new \CRM_Core_Exception('The request does not match any active API authorizations.');
90 }
91
92 /**
93 * Apply any filtering rules based on the chosen whitelist rule.
34f3bbd9 94 * @param \Civi\API\Event\RespondEvent $event
66ea2662
TO
95 */
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]);
102 }
103 }
104
105}