| @@ -2,8 +2,9 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace FluentBooking\App\Http\Policies; |
| 4 | 4 | |
| 5 | 5 | use FluentBooking\App\Models\Calendar; |
| 6 | +use FluentBooking\App\Models\CalendarSlot; | |
| 6 | 7 | use FluentBooking\App\Services\PermissionManager; |
| 7 | 8 | use FluentBooking\Framework\Http\Request\Request; |
| 8 | 9 | use FluentBooking\Framework\Foundation\Policy; |
| 9 | 10 | |
| @@ -15,20 +16,32 @@ | ||
| 15 | 16 | * @return bool |
| 16 | 17 | */ |
| 17 | 18 | public function verifyRequest(Request $request) |
| 18 | 19 | { |
| 19 | - if (current_user_can('manage_options')) { | |
| 20 | + if (PermissionManager::userCan('manage_all_data')) { | |
| 20 | 21 | return true; |
| 21 | 22 | } |
| 22 | 23 | |
| 23 | - $calendarId = $request->calendar_id; | |
| 24 | + // Resolve IDs strictly from URL route params; request-body values | |
| 25 | + // must never be allowed to redirect the authorization target. | |
| 26 | + $calendarId = (int) $this->getRouteParam($request, 'id'); | |
| 27 | + $eventId = (int) $this->getRouteParam($request, 'event_id'); | |
| 24 | 28 | |
| 25 | 29 | if (!$calendarId) { |
| 26 | 30 | return apply_filters('fluent_booking/verify_calendar_api', current_user_can('manage_options'), $request); |
| 27 | 31 | } |
| 28 | 32 | |
| 29 | - $method = $request->method(); | |
| 33 | + if ($eventId && !CalendarSlot::where('calendar_id', $calendarId)->where('id', $eventId)->exists()) { | |
| 34 | + return false; | |
| 35 | + } | |
| 30 | 36 | |
| 37 | + $method = $request->getMethod(); | |
| 38 | + | |
| 39 | + // Event-scoped for reads too: hosting one event must not expose its sibling events' settings. | |
| 40 | + if ($eventId) { | |
| 41 | + return PermissionManager::canUpdateCalendarEvent($eventId); | |
| 42 | + } | |
| 43 | + | |
| 31 | 44 | if ($method == 'GET') { |
| 32 | 45 | return PermissionManager::canReadCalendar($calendarId); |
| 33 | 46 | } |
| 34 | 47 | |
| @@ -36,48 +49,82 @@ | ||
| 36 | 49 | } |
| 37 | 50 | |
| 38 | 51 | public function getAllCalendars(Request $request) |
| 39 | 52 | { |
| 40 | - return !!PermissionManager::currentUserHasAnyPemrmission(); | |
| 53 | + return !!PermissionManager::currentUserHasAnyPermission(); | |
| 41 | 54 | } |
| 42 | 55 | |
| 43 | 56 | public function createCalendar(Request $request) |
| 44 | 57 | { |
| 45 | - if (PermissionManager::userCan('invite_team_members')) { | |
| 58 | + return $this->canCreateCalendar(); | |
| 59 | + } | |
| 60 | + | |
| 61 | + public function checkSlug(Request $request) | |
| 62 | + { | |
| 63 | + return $this->canCreateCalendar(); | |
| 64 | + } | |
| 65 | + | |
| 66 | + public function getNewEventLocationFields(Request $request) | |
| 67 | + { | |
| 68 | + return $this->canCreateCalendar(); | |
| 69 | + } | |
| 70 | + | |
| 71 | + public function getEvent(Request $request, $calendarId, $eventId) | |
| 72 | + { | |
| 73 | + return PermissionManager::canUpdateCalendarEvent($eventId); | |
| 74 | + } | |
| 75 | + | |
| 76 | + public function deleteCalendar(Request $request) | |
| 77 | + { | |
| 78 | + if (PermissionManager::userCan('manage_all_data')) { | |
| 46 | 79 | return true; |
| 47 | 80 | } |
| 48 | 81 | |
| 49 | - if (PermissionManager::userCan('manage_own_calendar')) { | |
| 82 | + $calendarId = (int) $this->getRouteParam($request, 'id'); | |
| 50 | 83 | |
| 51 | - $exist = Calendar::where('user_id', get_current_user_id())->first(); | |
| 52 | - if (!$exist) { | |
| 53 | - return true; | |
| 54 | - } | |
| 84 | + $calendar = Calendar::find($calendarId); | |
| 55 | 85 | |
| 56 | - return true; | |
| 86 | + if (!$calendar) { | |
| 87 | + return false; | |
| 57 | 88 | } |
| 58 | 89 | |
| 90 | + return $calendar->user_id == get_current_user_id(); | |
| 59 | 91 | } |
| 60 | 92 | |
| 61 | - public function checkSlug(Request $request) | |
| 93 | + public function deleteCalendarEvent(Request $request) | |
| 62 | 94 | { |
| 63 | - return PermissionManager::userCan(['invite_team_members', 'manage_own_calendar']); | |
| 95 | + return $this->deleteCalendar($request); | |
| 64 | 96 | } |
| 65 | 97 | |
| 66 | - public function deleteCalendar(Request $request) | |
| 98 | + public function cloneCalendarEvent(Request $request) | |
| 67 | 99 | { |
| 68 | - if (current_user_can('manage_options')) { | |
| 100 | + if (PermissionManager::userCan('manage_all_data')) { | |
| 69 | 101 | return true; |
| 70 | 102 | } |
| 71 | 103 | |
| 72 | - $calendarId = $request->id; | |
| 104 | + $eventId = (int) $this->getRouteParam($request, 'event_id'); | |
| 73 | 105 | |
| 74 | - $calendar = Calendar::find($calendarId); | |
| 106 | + if (!$eventId || !PermissionManager::canUpdateCalendarEvent($eventId)) { | |
| 107 | + return false; | |
| 108 | + } | |
| 75 | 109 | |
| 76 | - return $calendar->user_id === get_current_user_id(); | |
| 110 | + $sourceCalendarId = (int) $this->getRouteParam($request, 'id'); | |
| 111 | + $destinationCalendarId = intval($request->get('new_calendar_id')) ?: $sourceCalendarId; | |
| 112 | + | |
| 113 | + return PermissionManager::canWriteCalendar($destinationCalendarId); | |
| 77 | 114 | } |
| 78 | 115 | |
| 79 | - public function deleteCalendarEvent(Request $request) | |
| 116 | + private function canCreateCalendar() | |
| 80 | 117 | { |
| 81 | - return $this->deleteCalendar($request); | |
| 118 | + return PermissionManager::userCan(['manage_all_data', 'invite_team_members', 'manage_own_calendar']); | |
| 119 | + } | |
| 120 | + | |
| 121 | + /** | |
| 122 | + * Read a URL route parameter. Some routes here (event-lists, root listing, | |
| 123 | + * create) have no placeholder, so direct access would warn. | |
| 124 | + */ | |
| 125 | + private function getRouteParam(Request $request, $key) | |
| 126 | + { | |
| 127 | + $params = (array) $request->get_url_params(); | |
| 128 | + return isset($params[$key]) ? $params[$key] : null; | |
| 82 | 129 | } |
| 83 | 130 | } |