PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.2.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.2.0
2.2.0 2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 All 43 releases
fluent-boards / app / Services / PermissionManager.php

PermissionManager.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.2.0, at app/Services/PermissionManager.php

483 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\App\Services;
4
5 use FluentBoards\App\Models\Board;
6 use FluentBoards\App\Models\Relation;
7 use FluentBoards\App\Models\Meta;
8 use FluentBoards\App\Services\Constant;
9
10 class PermissionManager
11 {
12 public static function getFormattedBoardPermissions()
13 {
14 return [
15 'board_admin' => 'Board Admin',
16 'create_tasks' => 'Create Tasks',
17 'edit_tasks' => 'Edit Tasks',
18 'delete_tasks' => 'Delete Tasks',
19 ];
20 }
21
22 public static function getTopLevelPermissions()
23 {
24 return [
25 'all_board_admin' => 'All Board Admin',
26 'create_boards' => 'Create Boards',
27 'edit_boards' => 'Edit Boards',
28 'delete_boards' => 'Delete Boards',
29 'can_manage_permissions' => 'Can Manage Permissions',
30 ];
31 }
32
33 public static function getBoardPermissions($boardId, $userId)
34 {
35 if (user_can($userId, 'manage_options')) {
36 return array_keys(self::getFormattedBoardPermissions());
37 }
38
39 $globalPermissions = self::getTopUserPermission($userId);
40
41 if (in_array('all_board_admin', $globalPermissions)) {
42 return array_keys(self::getFormattedBoardPermissions());
43 }
44
45 // The user does not have global permission now we are checking for board permission
46
47 $isUserOn = Relation::query()->where('board_id', $boardId)->where('user_id', $userId)->exists();
48
49 $permissions = [
50
51 ];
52
53 if (in_array('board_admin', $permissions)) {
54 return array_keys(self::getFormattedBoardPermissions());
55 }
56
57 return $permissions;
58 }
59
60 private static function getTopUserPermission($userId)
61 {
62 $allAccesses = ['all_board_admin'];
63
64 $userPermission = ['create_boards', 'edit_boards', 'delete_boards', 'can_manage_permissions'];
65
66 return array_intersect($allAccesses, $userPermission);
67 }
68
69 public static function userHasBoardAccess($boardId, $userId = null, $permissions = [])
70 {
71 if (!$userId) {
72 $userId = get_current_user_id();
73 }
74
75 if (!$userId) {
76 return false;
77 }
78
79 $userPermissions = self::getBoardPermissions($boardId, $userId);
80
81 if (!$permissions) {
82 return false;
83 }
84
85 return (bool)array_intersect($permissions, $userPermissions);
86 }
87
88 public static function isBoardManager($boardId, $userId = null, $useCache = false)
89 {
90 if (!$userId) {
91 $userId = get_current_user_id();
92 if (!$userId) {
93 return false;
94 }
95 }
96
97 if (static::isAdmin($userId, $useCache)) {
98 return true;
99 }
100
101 $boardUser = Relation::where('object_id', $boardId)
102 ->where('foreign_id', $userId)
103 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
104 ->first();
105
106 if (!$boardUser) {
107 return false;
108 }
109
110 return (bool)($boardUser->settings[Constant::IS_BOARD_ADMIN] ?? false);
111
112 }
113
114 public static function userHasAnyBoardAccess($userId = null): bool
115 {
116 if (!$userId) {
117 $userId = get_current_user_id();
118 }
119
120 if (!$userId) {
121 return false;
122 }
123
124 if (static::isAdmin($userId)) {
125 return true;
126 }
127
128 return Relation::where('foreign_id', $userId)
129 ->where('object_type', 'board_user')
130 ->exists();
131 }
132
133 /// this is function currently being used , we will go permission way next time
134 public static function userHasPermission($boardId, $userId = null)
135 {
136 if (!$userId) {
137 $userId = get_current_user_id();
138 if (!$userId) {
139 return false;
140 }
141 }
142
143 // if boardId is not provided then we will return false
144 if (!$boardId) {
145 return false;
146 }
147
148 if (static::isAdmin($userId)) {
149 return true; // if task some admin we will allow him.
150 }
151
152
153 /* now, if user is board admin or board member then will allow him */
154 return Relation::where('object_id', $boardId)
155 ->where('foreign_id', $userId)
156 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
157 ->exists();
158 }
159
160 /** Filter existing users by board membership or global admin access using bulk lookups. */
161 public static function getUserIdsWithBoardAccess($boardId, array $userIds): array
162 {
163 $boardId = absint($boardId);
164 $userIds = array_values(array_unique(array_filter(array_map('absint', $userIds))));
165 if (!$boardId || !$userIds) {
166 return [];
167 }
168
169 $memberIds = Relation::where('object_id', $boardId)
170 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
171 ->whereIn('foreign_id', $userIds)
172 ->pluck('foreign_id')->toArray();
173 $adminIds = Meta::where('object_type', Constant::FLUENT_BOARD_ADMIN)
174 ->whereIn('object_id', $userIds)
175 ->pluck('object_id')->toArray();
176 $allowedIds = array_fill_keys(array_merge($memberIds, $adminIds), true);
177
178 // Loading full users primes their metadata together before capability checks.
179 $users = get_users(['include' => $userIds, 'fields' => 'all']);
180 $accessibleIds = [];
181 foreach ($users as $user) {
182 if (isset($allowedIds[$user->ID]) || user_can($user, 'manage_options')) {
183 $accessibleIds[] = (int) $user->ID;
184 }
185 }
186
187 return array_values(array_intersect($userIds, $accessibleIds));
188 }
189
190 public static function isFluentBoardsAdmin($userId = null): bool
191 {
192 if (!$userId) {
193 $userId = get_current_user_id();
194 if (!$userId) {
195 return false;
196 }
197 }
198
199 $isExists = (bool)Meta::where('object_id', $userId)
200 ->where('object_type', Constant::FLUENT_BOARD_ADMIN)
201 ->exists();
202
203 if (!$isExists) {
204 return false;
205 }
206
207 return true;
208 }
209
210 public static function isFluentBoardsUser($userId = null): bool
211 {
212 if (!$userId) {
213 $userId = get_current_user_id();
214 if (!$userId) {
215 return false;
216 }
217 }
218
219 if (static::isAdmin($userId)) { // boardAdmin is super admin and this function returns if loggedUser is task superadmin or not.
220 return true; // if board super admin we will allow him.
221 }
222
223 $isExists = (bool)Relation::where('foreign_id', $userId)
224 ->whereNotNull('object_id')
225 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
226 ->exists();
227 if (!$isExists) {
228 return false;
229 }
230
231 return true;
232 }
233
234 public static function userCanAccessMemberProfile($targetUserId, $userId = null): bool
235 {
236 $targetUserId = intval($targetUserId);
237
238 if (!$userId) {
239 $userId = get_current_user_id();
240 }
241
242 $userId = intval($userId);
243
244 if (!$targetUserId || !$userId) {
245 return false;
246 }
247
248 if ($userId === $targetUserId || static::isAdmin($userId)) {
249 return true;
250 }
251
252 if (!static::isFluentBoardsUser($targetUserId)) {
253 return false;
254 }
255
256 $boardIds = Relation::where('foreign_id', $userId)
257 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
258 ->pluck('object_id')
259 ->toArray();
260
261 if (empty($boardIds)) {
262 return false;
263 }
264
265 return Relation::where('foreign_id', $targetUserId)
266 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
267 ->whereIn('object_id', $boardIds)
268 ->exists();
269 }
270
271 /**
272 * Check WordPress or Boards admin access, caching by the resolved user ID.
273 */
274 public static function isAdmin($userId = null, $useCache = true)
275 {
276
277 static $cache = [];
278
279 if (!$userId) {
280 $userId = get_current_user_id();
281 }
282
283 if (!$userId) {
284 return false;
285 }
286
287 if ($useCache && isset($cache[$userId])) {
288 return $cache[$userId];
289 }
290
291 /*
292 * Two types of admin we have
293 * 1. WordPress admin
294 * 2. FluentBoard admin
295 * if user is WordPress admin then we will allow him
296 * if user is FluentBoard admin then we will allow him
297 */
298
299 if (user_can($userId, 'manage_options')) { // WordPress Administrator
300
301 $cache[$userId] = true;
302
303 return true;
304 }
305
306 if (static::isFluentBoardsAdmin($userId)) { // FluentBoard Plugin Administrator
307 $cache[$userId] = true;
308 return true;
309 }
310
311 $cache[$userId] = false;
312 return false;
313 }
314
315 /**
316 * Get array of board Ids for logged-in user
317 * @param int $userId
318 * @return array
319 */
320 public static function getBoardIdsForUser($userId = null, $boardId = null)
321 {
322 if (!$userId) {
323 $userId = get_current_user_id();
324 if (!$userId) {
325 return [];
326 }
327 }
328
329 if (static::isAdmin($userId)) {
330 if ($boardId) {
331 return Board::where('archived_at', null)->where('id', $boardId)->pluck('id')->toArray();
332 }
333 return Board::where('archived_at', null)->pluck('id')->toArray();
334 }
335
336 return Relation::where('foreign_id', $userId)
337 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
338 ->pluck('object_id')->toArray();
339 }
340
341 public static function getTaskIdsWatchByUser($userId = null)
342 {
343 if (!$userId) {
344 $userId = get_current_user_id();
345 if (!$userId) {
346 return [];
347 }
348 }
349
350 return Relation::where('foreign_id', $userId)
351 ->where('object_type', Constant::OBJECT_TYPE_USER_TASK_WATCH)
352 ->pluck('object_id')->toArray();
353 }
354
355 public static function userCan($permission, $userId = null)
356 {
357 if (!$userId) {
358 $userId = get_current_user_id();
359 if (!$userId) {
360 return false;
361 }
362 }
363
364 if (static::isAdmin($userId)) {
365 return true;
366 }
367 // if user has edit_posts capability then we will allow him
368 if (user_can($userId, 'edit_posts')) {
369 return true;
370 }
371 }
372
373 public static function hasAppAccess($userId = null)
374 {
375 return !!is_user_logged_in();
376 }
377
378 public static function getAll_WP_Admins($searchquery = '', $number = null)
379 {
380 $args = array(
381 'role' => '',
382 'capability' => 'manage_options',
383 'search' => '*' . $searchquery . '*',
384 );
385
386 // Optionally bound the result set (e.g. for selector popovers) so an
387 // empty search can't serialize every admin-capable user on large sites.
388 if ($number !== null) {
389 $args['number'] = (int) $number;
390 }
391
392 return get_users($args);
393 }
394
395 public static function isWPAdmin($userId = null)
396 {
397 if (!$userId) {
398 $userId = get_current_user_id();
399 if (!$userId) {
400 return false;
401 }
402 }
403
404 return user_can($userId, 'manage_options');
405 }
406
407 public static function userHasBoardPermission($boardId, $requestMethod, $userId = null)
408 {
409 // Get the current user if no user ID is provided
410 if (!$userId) {
411 $userId = get_current_user_id();
412 if (!$userId) {
413 return false; // Return false if no user is logged in
414 }
415 }
416
417 // Ensure the board ID is valid
418 if (!$boardId) {
419 return false; // Return false if no board ID is provided
420 }
421
422 // Admins have full permissions, allow access immediately
423 if (static::isAdmin($userId)) {
424 return true;
425 }
426
427 // Fetch user permissions for the given board
428 $boardPermissions = Relation::where('object_id', $boardId)
429 ->where('foreign_id', $userId)
430 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
431 ->first();
432
433 // If no permissions are found, deny access
434 if (!$boardPermissions) {
435 return false;
436 }
437
438 // Allow read-only access for GET requests
439 if ($requestMethod === 'GET') {
440 return true;
441 }
442
443 // Deny access if the user is a viewer only and trying to modify data
444 return !($boardPermissions->settings['is_viewer_only'] ?? false);
445 }
446
447 /**
448 * Allow admins, or members with a non-viewer membership when creation is enabled.
449 * The final filter remains available for site-specific permission overrides.
450 */
451 public static function userHasBoardCreationPermission($userId = null)
452 {
453 if (!$userId) {
454 $userId = get_current_user_id();
455 if (!$userId) {
456 return false;
457 }
458 }
459
460 if (static::isAdmin($userId)) {
461 return apply_filters('fluent_boards/can_create_board', true, $userId);
462 }
463
464 // Check if "allow members to create boards" setting is enabled
465 $generalSettings = fluent_boards_get_option('general_settings', []);
466 if (!empty($generalSettings['allow_members_to_create_boards']) && $generalSettings['allow_members_to_create_boards'] !== 'false') {
467 $memberships = Relation::where('foreign_id', $userId)
468 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
469 ->whereNotNull('object_id')
470 ->get(['settings']);
471
472 // Roles are per board: a viewer elsewhere may still be a member or manager here.
473 foreach ($memberships as $membership) {
474 if (!($membership->settings['is_viewer_only'] ?? false)) {
475 return apply_filters('fluent_boards/can_create_board', true, $userId);
476 }
477 }
478 }
479
480 return apply_filters('fluent_boards/can_create_board', false, $userId);
481 }
482 }
483