- Create a new Blade view for domain registration (`registrant-tochuc.blade.php`) to capture organization and manager details. - Implement email templates for new domain orders for both admin (`domain-order-new.blade.php`) and customers (`domain-order-received.blade.php`). - Add CSV exports for client and domain data. - Introduce tests for customer mass assignment, password reset, login throttling, and permission gating. - Ensure service renewals use current pricing and validate ownership for virtual machines. - Validate mass assignment behavior in service model.
302 lines
10 KiB
PHP
302 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Admin\Role;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
class RolePermissionController extends Controller
|
|
{
|
|
private function ensureFullAdmin(): bool
|
|
{
|
|
$user = auth('admin')->user();
|
|
return $user && $user->hasRole('Full Administrator');
|
|
}
|
|
|
|
/**
|
|
* GET /v1/administrator/role-permissions
|
|
* Danh sách tất cả roles (trừ Full Administrator) kèm permissions hiện tại
|
|
*/
|
|
public function index(): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$roles = Role::where('guard_name', 'admin')
|
|
->where('name', '!=', 'Full Administrator')
|
|
->with('permissions')
|
|
->get()
|
|
->map(fn ($role) => [
|
|
'id' => $role->id,
|
|
'name' => $role->name,
|
|
'permissions' => $role->permissions->pluck('name')->values(),
|
|
]);
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => $roles,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* GET /v1/administrator/role-permissions/all-permissions
|
|
* Tất cả permissions nhóm theo module
|
|
*/
|
|
public function allPermissions(): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$grouped = Permission::where('guard_name', 'admin')
|
|
->orderBy('id')
|
|
->get(['id', 'name'])
|
|
->groupBy(function ($p) {
|
|
// Format: module.action (e.g., product-service.view, customer.manager)
|
|
$parts = explode('.', $p->name);
|
|
return $parts[0] ?? $p->name;
|
|
})
|
|
->map(function ($group, $module) {
|
|
return [
|
|
'module' => $module,
|
|
'permissions' => $group->map(fn ($p) => [
|
|
'id' => $p->id,
|
|
'name' => $p->name,
|
|
'action' => explode('.', $p->name)[1] ?? $p->name,
|
|
])->values(),
|
|
];
|
|
})
|
|
->values();
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => $grouped,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* GET /v1/administrator/role-permissions/mine
|
|
* Trả về permissions hiệu lực của user đang đăng nhập (qua role của họ).
|
|
* Accessible bởi mọi admin đã xác thực — không yêu cầu Full Administrator.
|
|
*/
|
|
public function mine(): JsonResponse
|
|
{
|
|
$user = auth('admin')->user();
|
|
if (!$user) {
|
|
return response()->json(['error' => true, 'message' => 'Unauthorized'], 401);
|
|
}
|
|
|
|
$isFullAdmin = $user->hasRole('Full Administrator', 'admin');
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => [
|
|
'isFullAdmin' => $isFullAdmin,
|
|
'permissions' => $isFullAdmin
|
|
? ['*']
|
|
: $user->getAllPermissions()->pluck('name')->toArray(),
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* POST /v1/administrator/role-permissions
|
|
* Tạo một vai trò mới (chỉ Full Administrator)
|
|
*/
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$name = trim($request->input('name', ''));
|
|
if (!$name) {
|
|
return response()->json(['error' => true, 'message' => 'Tên vai trò không được trống'], 422);
|
|
}
|
|
|
|
if ($name === 'Full Administrator') {
|
|
return response()->json(['error' => true, 'message' => 'Tên vai trò không hợp lệ'], 422);
|
|
}
|
|
|
|
if (Role::where('guard_name', 'admin')->where('name', $name)->exists()) {
|
|
return response()->json(['error' => true, 'message' => "Vai trò \"{$name}\" đã tồn tại"], 422);
|
|
}
|
|
|
|
$role = Role::create(['name' => $name, 'guard_name' => 'admin']);
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => [
|
|
'id' => $role->id,
|
|
'name' => $role->name,
|
|
'permissions' => [],
|
|
],
|
|
], 201);
|
|
}
|
|
|
|
/**
|
|
* POST /v1/administrator/role-permissions/permissions
|
|
* Tạo một nhóm permissions mới theo module (chỉ Full Administrator)
|
|
*/
|
|
public function createPermissionGroup(Request $request): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$module = trim($request->input('module', ''));
|
|
$actions = $request->input('actions', ['view', 'create', 'edit', 'destroy', 'manager']);
|
|
|
|
if (!$module) {
|
|
return response()->json(['error' => true, 'message' => 'Tên module không được trống'], 422);
|
|
}
|
|
|
|
// Kiểm tra module đã tồn tại chưa
|
|
$existing = Permission::where('guard_name', 'admin')
|
|
->where('name', 'like', $module . '.%')
|
|
->exists();
|
|
|
|
if ($existing) {
|
|
return response()->json(['error' => true, 'message' => "Module \"{$module}\" đã tồn tại"], 422);
|
|
}
|
|
|
|
$created = [];
|
|
foreach ($actions as $action) {
|
|
$name = $module . '.' . $action;
|
|
$perm = Permission::firstOrCreate([
|
|
'name' => $name,
|
|
'guard_name' => 'admin',
|
|
]);
|
|
$created[] = [
|
|
'id' => $perm->id,
|
|
'name' => $perm->name,
|
|
'action' => $action,
|
|
];
|
|
}
|
|
|
|
// Full Administrator tự động được cấp permissions mới
|
|
$fullAdmin = Role::where('name', 'Full Administrator')
|
|
->where('guard_name', 'admin')
|
|
->first();
|
|
if ($fullAdmin) {
|
|
$fullAdmin->givePermissionTo(array_column($created, 'name'));
|
|
}
|
|
|
|
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => [
|
|
'module' => $module,
|
|
'permissions' => $created,
|
|
],
|
|
], 201);
|
|
}
|
|
|
|
/**
|
|
* DELETE /v1/administrator/role-permissions/permissions/group/{module}
|
|
* Xóa toàn bộ permissions của một module (chỉ Full Administrator)
|
|
*/
|
|
public function deletePermissionGroup(string $module): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$deleted = Permission::where('guard_name', 'admin')
|
|
->where('name', 'like', $module . '.%')
|
|
->get();
|
|
|
|
if ($deleted->isEmpty()) {
|
|
return response()->json(['error' => true, 'message' => 'Không tìm thấy nhóm quyền'], 404);
|
|
}
|
|
|
|
foreach ($deleted as $perm) {
|
|
$perm->delete();
|
|
}
|
|
|
|
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => "Đã xóa nhóm quyền \"{$module}\"",
|
|
'data' => ['module' => $module, 'deleted' => $deleted->count()],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* PATCH /v1/administrator/role-permissions/permissions/{id}
|
|
* Đổi tên một permission (chỉ Full Administrator)
|
|
*/
|
|
public function renamePermission(int $id, Request $request): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$permission = Permission::where('guard_name', 'admin')->find($id);
|
|
if (!$permission) {
|
|
return response()->json(['error' => true, 'message' => 'Không tìm thấy permission'], 404);
|
|
}
|
|
|
|
$newName = trim($request->input('name', ''));
|
|
if (!$newName) {
|
|
return response()->json(['error' => true, 'message' => 'Tên permission không được trống'], 422);
|
|
}
|
|
|
|
if (Permission::where('guard_name', 'admin')->where('name', $newName)->where('id', '!=', $id)->exists()) {
|
|
return response()->json(['error' => true, 'message' => 'Tên permission đã tồn tại'], 422);
|
|
}
|
|
|
|
$permission->update(['name' => $newName]);
|
|
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => ['id' => $permission->id, 'name' => $permission->name],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* PUT /v1/administrator/role-permissions/{roleId}
|
|
* Sync permissions cho một role
|
|
*/
|
|
public function update(int $roleId, Request $request): JsonResponse
|
|
{
|
|
if (!$this->ensureFullAdmin()) {
|
|
return response()->json(['error' => true, 'message' => 'Bạn không có quyền truy cập'], 403);
|
|
}
|
|
|
|
$role = Role::where('guard_name', 'admin')
|
|
->where('name', '!=', 'Full Administrator')
|
|
->find($roleId);
|
|
|
|
if (!$role) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy vai trò',
|
|
], 404);
|
|
}
|
|
|
|
$permissions = $request->input('permissions', []);
|
|
$role->syncPermissions($permissions);
|
|
|
|
// Xóa cache để /mine endpoint trả về permissions mới nhất
|
|
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => "Đã cập nhật quyền cho vai trò \"{$role->name}\"",
|
|
'data' => [
|
|
'id' => $role->id,
|
|
'name' => $role->name,
|
|
'permissions' => $role->permissions()->pluck('name')->values(),
|
|
],
|
|
]);
|
|
}
|
|
}
|