PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.3.2
Fluent Support – Helpdesk & Customer Support Ticket System v2.3.2
2.4.5 2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 All 69 releases
fluent-support / app / Http / Policies / AgentTicketPolicy.php

AgentTicketPolicy.php in Fluent Support – Helpdesk & Customer Support Ticket System 2.3.2, at app/Http/Policies/AgentTicketPolicy.php

297 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Policies;
4
5 use FluentSupport\App\Modules\PermissionManager;
6 use FluentSupport\Framework\Http\Request\Request;
7 use FluentSupport\Framework\Foundation\Policy;
8
9 class AgentTicketPolicy extends Policy
10 {
11 /**
12 * Default policy check: GET requests require view permission, POST/PUT/DELETE require manage permission.
13 *
14 * Use getMethod() (WP_REST_Request::get_method()), never method() — that one
15 * returns $_SERVER['REQUEST_METHOD'] raw. WordPress dispatches on the
16 * `?_method=` / `X-HTTP-Method-Override` value but leaves the raw server
17 * value alone, so reading it here let a view-only agent run a write handler
18 * under the read capability (FS-SEC-025).
19 *
20 * @param \FluentSupport\Framework\Request\Request $request
21 * @return Boolean
22 */
23 public function verifyRequest(Request $request)
24 {
25 // @phpstan-ignore-next-line -- proxied to WP_REST_Request by Request::__call()
26 if ($request->getMethod() === 'GET') {
27 $status = PermissionManager::userCan([
28 'fst_view_tickets',
29 'fst_draft_reply',
30 'fst_manage_own_tickets',
31 'fst_manage_unassigned_tickets',
32 'fst_manage_other_tickets'
33 ]);
34 } else {
35 // Non-GET requests require manage permission by default. An
36 // unreadable verb also lands here, which is the safe side.
37 // Routes safe for draft/view-only agents have dedicated policy methods
38 // (e.g. createResponse, createOrUpdatDraft, storeOrUpdateLabelSearch).
39 $status = PermissionManager::canManageTickets();
40 }
41
42 return apply_filters('fluent_support/agent_has_access', $status, $request);
43 }
44
45 /**
46 * Contact search backs the Add Ticket flow, so any agent who can manage
47 * tickets needs it to work.
48 */
49 public function searchContact(Request $request)
50 {
51 return PermissionManager::canManageTickets();
52 }
53
54 /**
55 * Bulk actions: delete requires fst_delete_tickets plus manage permission
56 * (mirroring deleteTicket), others require manage permission.
57 */
58 public function doBulkActions(Request $request)
59 {
60 $action = $request->getSafe('bulk_action', 'sanitize_text_field');
61
62 if ($action === 'delete_tickets') {
63 return PermissionManager::currentUserCan('fst_delete_tickets')
64 && PermissionManager::canManageTickets();
65 }
66
67 return PermissionManager::canManageTickets();
68 }
69
70 /**
71 * Delete ticket requires explicit delete permission and manage permission.
72 * View-only and draft agents resolve to full ticket visibility, so the
73 * delete capability alone would let them delete any ticket.
74 */
75 public function deleteTicket(Request $request)
76 {
77 return PermissionManager::currentUserCan('fst_delete_tickets')
78 && PermissionManager::canManageTickets();
79 }
80
81 /**
82 * Delete an individual response: requires explicit delete permission and
83 * manage permission, mirroring deleteTicket. Per-ticket access is enforced
84 * in the controller via ensureCanAccessTicket().
85 */
86 public function deleteResponse(Request $request)
87 {
88 return PermissionManager::currentUserCan('fst_delete_tickets')
89 && PermissionManager::canManageTickets();
90 }
91
92 /**
93 * Update an individual response: requires manage permission. Author/type
94 * and per-ticket access rules are enforced in the controller.
95 */
96 public function updateResponse(Request $request)
97 {
98 return PermissionManager::canManageTickets();
99 }
100
101 /**
102 * Creating a response: accessible to manage and draft agents.
103 * View-only agents cannot create responses or drafts.
104 */
105 public function createResponse(Request $request)
106 {
107 return PermissionManager::canManageTickets()
108 || PermissionManager::currentUserCan('fst_draft_reply');
109 }
110
111 /**
112 * Auto-save draft: accessible to manage and draft agents.
113 * View-only agents cannot create drafts.
114 */
115 public function createOrUpdatDraft(Request $request)
116 {
117 return PermissionManager::canManageTickets()
118 || PermissionManager::currentUserCan('fst_draft_reply');
119 }
120
121 /**
122 * Label search save: POST endpoint accessible to any agent with ticket access.
123 */
124 public function storeOrUpdateLabelSearch(Request $request)
125 {
126 return PermissionManager::canAccessTicketRoutes();
127 }
128
129 /**
130 * Label search delete: DELETE endpoint accessible to any agent (personal data).
131 */
132 public function deleteLabelSearch(Request $request)
133 {
134 return PermissionManager::canAccessTicketRoutes();
135 }
136
137 /**
138 * Live activity removal: DELETE endpoint accessible to any agent (cleanup).
139 */
140 public function removeLiveActivity(Request $request)
141 {
142 return PermissionManager::canAccessTicketRoutes();
143 }
144
145 /**
146 * Update ticket property (product, priority, etc.): requires manage ticket permission.
147 */
148 public function updateTicketProperty(Request $request)
149 {
150 return PermissionManager::canManageTickets();
151 }
152
153 /**
154 * Add watchers to a ticket: requires manage ticket permission.
155 */
156 public function addTicketWatchers(Request $request)
157 {
158 return PermissionManager::canManageTickets();
159 }
160
161 /**
162 * Sync watchers on a ticket: requires manage ticket permission.
163 */
164 public function syncTicketWatchers(Request $request)
165 {
166 return PermissionManager::canManageTickets();
167 }
168
169 /**
170 * Update estimated time: requires manage ticket permission.
171 */
172 public function updateEstimatedTime(Request $request)
173 {
174 return PermissionManager::canManageTickets();
175 }
176
177 /**
178 * Manual time commit: requires manage ticket permission.
179 */
180 public function manualCommitTrack(Request $request)
181 {
182 return PermissionManager::canManageTickets();
183 }
184
185 /**
186 * Approve draft response: requires approve permission and ticket route access.
187 */
188 public function approveDraftResponse(Request $request)
189 {
190 return PermissionManager::currentUserCan('fst_approve_draft_reply')
191 && PermissionManager::canAccessTicketRoutes();
192 }
193
194 /**
195 * Delete draft: accessible to draft-capable agents (same as create/update draft).
196 */
197 public function deleteDraft(Request $request)
198 {
199 return PermissionManager::canManageTickets()
200 || PermissionManager::currentUserCan('fst_draft_reply');
201 }
202
203 /**
204 * FluentBot AI-assist actions: accessible to any agent with ticket access.
205 */
206 public function generateResponse(Request $request)
207 {
208 return PermissionManager::canAccessTicketRoutes();
209 }
210
211 public function getRuntimeConfig(Request $request)
212 {
213 return PermissionManager::canAccessTicketRoutes();
214 }
215
216 public function generateStreamResponse(Request $request)
217 {
218 return PermissionManager::canAccessTicketRoutes();
219 }
220
221 public function getTicketSummary(Request $request)
222 {
223 return PermissionManager::canAccessTicketRoutes();
224 }
225
226 public function getTicketTone(Request $request)
227 {
228 return PermissionManager::canAccessTicketRoutes();
229 }
230
231 public function markRead(Request $request)
232 {
233 return PermissionManager::canAccessTicketRoutes();
234 }
235
236 public function markAllRead(Request $request)
237 {
238 return PermissionManager::canAccessTicketRoutes();
239 }
240
241 public function getChatId(Request $request)
242 {
243 return PermissionManager::canAccessTicketRoutes();
244 }
245
246 public function getChatMessages(Request $request)
247 {
248 return PermissionManager::canAccessTicketRoutes();
249 }
250
251 public function getContextSelection(Request $request)
252 {
253 return PermissionManager::canAccessTicketRoutes();
254 }
255
256 public function getConversations(Request $request)
257 {
258 return PermissionManager::canAccessTicketRoutes();
259 }
260
261 public function saveChatId(Request $request)
262 {
263 return PermissionManager::canManageTickets()
264 || PermissionManager::currentUserCan('fst_draft_reply');
265 }
266
267 public function deleteChatId(Request $request)
268 {
269 return PermissionManager::canManageTickets()
270 || PermissionManager::currentUserCan('fst_draft_reply');
271 }
272
273 public function saveContextSelection(Request $request)
274 {
275 return PermissionManager::canManageTickets()
276 || PermissionManager::currentUserCan('fst_draft_reply');
277 }
278
279 public function switchConversation(Request $request)
280 {
281 return PermissionManager::canManageTickets()
282 || PermissionManager::currentUserCan('fst_draft_reply');
283 }
284
285 public function createFeedback(Request $request)
286 {
287 return PermissionManager::canManageTickets()
288 || PermissionManager::currentUserCan('fst_draft_reply');
289 }
290
291 public function deleteFeedback(Request $request)
292 {
293 return PermissionManager::canManageTickets()
294 || PermissionManager::currentUserCan('fst_draft_reply');
295 }
296 }
297