- Added `RestrictedUserPermission` migration and model for managing user-role-permission restrictions. - Introduced `UserService`, `RoleService`, and related DTOs for handling user access, role assignments, and permission restrictions. - Created new Livewire components and Blade views for user management, including role/permission assignment modals. - Updated navigation and routing to include the "Users" section under "Access Manager." - Enhanced `RoleService` with methods for retrieving permissions and managing role-user interactions. - Improved UI with permission toggles and streamlined selection features for better user-role management.
118 lines
3.1 KiB
PHP
118 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Data\Permissions\DeactivatedPermissionData;
|
|
use App\Data\User\UserIndexData;
|
|
use App\Models\{RestrictedUserPermission, User};
|
|
use Illuminate\Support\Facades\DB;
|
|
use InvalidArgumentException;
|
|
use NoDiscard;
|
|
use Spatie\LaravelData\{DataCollection, PaginatedDataCollection};
|
|
use Throwable;
|
|
|
|
final class UserService
|
|
{
|
|
/**
|
|
* Returns a Paginated Collection of users with their roles and connected apps DTO
|
|
*
|
|
* @return PaginatedDataCollection<int, UserIndexData>
|
|
*/
|
|
#[NoDiscard]
|
|
public function getAll(): PaginatedDataCollection
|
|
{
|
|
$users = User::query()
|
|
->with([
|
|
'roles:id,name',
|
|
'roles.apps:id,name',
|
|
'roles.permissions:id,name',
|
|
'restrictedPermissions',
|
|
])
|
|
->orderBy('id')
|
|
->paginate();
|
|
|
|
return UserIndexData::collect($users, PaginatedDataCollection::class);
|
|
}
|
|
|
|
/**
|
|
* Get the restricted permission IDs for a user.
|
|
*
|
|
* @return array<int>
|
|
*/
|
|
public function getRestrictedPermissionIds(int $userId): array
|
|
{
|
|
if ($userId <= 0) {
|
|
return [];
|
|
}
|
|
|
|
return RestrictedUserPermission::query()
|
|
->where('user_id', $userId)
|
|
->pluck('permission_id')
|
|
->toArray();
|
|
}
|
|
|
|
/**
|
|
* Assign roles to a user.
|
|
*/
|
|
public function assignRoles(int $userId, array $roleIds): void
|
|
{
|
|
if ($userId <= 0) {
|
|
throw new InvalidArgumentException('Invalid id');
|
|
}
|
|
|
|
DB::transaction(function () use ($userId, $roleIds): void {
|
|
$user = User::query()->findOrFail($userId);
|
|
$user->syncRoles($roleIds);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sync restricted permissions for a user.
|
|
*
|
|
* @param DataCollection<int, DeactivatedPermissionData> $deactivatedPermissions
|
|
*
|
|
* @throws Throwable
|
|
*/
|
|
public function syncRestrictedPermissions(int $userId, DataCollection $deactivatedPermissions): void
|
|
{
|
|
if ($userId <= 0) {
|
|
throw new InvalidArgumentException('Invalid user ID');
|
|
}
|
|
|
|
$payload = $deactivatedPermissions->toCollection()->map(fn ($data) => [
|
|
'user_id' => $userId,
|
|
'role_id' => $data->roleId,
|
|
'permission_id' => $data->permissionId,
|
|
])->toArray();
|
|
|
|
DB::transaction(function () use ($userId, $payload): void {
|
|
|
|
RestrictedUserPermission::query()
|
|
->where('user_id', $userId)
|
|
->delete();
|
|
|
|
if (! empty($payload)) {
|
|
RestrictedUserPermission::query()->insert($payload);
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @throws InvalidArgumentException when id is invalid.
|
|
* @throws Throwable when an error occurs during the deletion.
|
|
*/
|
|
public function delete(int $id): void
|
|
{
|
|
if ($id <= 0) {
|
|
throw new InvalidArgumentException('Invalid id');
|
|
}
|
|
|
|
DB::transaction(function () use ($id): void {
|
|
User::query()->findOrFail($id)->delete();
|
|
});
|
|
}
|
|
}
|