From 692f4d5492b844aee88f7632fe1bdac6a2e19222 Mon Sep 17 00:00:00 2001 From: Yutaka Kurosaki <> Date: Sat, 9 May 2026 10:22:18 +0900 Subject: [PATCH] Restrict document edit/delete to owners and close public registration Adds DocumentPolicy gating update/delete to the creator (admins bypass via before()), invokes $this->authorize() in DocumentEditor mount/save/delete, applies can:update,document on the edit route, hides the edit button for non-owners, and removes the open /register routes so accounts must be provisioned via the admin panel. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/app/Livewire/DocumentEditor.php | 6 ++++ src/app/Policies/DocumentPolicy.php | 34 +++++++++++++++++++ .../views/livewire/document-viewer.blade.php | 4 +-- src/routes/auth.php | 6 ---- src/routes/web.php | 4 ++- 5 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/app/Policies/DocumentPolicy.php diff --git a/src/app/Livewire/DocumentEditor.php b/src/app/Livewire/DocumentEditor.php index cf3623e..cc8ccfc 100644 --- a/src/app/Livewire/DocumentEditor.php +++ b/src/app/Livewire/DocumentEditor.php @@ -18,6 +18,8 @@ class DocumentEditor extends Component public function mount(?Document $document = null) { if ($document) { + $this->authorize('update', $document); + $this->document = $document; $this->title = $document->title; $this->content = $document->content; @@ -40,6 +42,8 @@ public function save(DocumentService $documentService) try { if ($this->isEditMode && $this->document) { + $this->authorize('update', $this->document); + $this->document = $documentService->updateDocument( $this->document, $this->title, @@ -71,6 +75,8 @@ public function delete(DocumentService $documentService) return; } + $this->authorize('delete', $this->document); + try { $documentService->deleteDocument($this->document); session()->flash('message', 'Document deleted successfully!'); diff --git a/src/app/Policies/DocumentPolicy.php b/src/app/Policies/DocumentPolicy.php new file mode 100644 index 0000000..0d2728b --- /dev/null +++ b/src/app/Policies/DocumentPolicy.php @@ -0,0 +1,34 @@ +isAdmin() ? true : null; + } + + public function view(User $user, Document $document): bool + { + return true; + } + + public function create(User $user): bool + { + return true; + } + + public function update(User $user, Document $document): bool + { + return $document->created_by === $user->id; + } + + public function delete(User $user, Document $document): bool + { + return $document->created_by === $user->id; + } +} diff --git a/src/resources/views/livewire/document-viewer.blade.php b/src/resources/views/livewire/document-viewer.blade.php index 9e9b0df..b3eafd1 100644 --- a/src/resources/views/livewire/document-viewer.blade.php +++ b/src/resources/views/livewire/document-viewer.blade.php @@ -6,7 +6,7 @@ {{ $document->title }} - @auth + @can('update', $document) diff --git a/src/routes/auth.php b/src/routes/auth.php index 3926ecf..efc3763 100644 --- a/src/routes/auth.php +++ b/src/routes/auth.php @@ -7,16 +7,10 @@ use App\Http\Controllers\Auth\NewPasswordController; use App\Http\Controllers\Auth\PasswordController; use App\Http\Controllers\Auth\PasswordResetLinkController; -use App\Http\Controllers\Auth\RegisteredUserController; use App\Http\Controllers\Auth\VerifyEmailController; use Illuminate\Support\Facades\Route; Route::middleware('guest')->group(function () { - Route::get('register', [RegisteredUserController::class, 'create']) - ->name('register'); - - Route::post('register', [RegisteredUserController::class, 'store']); - Route::get('login', [AuthenticatedSessionController::class, 'create']) ->name('login'); diff --git a/src/routes/web.php b/src/routes/web.php index afdbd37..ce6f662 100644 --- a/src/routes/web.php +++ b/src/routes/web.php @@ -44,7 +44,9 @@ // 認証が必要なルート(より具体的なルートを先に定義) Route::middleware('auth')->group(function () { Route::get('/create', DocumentEditor::class)->name('create'); - Route::get('/{document}/edit', DocumentEditor::class)->name('edit'); + Route::get('/{document}/edit', DocumentEditor::class) + ->middleware('can:update,document') + ->name('edit'); }); // 公開ルート(動的ルートは最後に)