Skip to content

Commit

Permalink
Create common function for userIsFormOwner & rewrite protected form (#…
Browse files Browse the repository at this point in the history
…244)

* Create common function for userIsFormOwner & rewrite protected form

* fix testcase
  • Loading branch information
formsdev authored Nov 28, 2023
1 parent 64e79f3 commit d65c1be
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 34 deletions.
2 changes: 1 addition & 1 deletion app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class PasswordProtectedForm
class ProtectedForm
{
const PASSWORD_HEADER_NAME = 'form-password';

Expand All @@ -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);
Expand Down
18 changes: 5 additions & 13 deletions app/Http/Resources/FormResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() ? [
Expand Down Expand Up @@ -96,14 +96,7 @@ public function setCleanings(array $cleanings)
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,
Expand Down Expand Up @@ -131,8 +124,7 @@ private function workspaceIsPro() {
private function userIsFormOwner() {
return $this->extra?->userIsOwner ??
(
Auth::check()
&& Auth::user()->workspaces()->find($this->workspace_id) !== null
Auth::check() && Auth::user()->ownsForm($this->resource)
);
}

Expand Down
5 changes: 5 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
2 changes: 1 addition & 1 deletion routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
* 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.)
Expand Down
4 changes: 2 additions & 2 deletions tests/Feature/Forms/FormPasswordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
->assertStatus(403)
->assertJson([
'status' => 'Unauthorized',
'message' => 'Form is password protected.'
'message' => 'Form is protected.'
]);
});

Expand All @@ -66,7 +66,7 @@
->assertStatus(403)
->assertJson([
'status' => 'Unauthorized',
'message' => 'Form is password protected.'
'message' => 'Form is protected.'
]);
});

Expand Down

0 comments on commit d65c1be

Please sign in to comment.