From d65c1be9b520eb8dfef9f4420aecf6450ba90904 Mon Sep 17 00:00:00 2001 From: formsdev <136701234+formsdev@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:53:04 +0530 Subject: [PATCH] Create common function for userIsFormOwner & rewrite protected form (#244) * Create common function for userIsFormOwner & rewrite protected form * fix testcase --- app/Http/Kernel.php | 2 +- ...ordProtectedForm.php => ProtectedForm.php} | 42 +++++++++++-------- app/Http/Resources/FormResource.php | 18 +++----- app/Models/User.php | 5 +++ routes/api.php | 2 +- tests/Feature/Forms/FormPasswordTest.php | 4 +- 6 files changed, 39 insertions(+), 34 deletions(-) rename app/Http/Middleware/Form/{PasswordProtectedForm.php => ProtectedForm.php} (53%) diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a786d57..970e320 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -80,6 +80,6 @@ class Kernel extends HttpKernel 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'pro-form' => \App\Http\Middleware\Form\ProForm::class, - 'password-protected-form' => \App\Http\Middleware\Form\PasswordProtectedForm::class, + 'protected-form' => \App\Http\Middleware\Form\ProtectedForm::class, ]; } diff --git a/app/Http/Middleware/Form/PasswordProtectedForm.php b/app/Http/Middleware/Form/ProtectedForm.php similarity index 53% rename from app/Http/Middleware/Form/PasswordProtectedForm.php rename to app/Http/Middleware/Form/ProtectedForm.php index b4e2e15..6bbc947 100644 --- a/app/Http/Middleware/Form/PasswordProtectedForm.php +++ b/app/Http/Middleware/Form/ProtectedForm.php @@ -7,7 +7,7 @@ use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; -class PasswordProtectedForm +class ProtectedForm { const PASSWORD_HEADER_NAME = 'form-password'; @@ -20,26 +20,34 @@ class PasswordProtectedForm */ public function handle(Request $request, Closure $next) { - if ($request->route('slug')) { - $form = Form::where('slug',$request->route('slug'))->firstOrFail(); - $request->merge([ - 'form' => $form, - ]); - $userIsFormOwner = Auth::check() && Auth::user()->workspaces()->find($form->workspace_id) !== null; - if (!$userIsFormOwner && $form->has_password) { - if($this->hasCorrectPassword($request, $form)){ - return $next($request); - } - - return response([ - 'status' => 'Unauthorized', - 'message' => 'Form is password protected.', - ], 403); - } + if (!$request->route('slug')) { + return $next($request); } + + $form = Form::where('slug',$request->route('slug'))->firstOrFail(); + $request->merge([ + 'form' => $form, + ]); + $userIsFormOwner = Auth::check() && Auth::user()->ownsForm($form); + if (!$userIsFormOwner && $this->isProtected($request, $form)) { + return response([ + 'status' => 'Unauthorized', + 'message' => 'Form is protected.', + ], 403); + } + return $next($request); } + public static function isProtected(Request $request, Form $form) + { + if (!$form->has_password) { + return false; + } + + return !self::hasCorrectPassword($request, $form); + } + public static function hasCorrectPassword(Request $request, Form $form) { return $request->headers->has(self::PASSWORD_HEADER_NAME) && $request->headers->get(self::PASSWORD_HEADER_NAME) == hash('sha256', $form->password); diff --git a/app/Http/Resources/FormResource.php b/app/Http/Resources/FormResource.php index 0cc8949..7f6a86f 100644 --- a/app/Http/Resources/FormResource.php +++ b/app/Http/Resources/FormResource.php @@ -2,7 +2,7 @@ namespace App\Http\Resources; -use App\Http\Middleware\Form\PasswordProtectedForm; +use App\Http\Middleware\Form\ProtectedForm; use App\Http\Resources\UserResource; use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Support\Facades\Auth; @@ -20,8 +20,8 @@ class FormResource extends JsonResource */ public function toArray($request) { - if(!$this->userIsFormOwner() && $this->doesMissPassword($request)){ - return $this->getPasswordProtectedForm(); + if(!$this->userIsFormOwner() && ProtectedForm::isProtected($request, $this->resource)){ + return $this->getProtectedForm(); } $ownerData = $this->userIsFormOwner() ? [ @@ -96,14 +96,7 @@ class FormResource extends JsonResource return $this; } - private function doesMissPassword(Request $request) - { - if (!$this->has_password) return false; - - return !PasswordProtectedForm::hasCorrectPassword($request, $this->resource); - } - - private function getPasswordProtectedForm() + private function getProtectedForm() { return [ 'id' => $this->id, @@ -131,8 +124,7 @@ class FormResource extends JsonResource private function userIsFormOwner() { return $this->extra?->userIsOwner ?? ( - Auth::check() - && Auth::user()->workspaces()->find($this->workspace_id) !== null + Auth::check() && Auth::user()->ownsForm($this->resource) ); } diff --git a/app/Models/User.php b/app/Models/User.php index f9cabff..764d927 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -61,6 +61,11 @@ class User extends Authenticatable implements JWTSubject protected $withCount = ['workspaces']; + public function ownsForm(Form $form) + { + return $this->workspaces()->find($form->workspace_id) !== null; + } + /** * Get the profile photo URL attribute. * diff --git a/routes/api.php b/routes/api.php index cfb0aba..1719bea 100644 --- a/routes/api.php +++ b/routes/api.php @@ -139,7 +139,7 @@ Route::group(['prefix' => 'appsumo'], function () { * Public Forms related routes */ Route::prefix('forms')->name('forms.')->group(function () { - Route::middleware('password-protected-form')->group(function () { + Route::middleware('protected-form')->group(function () { Route::post('{slug}/answer', [PublicFormController::class, 'answer'])->name('answer'); // Form content endpoints (user lists, relation lists etc.) diff --git a/tests/Feature/Forms/FormPasswordTest.php b/tests/Feature/Forms/FormPasswordTest.php index 15274a2..03d2650 100644 --- a/tests/Feature/Forms/FormPasswordTest.php +++ b/tests/Feature/Forms/FormPasswordTest.php @@ -54,7 +54,7 @@ it('can not submit form without password for guest user', function () { ->assertStatus(403) ->assertJson([ 'status' => 'Unauthorized', - 'message' => 'Form is password protected.' + 'message' => 'Form is protected.' ]); }); @@ -66,7 +66,7 @@ it('can not submit form with wrong password for guest user', function () { ->assertStatus(403) ->assertJson([ 'status' => 'Unauthorized', - 'message' => 'Form is password protected.' + 'message' => 'Form is protected.' ]); });