PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.7
Booking for Appointments and Events Calendar – Amelia v2.4.7
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Application / Commands / Command.php
ameliabooking / src / Application / Commands Last commit date
Bookable 1 month ago Booking 2 weeks ago Calendar 3 weeks ago Entities 3 weeks ago Google 5 months ago Import 1 month ago Mobile 2 months ago Notification 2 months ago Payment 1 month ago QrCode 3 weeks ago Settings 1 month ago Square 8 months ago Stash 3 weeks ago Stats 8 months ago Test 8 months ago User 2 weeks ago WhatsNew 5 months ago Command.php 2 weeks ago CommandHandler.php 7 years ago CommandResult.php 6 months ago SortParamsTrait.php 5 months ago
Command.php
390 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands;
4
5 use AmeliaBooking\Application\Common\Exceptions\AccessDeniedException;
6 use AmeliaBooking\Application\Commands\Booking\Appointment\AddBookingCommand;
7 use AmeliaBooking\Application\Commands\Booking\Appointment\DeleteBookingRemotelyCommand;
8 use AmeliaBooking\Application\Commands\Booking\Appointment\SuccessfulBookingCommand;
9 use AmeliaBooking\Application\Commands\Notification\SendUndeliveredNotificationsCommand;
10 use AmeliaBooking\Application\Commands\Notification\UpdateSMSNotificationHistoryCommand;
11 use AmeliaBooking\Application\Commands\Outlook\FetchAccessTokenWithAuthCodeOutlookCommand;
12 use AmeliaBooking\Application\Commands\Payment\CalculatePaymentAmountCommand;
13 use AmeliaBooking\Application\Commands\Square\DisconnectFromSquareAccountCommand;
14 use AmeliaBooking\Application\Commands\Square\SquareRefundWebhookCommand;
15 use AmeliaBooking\Application\Services\User\UserApplicationService;
16 use AmeliaBooking\Domain\Entity\Entities;
17 use AmeliaBooking\Domain\Entity\User\AbstractUser;
18 use AmeliaBooking\Domain\Common\Exceptions\AuthorizationException;
19 use AmeliaBooking\Domain\Services\Permissions\PermissionsService;
20 use AmeliaBooking\Domain\Services\Settings\SettingsService;
21 use AmeliaBooking\Infrastructure\WP\SettingsService\SettingsStorage;
22 use AmeliaVendor\Psr\Http\Message\ServerRequestInterface as Request;
23
24 /**
25 * Class Command
26 *
27 * @package AmeliaBooking\Application\Commands
28 */
29 abstract class Command
30 {
31 protected $args;
32
33 protected $container;
34
35 private $fields = [];
36
37 public $token;
38
39 private $page;
40
41 private $cabinetType;
42
43 private $permissionService;
44
45 private $userApplicationService;
46
47 /**
48 * Command constructor.
49 *
50 * @param $args
51 */
52 public function __construct($args)
53 {
54 $this->args = $args;
55 if (isset($args['type'])) {
56 $this->setField('type', $args['type']);
57 }
58 }
59
60 /**
61 * @return mixed
62 */
63 public function getArgs()
64 {
65 return $this->args;
66 }
67
68 /**
69 * @param mixed $arg Argument to be fetched
70 *
71 * @return null|mixed
72 */
73 public function getArg($arg)
74 {
75 return isset($this->args[$arg]) ? $this->args[$arg] : null;
76 }
77
78 /**
79 * @param $fieldName
80 * @param $fieldValue
81 */
82 public function setField($fieldName, $fieldValue)
83 {
84 $this->fields[$fieldName] = $fieldValue;
85 }
86
87 /**
88 * @param $fieldName
89 */
90 public function removeField($fieldName)
91 {
92 unset($this->fields[$fieldName]);
93 }
94
95 /**
96 * Return a single field
97 *
98 * @param $fieldName
99 *
100 * @return mixed|null
101 */
102 public function getField($fieldName)
103 {
104 return isset($this->fields[$fieldName]) ? $this->fields[$fieldName] : null;
105 }
106
107 /**
108 * Return all fields
109 *
110 * @return array
111 */
112 public function getFields()
113 {
114 return $this->fields;
115 }
116
117 /**
118 * Set Token
119 *
120 * @param Request $request
121 */
122 public function setToken($request)
123 {
124 $token = null;
125
126 /** @var SettingsService $settingsService */
127 $settingsService = new SettingsService(new SettingsStorage());
128
129 $authorization = $request->getHeaderLine('Authorization');
130
131 if (
132 $authorization !== '' &&
133 ($values = explode(' ', $authorization)) &&
134 sizeof($values) === 2 &&
135 $settingsService->getSetting('roles', 'enabledHttpAuthorization')
136 ) {
137 $token = $values[1];
138 } else {
139 $cookies = $request->getCookieParams();
140 if (!empty($cookies['ameliaToken'])) {
141 $token = $cookies['ameliaToken'];
142 }
143 }
144
145 $this->token = $token;
146 }
147
148 /**
149 * Return Token
150 *
151 * @return string|null
152 */
153 public function getToken()
154 {
155 return $this->token;
156 }
157
158 /**
159 * Set page
160 *
161 * @param string $page
162 */
163 public function setPage($page)
164 {
165 $this->page = explode('-', $page)[0];
166
167 $this->cabinetType = !empty(explode('-', $page)[1]) ? explode('-', $page)[1] : null;
168 }
169
170 /**
171 * Return page
172 *
173 * @return string|null
174 */
175 public function getPage()
176 {
177 return $this->page;
178 }
179
180 /**
181 * @param $request
182 * @return int|boolean
183 */
184 public function validateNonce($request)
185 {
186 if (
187 $request->getMethod() === 'POST' &&
188 !self::getToken() &&
189 !($this instanceof CalculatePaymentAmountCommand) &&
190 !($this instanceof AddBookingCommand) &&
191 !($this instanceof DeleteBookingRemotelyCommand) &&
192 !($this instanceof SquareRefundWebhookCommand) &&
193 !($this instanceof DisconnectFromSquareAccountCommand) &&
194 !($this instanceof SuccessfulBookingCommand) &&
195 !($this instanceof FetchAccessTokenWithAuthCodeOutlookCommand) &&
196 !($this instanceof UpdateSMSNotificationHistoryCommand)
197 ) {
198 $queryParams = $request->getQueryParams();
199
200 return wp_verify_nonce(
201 !empty($queryParams['wpAmeliaNonce']) ? $queryParams['wpAmeliaNonce'] : $queryParams['ameliaNonce'],
202 'ajax-nonce'
203 );
204 }
205
206 return true;
207 }
208
209 /**
210 * Commands listed here are meant to be run from an external cron job, so they are reached with a GET request that
211 * carries neither a nonce nor a logged in user. They are protected with a secret key, generated per site and
212 * stored in the "activation" settings, that has to be passed as a "cronKey" query parameter.
213 *
214 * @param $request
215 * @return boolean
216 */
217 public function validateCron($request)
218 {
219 if (!($this instanceof SendUndeliveredNotificationsCommand)) {
220 return true;
221 }
222
223 $settingsService = new SettingsService(new SettingsStorage());
224
225 $cronKey = $settingsService->getSetting('activation', 'cronKey');
226
227 if (empty($cronKey)) {
228 return false;
229 }
230
231 $queryParams = $request->getQueryParams();
232
233 $givenKey = !empty($queryParams['cronKey']) ? $queryParams['cronKey'] : '';
234
235 return is_string($givenKey) && hash_equals((string)$cronKey, $givenKey);
236 }
237
238 /**
239 * Return cabinet type
240 *
241 * @return string|null
242 */
243 public function getCabinetType()
244 {
245 return $this->cabinetType;
246 }
247
248 /**
249 * @return PermissionsService
250 */
251 public function getPermissionService()
252 {
253 return $this->permissionService;
254 }
255
256 /**
257 * @param PermissionsService $permissionService
258 */
259 public function setPermissionService($permissionService)
260 {
261 $this->permissionService = $permissionService;
262 }
263
264 /**
265 * @return UserApplicationService
266 */
267 public function getUserApplicationService()
268 {
269 return $this->userApplicationService;
270 }
271
272 /**
273 * @param UserApplicationService $userApplicationService
274 */
275 public function setUserApplicationService($userApplicationService)
276 {
277 $this->userApplicationService = $userApplicationService;
278 }
279
280 /**
281 * Authorize user
282 *
283 * @return AbstractUser
284 * @throws AuthorizationException
285 * @throws AccessDeniedException
286 */
287 public function authorize($type = null): AbstractUser
288 {
289 if ($type === AbstractUser::USER_ROLE_PROVIDER || $type === AbstractUser::USER_ROLE_CUSTOMER) {
290 /** @var AbstractUser $user */
291 $user = $this->getUserApplicationService()->authorization(
292 $this->getToken(),
293 $type
294 );
295
296 // If user is admin or manager, return user
297 if (
298 $user && (
299 $user->getType() === AbstractUser::USER_ROLE_ADMIN ||
300 $user->getType() === AbstractUser::USER_ROLE_MANAGER
301 )
302 ) {
303 return $user;
304 }
305
306 // If user is not admin or manager, check if user is of the given type
307 if (!$user || $user->getType() !== $type) {
308 throw new AccessDeniedException('You are not allowed');
309 }
310
311 return $user;
312 }
313
314 return $this->getUserApplicationService()->authorization(
315 $this->getPage() === 'cabinet' ? $this->getToken() : null,
316 $this->getCabinetType()
317 );
318 }
319
320 /**
321 * Authorize provider read permission
322 *
323 * @param int $userId
324 * @param string $entity
325 *
326 * @return AbstractUser
327 *
328 * @throws AuthorizationException
329 * @throws AccessDeniedException
330 */
331 public function authorizeProviderReadPermission(int $userId, string $entity = Entities::EMPLOYEES): AbstractUser
332 {
333 // if logged in user is not WP admin, WP Amelia manager or WP Amelia provider, try to authorize as non WP Amelia provider
334 if (
335 !$this->getPermissionService()->currentUserCanRead($entity) ||
336 !$this->getPermissionService()->currentUserCanReadOthers($entity)
337 ) {
338 /** @var AbstractUser $user */
339 $user = $this->authorize(Entities::PROVIDER);
340
341 // if authorized as non WP Amelia provider, check if user ID is the same as the requested user ID
342 if (
343 $user->getType() === AbstractUser::USER_ROLE_PROVIDER &&
344 $user->getId()->getValue() !== $userId
345 ) {
346 throw new AccessDeniedException('You are not allowed');
347 }
348
349 return $user;
350 }
351
352 return $this->getUserApplicationService()->authorization(null, null);
353 }
354
355 /**
356 * Authorize provider write permission
357 *
358 * @param int $userId
359 * @param string $entity
360 *
361 * @return AbstractUser
362 *
363 * @throws AuthorizationException
364 * @throws AccessDeniedException
365 */
366 public function authorizeProviderWritePermission(int $userId, string $entity = Entities::EMPLOYEES): AbstractUser
367 {
368 // if logged in user is not WP admin, WP Amelia manager or WP Amelia provider, try to authorize as non WP Amelia provider
369 if (
370 !$this->getPermissionService()->currentUserCanWrite($entity) ||
371 !$this->getPermissionService()->currentUserCanWriteOthers($entity)
372 ) {
373 /** @var AbstractUser $user */
374 $user = $this->authorize(Entities::PROVIDER);
375
376 // if authorized as non WP Amelia provider, check if user ID is the same as the requested user ID
377 if (
378 $user->getType() === AbstractUser::USER_ROLE_PROVIDER &&
379 $user->getId()->getValue() !== $userId
380 ) {
381 throw new AccessDeniedException('You are not allowed');
382 }
383
384 return $user;
385 }
386
387 return $this->getUserApplicationService()->authorization(null, null);
388 }
389 }
390