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 +21 -62 2.3.2 → 2.4.5 View file →
@@ -8,17 +8,15 @@
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 - * 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).
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.
19 17 *
20 - * @param \FluentSupport\Framework\Request\Request $request
18 + * @param \FluentSupport\Framework\Http\Request\Request $request
21 19 * @return Boolean
22 20 */
23 21 public function verifyRequest(Request $request)
24 22 {
@@ -31,12 +29,10 @@
31 29 'fst_manage_unassigned_tickets',
32 30 'fst_manage_other_tickets'
33 31 ]);
34 32 } 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).
33 + // Unknown verbs land here too. Writes open to draft/view-only agents
34 + // have their own policy methods below.
39 35 $status = PermissionManager::canManageTickets();
40 36 }
41 37
42 38 return apply_filters('fluent_support/agent_has_access', $status, $request);
@@ -42,10 +38,9 @@
42 38 return apply_filters('fluent_support/agent_has_access', $status, $request);
43 39 }
44 40
45 41 /**
46 - * Contact search backs the Add Ticket flow, so any agent who can manage
47 - * tickets needs it to work.
42 + * Backs the Add Ticket flow.
48 43 */
49 44 public function searchContact(Request $request)
50 45 {
51 46 return PermissionManager::canManageTickets();
@@ -51,10 +46,10 @@
51 46 return PermissionManager::canManageTickets();
52 47 }
53 48
54 49 /**
55 - * Bulk actions: delete requires fst_delete_tickets plus manage permission
56 - * (mirroring deleteTicket), others require manage permission.
50 + * Same gates as the single-ticket routes. Both assign actions write agent_id,
51 + * so both need fst_assign_agents.
57 52 */
58 53 public function doBulkActions(Request $request)
59 54 {
60 55 $action = $request->getSafe('bulk_action', 'sanitize_text_field');
@@ -63,15 +58,19 @@
63 58 return PermissionManager::currentUserCan('fst_delete_tickets')
64 59 && PermissionManager::canManageTickets();
65 60 }
66 61
62 + if ($action === 'assign_agent' || $action === 'assign_agent_group') {
63 + return PermissionManager::currentUserCan('fst_assign_agents')
64 + && PermissionManager::canManageTickets();
65 + }
66 +
67 67 return PermissionManager::canManageTickets();
68 68 }
69 69
70 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.
71 + * View-only and draft agents see every ticket, so fst_delete_tickets alone
72 + * would let them delete any of them.
74 73 */
75 74 public function deleteTicket(Request $request)
76 75 {
77 76 return PermissionManager::currentUserCan('fst_delete_tickets')
@@ -78,11 +77,9 @@
78 77 && PermissionManager::canManageTickets();
79 78 }
80 79
81 80 /**
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().
81 + * Same gate as deleteTicket. The controller checks per-ticket access.
85 82 */
86 83 public function deleteResponse(Request $request)
87 84 {
88 85 return PermissionManager::currentUserCan('fst_delete_tickets')
@@ -89,10 +86,9 @@
89 86 && PermissionManager::canManageTickets();
90 87 }
91 88
92 89 /**
93 - * Update an individual response: requires manage permission. Author/type
94 - * and per-ticket access rules are enforced in the controller.
90 + * Author, type and per-ticket access are checked in the controller.
95 91 */
96 92 public function updateResponse(Request $request)
97 93 {
98 94 return PermissionManager::canManageTickets();
@@ -97,12 +93,8 @@
97 93 {
98 94 return PermissionManager::canManageTickets();
99 95 }
100 96
101 - /**
102 - * Creating a response: accessible to manage and draft agents.
103 - * View-only agents cannot create responses or drafts.
104 - */
105 97 public function createResponse(Request $request)
106 98 {
107 99 return PermissionManager::canManageTickets()
108 100 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -107,12 +99,8 @@
107 99 return PermissionManager::canManageTickets()
108 100 || PermissionManager::currentUserCan('fst_draft_reply');
109 101 }
110 102
111 - /**
112 - * Auto-save draft: accessible to manage and draft agents.
113 - * View-only agents cannot create drafts.
114 - */
115 103 public function createOrUpdatDraft(Request $request)
116 104 {
117 105 return PermissionManager::canManageTickets()
118 106 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -118,9 +106,9 @@
118 106 || PermissionManager::currentUserCan('fst_draft_reply');
119 107 }
120 108
121 109 /**
122 - * 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.
123 111 */
124 112 public function storeOrUpdateLabelSearch(Request $request)
125 113 {
126 114 return PermissionManager::canAccessTicketRoutes();
@@ -125,67 +113,43 @@
125 113 {
126 114 return PermissionManager::canAccessTicketRoutes();
127 115 }
128 116
129 - /**
130 - * Label search delete: DELETE endpoint accessible to any agent (personal data).
131 - */
132 117 public function deleteLabelSearch(Request $request)
133 118 {
134 119 return PermissionManager::canAccessTicketRoutes();
135 120 }
136 121
137 - /**
138 - * Live activity removal: DELETE endpoint accessible to any agent (cleanup).
139 - */
140 122 public function removeLiveActivity(Request $request)
141 123 {
142 124 return PermissionManager::canAccessTicketRoutes();
143 125 }
144 126
145 - /**
146 - * Update ticket property (product, priority, etc.): requires manage ticket permission.
147 - */
148 127 public function updateTicketProperty(Request $request)
149 128 {
150 129 return PermissionManager::canManageTickets();
151 130 }
152 131
153 - /**
154 - * Add watchers to a ticket: requires manage ticket permission.
155 - */
156 132 public function addTicketWatchers(Request $request)
157 133 {
158 134 return PermissionManager::canManageTickets();
159 135 }
160 136
161 - /**
162 - * Sync watchers on a ticket: requires manage ticket permission.
163 - */
164 137 public function syncTicketWatchers(Request $request)
165 138 {
166 139 return PermissionManager::canManageTickets();
167 140 }
168 141
169 - /**
170 - * Update estimated time: requires manage ticket permission.
171 - */
172 142 public function updateEstimatedTime(Request $request)
173 143 {
174 144 return PermissionManager::canManageTickets();
175 145 }
176 146
177 - /**
178 - * Manual time commit: requires manage ticket permission.
179 - */
180 147 public function manualCommitTrack(Request $request)
181 148 {
182 149 return PermissionManager::canManageTickets();
183 150 }
184 151
185 - /**
186 - * Approve draft response: requires approve permission and ticket route access.
187 - */
188 152 public function approveDraftResponse(Request $request)
189 153 {
190 154 return PermissionManager::currentUserCan('fst_approve_draft_reply')
191 155 && PermissionManager::canAccessTicketRoutes();
@@ -190,11 +154,8 @@
190 154 return PermissionManager::currentUserCan('fst_approve_draft_reply')
191 155 && PermissionManager::canAccessTicketRoutes();
192 156 }
193 157
194 - /**
195 - * Delete draft: accessible to draft-capable agents (same as create/update draft).
196 - */
197 158 public function deleteDraft(Request $request)
198 159 {
199 160 return PermissionManager::canManageTickets()
200 161 || PermissionManager::currentUserCan('fst_draft_reply');
@@ -199,11 +160,9 @@
199 160 return PermissionManager::canManageTickets()
200 161 || PermissionManager::currentUserCan('fst_draft_reply');
201 162 }
202 163
203 - /**
204 - * FluentBot AI-assist actions: accessible to any agent with ticket access.
205 - */
164 + // FluentBot AI-assist actions.
206 165 public function generateResponse(Request $request)
207 166 {
208 167 return PermissionManager::canAccessTicketRoutes();
209 168 }