2828use App \Facades \LibrenmsConfig ;
2929use App \Models \Bill ;
3030use App \Models \Device ;
31+ use App \Models \DeviceGroup ;
3132use App \Models \Port ;
33+ use App \Models \PortGroup ;
3234use App \Models \User ;
3335use Illuminate \Database \Query \Builder ;
3436use Illuminate \Support \Collection ;
@@ -43,6 +45,9 @@ class PermissionsCache
4345 /** @var array<int, Collection<int>> */
4446 private array $ deviceGroupMap = [];
4547
48+ /** @var array<int, Collection<int>> */
49+ private array $ portGroupPermissions = [];
50+
4651 /** @var Collection<object{user_id: int, port_id: int}>|null */
4752 private ?Collection $ portPermissions = null ;
4853
@@ -59,6 +64,12 @@ public function canAccessDevice(Device|int $device, User|int|null $user = null):
5964 ->contains ('device_id ' , $ this ->getDeviceId ($ device ));
6065 }
6166
67+ public function canAccessDeviceGroup (DeviceGroup |int $ deviceGroup , User |int |null $ user = null ): bool
68+ {
69+ return $ this ->deviceGroupsForUser ($ user )
70+ ->contains (is_int ($ deviceGroup ) ? $ deviceGroup : $ deviceGroup ->id );
71+ }
72+
6273 /**
6374 * Check if a access can be accessed by user (non-global read/admin)
6475 * If no user is given, use the logged in user
@@ -71,6 +82,16 @@ public function canAccessPort(Port|int $port, User|int|null $user = null): bool
7182 ->isNotEmpty ();
7283 }
7384
85+ /**
86+ * Check if a port group can be accessed by user (non-global read/admin)
87+ * If no user is given, use the logged in user
88+ */
89+ public function canAccessPortGroup (PortGroup |int $ portGroup , User |int |null $ user = null ): bool
90+ {
91+ return $ this ->portGroupsForUser ($ user )
92+ ->contains (is_int ($ portGroup ) ? $ portGroup : $ portGroup ->id );
93+ }
94+
7495 /**
7596 * Check if a bill can be accessed by user (non-global read/admin)
7697 * If no user is given, use the logged in user
@@ -162,6 +183,31 @@ public function deviceGroupsForUser(User|int|null $user = null): Collection
162183 return $ this ->deviceGroupMap [$ user_id ];
163184 }
164185
186+ /**
187+ * Get the ids of all port groups the user can access
188+ *
189+ * @return Collection<int>
190+ */
191+ public function portGroupsForUser (User |int |null $ user = null ): Collection
192+ {
193+ $ user_id = $ this ->getUserId ($ user );
194+
195+ if (! isset ($ this ->portGroupPermissions [$ user_id ])) {
196+ $ this ->portGroupPermissions [$ user_id ] = DB ::table ('port_groups ' )
197+ ->leftJoin ('port_group_port ' , 'port_groups.id ' , '= ' , 'port_group_port.port_group_id ' )
198+ ->leftJoin ('ports ' , 'ports.port_id ' , '= ' , 'port_group_port.port_id ' )
199+ ->where (function ($ query ) use ($ user ): void {
200+ $ query ->whereNull ('port_group_port.port_group_id ' )
201+ ->orWhereIntegerInRaw ('port_group_port.port_id ' , $ this ->portsForUser ($ user ))
202+ ->orWhereIntegerInRaw ('ports.device_id ' , $ this ->devicesForUser ($ user ));
203+ })
204+ ->distinct ('port_groups.id ' )
205+ ->pluck ('port_groups.id ' );
206+ }
207+
208+ return $ this ->portGroupPermissions [$ user_id ];
209+ }
210+
165211 /**
166212 * Get the cached data for device permissions. Use helpers instead.
167213 *
@@ -217,6 +263,7 @@ public function invalidateCache(): void
217263 {
218264 $ this ->devicePermissions = [];
219265 $ this ->deviceGroupMap = [];
266+ $ this ->portGroupPermissions = [];
220267 $ this ->portPermissions = null ;
221268 $ this ->billPermissions = null ;
222269 }
0 commit comments