256 lines
9.6 KiB
PHP
256 lines
9.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\RoleRequest;
|
|
use App\Models\Permission;
|
|
use App\Models\Role;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Str;
|
|
use Inertia\Inertia;
|
|
|
|
class RoleController extends BaseController
|
|
{
|
|
public function index()
|
|
{
|
|
$user = Auth::user();
|
|
if ($user->type === 'company' || $user->can('manage-roles') || $user->can('view-roles') || $user->can('create-roles')) {
|
|
$query = Role::with(['permissions', 'creator']);
|
|
if ($user->type !== 'company' && !$user->can('manage-any-roles') && !$user->can('manage-roles')) {
|
|
if ($user->can('manage-own-roles')) {
|
|
$query->where('created_by', $user->id);
|
|
}
|
|
}
|
|
$roles = $query->latest()->paginate(10);
|
|
|
|
// Add label and is_editable attribute to each role
|
|
$roles->getCollection()->transform(function ($role) {
|
|
if (empty($role->label)) {
|
|
$role->label = ucwords(str_replace(['-', '_'], ' ', $role->name));
|
|
}
|
|
$role->is_editable = !in_array($role->name, isNotEditableRoles());
|
|
|
|
return $role;
|
|
});
|
|
|
|
$permissions = $this->getFilteredPermissions();
|
|
|
|
return Inertia::render('roles/index', [
|
|
'roles' => $roles,
|
|
'permissions' => $permissions,
|
|
]);
|
|
} else {
|
|
return redirect()->back()->with('error', __('Permission Denied.'));
|
|
}
|
|
|
|
}
|
|
|
|
private function getFilteredPermissions($targetRole = null)
|
|
{
|
|
$user = Auth::user();
|
|
$userType = $user->type ?? 'company';
|
|
|
|
// Superadmin can see all permissions
|
|
if ($userType === 'superadmin' || $userType === 'super admin') {
|
|
$all = Permission::all();
|
|
foreach ($all as $p) {
|
|
if (empty($p->module)) {
|
|
$p->module = $this->inferModuleFromPermissionName($p->name);
|
|
$p->save();
|
|
}
|
|
$p->label = ucwords(str_replace(['-', '_'], ' ', $p->name));
|
|
}
|
|
return $all->groupBy('module');
|
|
}
|
|
|
|
// Get allowed permissions for current tenant
|
|
$allowedPermissions = [];
|
|
if (function_exists('tenant') && tenant()) {
|
|
try {
|
|
$enabledModules = \App\Models\TenantModule::where('enabled', 1)->pluck('module_key')->toArray();
|
|
$inquiryKeys = [];
|
|
foreach (\App\Constants\ModuleContract::MODULE_MAP as $inqKey => $cfg) {
|
|
if (in_array($cfg['module_key'], $enabledModules)) {
|
|
$inquiryKeys[] = $inqKey;
|
|
}
|
|
}
|
|
$allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys($inquiryKeys);
|
|
} catch (\Exception $e) {
|
|
$allowedPermissions = [];
|
|
}
|
|
} else {
|
|
$allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys(\App\Constants\ModuleContract::getAllInquiryKeys());
|
|
}
|
|
|
|
foreach ($allowedPermissions as $perm) {
|
|
Permission::findOrCreate($perm, 'web');
|
|
}
|
|
|
|
$permissions = Permission::whereIn('name', $allowedPermissions)->get();
|
|
|
|
foreach ($permissions as $p) {
|
|
if (empty($p->module)) {
|
|
$p->module = $this->inferModuleFromPermissionName($p->name);
|
|
$p->save();
|
|
}
|
|
$p->label = ucwords(str_replace(['-', '_'], ' ', $p->name));
|
|
}
|
|
|
|
return $permissions->groupBy('module');
|
|
}
|
|
|
|
private function inferModuleFromPermissionName(string $name): string
|
|
{
|
|
foreach (\App\Constants\ModuleContract::MODULE_MAP as $inqKey => $config) {
|
|
if (in_array($name, $config['permissions'], true)) {
|
|
return $config['label'] ?? ucfirst($config['module_key']);
|
|
}
|
|
}
|
|
|
|
$parts = explode('-', $name);
|
|
if (count($parts) > 1) {
|
|
array_shift($parts);
|
|
return ucfirst(implode(' ', $parts));
|
|
}
|
|
|
|
return 'General';
|
|
}
|
|
|
|
private function validatePermissions(array $permissions, $role = null)
|
|
{
|
|
$user = Auth::user();
|
|
if (!$user) {
|
|
throw new \Exception('User not authenticated');
|
|
}
|
|
|
|
$userType = $user->type ?? 'company';
|
|
|
|
// Superadmin can assign any permission
|
|
if (in_array($userType, ['superadmin', 'super admin'])) {
|
|
return array_filter($permissions);
|
|
}
|
|
|
|
// Get allowed permissions for current tenant
|
|
$allowedPermissions = [];
|
|
if (function_exists('tenant') && tenant()) {
|
|
try {
|
|
$enabledModules = \App\Models\TenantModule::where('enabled', 1)->pluck('module_key')->toArray();
|
|
$inquiryKeys = [];
|
|
foreach (\App\Constants\ModuleContract::MODULE_MAP as $inqKey => $cfg) {
|
|
if (in_array($cfg['module_key'], $enabledModules)) {
|
|
$inquiryKeys[] = $inqKey;
|
|
}
|
|
}
|
|
$allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys($inquiryKeys);
|
|
} catch (\Exception $e) {
|
|
$allowedPermissions = [];
|
|
}
|
|
} else {
|
|
$allowedPermissions = \App\Constants\ModuleContract::getPermissionsForInquiryKeys(\App\Constants\ModuleContract::getAllInquiryKeys());
|
|
}
|
|
|
|
return array_values(array_intersect(array_filter($permissions), $allowedPermissions));
|
|
}
|
|
|
|
|
|
public function store(RoleRequest $request)
|
|
{
|
|
if (Auth::user()->can('create-roles')) {
|
|
// Validate permissions against user's allowed modules
|
|
$validatedPermissions = $this->validatePermissions($request->permissions ?? []);
|
|
|
|
$checkRoleExist = Role::where('name', Str::slug($request->label))->whereIn('created_by', getCompanyAndUsersId())->exists();
|
|
if (!$checkRoleExist) {
|
|
// Use direct model creation to bypass Spatie's duplicate check
|
|
$role = new Role;
|
|
$role->label = $request->label;
|
|
$role->name = Str::slug($request->label);
|
|
$role->description = $request->description;
|
|
$role->created_by = Auth::id();
|
|
$role->guard_name = 'web';
|
|
$role->save();
|
|
|
|
if ($role) {
|
|
$role->syncPermissions($validatedPermissions);
|
|
app(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();
|
|
|
|
return redirect()->route('roles.index')->with('success', __('Role created successfully with Permissions!'));
|
|
}
|
|
|
|
return redirect()->back()->with('error', __('Unable to create Role with permissions. Please try again!'));
|
|
} else {
|
|
return redirect()->back()->with('error', __('Role already exists!'));
|
|
}
|
|
} else {
|
|
return redirect()->back()->with('error', __('Permission Denied.'));
|
|
}
|
|
}
|
|
|
|
public function update(RoleRequest $request, Role $role)
|
|
{
|
|
if (Auth::user()->can('edit-roles')) {
|
|
if ($role) {
|
|
// Validate permissions (will keep existing ones from commented modules)
|
|
$validatedPermissions = $this->validatePermissions($request->permissions ?? [], $role);
|
|
|
|
$newSlug = Str::slug($request->label);
|
|
|
|
// Check if role name already exists (excluding current role)
|
|
$checkRoleExist = Role::where('name', $newSlug)
|
|
->where('id', '!=', $role->id)
|
|
->whereIn('created_by', getCompanyAndUsersId())
|
|
->exists();
|
|
|
|
if ($checkRoleExist) {
|
|
return redirect()->back()->with('error', __('Role already exists!'));
|
|
}
|
|
|
|
// Only update name if it's different to avoid duplicate key error
|
|
if ($role->name !== $newSlug) {
|
|
$role->name = $newSlug;
|
|
}
|
|
|
|
$role->label = $request->label;
|
|
$role->description = $request->description;
|
|
|
|
$role->save();
|
|
|
|
// Update the permissions
|
|
$role->syncPermissions($validatedPermissions);
|
|
app(\Spatie\Permission\PermissionRegistrar::class)->forgetCachedPermissions();
|
|
|
|
return redirect()->route('roles.index')->with('success', __('Role updated successfully with Permissions!'));
|
|
}
|
|
|
|
return redirect()->back()->with('error', __('Unable to update Role with permissions. Please try again!'));
|
|
} else {
|
|
return redirect()->back()->with('error', __('Permission Denied.'));
|
|
}
|
|
}
|
|
|
|
|
|
public function destroy(Role $role)
|
|
{
|
|
if (Auth::user()->can('delete-roles')) {
|
|
if ($role) {
|
|
// Prevent deletion of system roles
|
|
// if ($role->is_system_role) {
|
|
// return redirect()->back()->with('error', __('System roles cannot be deleted!'));
|
|
// }
|
|
|
|
if (in_array($role->name, isNotDeletableRoles())) {
|
|
return redirect()->back()->with('error', __('System roles cannot be deleted!'));
|
|
}
|
|
|
|
$role->delete();
|
|
|
|
return redirect()->route('roles.index')->with('success', __('Role deleted successfully!'));
|
|
}
|
|
|
|
return redirect()->back()->with('error', __('Unable to delete Role. Please try again!'));
|
|
} else {
|
|
return redirect()->back()->with('error', __('Permission Denied.'));
|
|
}
|
|
}
|
|
}
|