PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.5
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.5
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
← All changes | app/Http/Policies/AgentTicketPolicy.php +59 -47 2.2.0 → 2.4.5 View file →
@@ -8,16 +8,21 @@
8 8
9 9 class AgentTicketPolicy extends Policy
10 10 {
11 11 /**
12 - * Default policy check: GET requests require view permission, POST/PUT/DELETE require manage permission.
12 + * Reads need view permission, writes need manage permission.
13 13 *
14 - * @param \FluentSupport\Framework\Request\Request $request
14 + * Use getMethod(), not method(). method() returns the raw REQUEST_METHOD, but
15 + * WordPress dispatches on the _method / X-HTTP-Method-Override value, so a
16 + * write could pass as a GET.
17 + *
18 + * @param \FluentSupport\Framework\Http\Request\Request $request
15 19 * @return Boolean
16 20 */
17 21 public function verifyRequest(Request $request)
18 22 {
19 - if ($request->method() === 'GET') {
23 + // @phpstan-ignore-next-line -- proxied to WP_REST_Request by Request::__call()
24 + if ($request->getMethod() === 'GET') {
20 25 $status = PermissionManager::userCan([
21 26 'fst_view_tickets',
22 27 'fst_draft_reply',
23 28 'fst_manage_own_tickets',
@@ -24,11 +29,10 @@
24 29 'fst_manage_unassigned_tickets',
25 30 'fst_manage_other_tickets'
26 31 ]);
27 32 } else {
28 - // Non-GET requests require manage permission by default.
29 - // Routes safe for draft/view-only agents have dedicated policy methods
30 - // (e.g. createResponse, createOrUpdatDraft, storeOrUpdateLabelSearch).
33 + // Unknown verbs land here too. Writes open to draft/view-only agents
34 + // have their own policy methods below.
31 35 $status = PermissionManager::canManageTickets();
32 36 }
33 37
34 38 return apply_filters('fluent_support/agent_has_access', $status, $request);
@@ -34,33 +38,63 @@
34 38 return apply_filters('fluent_support/agent_has_access', $status, $request);
35 39 }
36 40
37 41 /**
38 - * Bulk actions: delete requires fst_delete_tickets, others require manage permission.
42 + * Backs the Add Ticket flow.
39 43 */
44 + public function searchContact(Request $request)
45 + {
46 + return PermissionManager::canManageTickets();
47 + }
48 +
49 + /**
50 + * Same gates as the single-ticket routes. Both assign actions write agent_id,
51 + * so both need fst_assign_agents.
52 + */
40 53 public function doBulkActions(Request $request)
41 54 {
42 55 $action = $request->getSafe('bulk_action', 'sanitize_text_field');
43 56
44 57 if ($action === 'delete_tickets') {
45 - return PermissionManager::currentUserCan('fst_delete_tickets');
58 + return PermissionManager::currentUserCan('fst_delete_tickets')
59 + && PermissionManager::canManageTickets();
46 60 }
47 61
62 + if ($action === 'assign_agent' || $action === 'assign_agent_group') {
63 + return PermissionManager::currentUserCan('fst_assign_agents')
64 + && PermissionManager::canManageTickets();
65 + }
66 +
48 67 return PermissionManager::canManageTickets();
49 68 }
50 69
51 70 /**
52 - * Delete ticket requires explicit delete permission.
71 + * View-only and draft agents see every ticket, so fst_delete_tickets alone
72 + * would let them delete any of them.
53 73 */
54 74 public function deleteTicket(Request $request)
55 75 {
56 - return PermissionManager::currentUserCan('fst_delete_tickets');
76 + return PermissionManager::currentUserCan('fst_delete_tickets')
77 + && PermissionManager::canManageTickets();
57 78 }
58 79
59 80 /**
60 - * Creating a response: accessible to manage and draft agents.
61 - * View-only agents cannot create responses or drafts.
81 + * Same gate as deleteTicket. The controller checks per-ticket access.
62 82 */
83 + public function deleteResponse(Request $request)
84 + {
85 + return PermissionManager::currentUserCan('fst_delete_tickets')
86 + && PermissionManager::canManageTickets();
87 + }
88 +
89 + /**
90 + * Author, type and per-ticket access are checked in the controller.
91 + */
92 + public function updateResponse(Request $request)
93 + {
94 + return PermissionManager::canManageTickets();
95 + }
96 +
63 97 public function createResponse(Request $request)
64 98 {
65 99 return PermissionManager::canManageTickets()
66 100 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -65,12 +99,8 @@
65 99 return PermissionManager::canManageTickets()
66 100 || PermissionManager::currentUserCan('fst_draft_reply');
67 101 }
68 102
69 - /**
70 - * Auto-save draft: accessible to manage and draft agents.
71 - * View-only agents cannot create drafts.
72 - */
73 103 public function createOrUpdatDraft(Request $request)
74 104 {
75 105 return PermissionManager::canManageTickets()
76 106 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -76,9 +106,9 @@
76 106 || PermissionManager::currentUserCan('fst_draft_reply');
77 107 }
78 108
79 109 /**
80 - * Label search save: POST endpoint accessible to any agent with ticket access.
110 + * Saved label searches are personal, so any agent with ticket access may write them.
81 111 */
82 112 public function storeOrUpdateLabelSearch(Request $request)
83 113 {
84 114 return PermissionManager::canAccessTicketRoutes();
@@ -83,67 +113,43 @@
83 113 {
84 114 return PermissionManager::canAccessTicketRoutes();
85 115 }
86 116
87 - /**
88 - * Label search delete: DELETE endpoint accessible to any agent (personal data).
89 - */
90 117 public function deleteLabelSearch(Request $request)
91 118 {
92 119 return PermissionManager::canAccessTicketRoutes();
93 120 }
94 121
95 - /**
96 - * Live activity removal: DELETE endpoint accessible to any agent (cleanup).
97 - */
98 122 public function removeLiveActivity(Request $request)
99 123 {
100 124 return PermissionManager::canAccessTicketRoutes();
101 125 }
102 126
103 - /**
104 - * Update ticket property (product, priority, etc.): requires manage ticket permission.
105 - */
106 127 public function updateTicketProperty(Request $request)
107 128 {
108 129 return PermissionManager::canManageTickets();
109 130 }
110 131
111 - /**
112 - * Add watchers to a ticket: requires manage ticket permission.
113 - */
114 132 public function addTicketWatchers(Request $request)
115 133 {
116 134 return PermissionManager::canManageTickets();
117 135 }
118 136
119 - /**
120 - * Sync watchers on a ticket: requires manage ticket permission.
121 - */
122 137 public function syncTicketWatchers(Request $request)
123 138 {
124 139 return PermissionManager::canManageTickets();
125 140 }
126 141
127 - /**
128 - * Update estimated time: requires manage ticket permission.
129 - */
130 142 public function updateEstimatedTime(Request $request)
131 143 {
132 144 return PermissionManager::canManageTickets();
133 145 }
134 146
135 - /**
136 - * Manual time commit: requires manage ticket permission.
137 - */
138 147 public function manualCommitTrack(Request $request)
139 148 {
140 149 return PermissionManager::canManageTickets();
141 150 }
142 151
143 - /**
144 - * Approve draft response: requires approve permission and ticket route access.
145 - */
146 152 public function approveDraftResponse(Request $request)
147 153 {
148 154 return PermissionManager::currentUserCan('fst_approve_draft_reply')
149 155 && PermissionManager::canAccessTicketRoutes();
@@ -148,11 +154,8 @@
148 154 return PermissionManager::currentUserCan('fst_approve_draft_reply')
149 155 && PermissionManager::canAccessTicketRoutes();
150 156 }
151 157
152 - /**
153 - * Delete draft: accessible to draft-capable agents (same as create/update draft).
154 - */
155 158 public function deleteDraft(Request $request)
156 159 {
157 160 return PermissionManager::canManageTickets()
158 161 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -157,11 +160,9 @@
157 160 return PermissionManager::canManageTickets()
158 161 || PermissionManager::currentUserCan('fst_draft_reply');
159 162 }
160 163
161 - /**
162 - * FluentBot AI-assist actions: accessible to any agent with ticket access.
163 - */
164 + // FluentBot AI-assist actions.
164 165 public function generateResponse(Request $request)
165 166 {
166 167 return PermissionManager::canAccessTicketRoutes();
167 168 }
@@ -210,8 +211,13 @@
210 211 {
211 212 return PermissionManager::canAccessTicketRoutes();
212 213 }
213 214
215 + public function getConversations(Request $request)
216 + {
217 + return PermissionManager::canAccessTicketRoutes();
218 + }
219 +
214 220 public function saveChatId(Request $request)
215 221 {
216 222 return PermissionManager::canManageTickets()
217 223 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -223,8 +229,14 @@
223 229 || PermissionManager::currentUserCan('fst_draft_reply');
224 230 }
225 231
226 232 public function saveContextSelection(Request $request)
233 + {
234 + return PermissionManager::canManageTickets()
235 + || PermissionManager::currentUserCan('fst_draft_reply');
236 + }
237 +
238 + public function switchConversation(Request $request)
227 239 {
228 240 return PermissionManager::canManageTickets()
229 241 || PermissionManager::currentUserCan('fst_draft_reply');
230 242 }