Create common function for userIsFormOwner & rewrite protected form (#244)
* Create common function for userIsFormOwner & rewrite protected form * fix testcase
This commit is contained in:
parent
64e79f34f2
commit
d65c1be9b5
|
@ -80,6 +80,6 @@ class Kernel extends HttpKernel
|
||||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||||
|
|
||||||
'pro-form' => \App\Http\Middleware\Form\ProForm::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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class PasswordProtectedForm
|
class ProtectedForm
|
||||||
{
|
{
|
||||||
const PASSWORD_HEADER_NAME = 'form-password';
|
const PASSWORD_HEADER_NAME = 'form-password';
|
||||||
|
|
||||||
|
@ -20,26 +20,34 @@ class PasswordProtectedForm
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, Closure $next)
|
public function handle(Request $request, Closure $next)
|
||||||
{
|
{
|
||||||
if ($request->route('slug')) {
|
if (!$request->route('slug')) {
|
||||||
$form = Form::where('slug',$request->route('slug'))->firstOrFail();
|
return $next($request);
|
||||||
$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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$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);
|
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)
|
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);
|
return $request->headers->has(self::PASSWORD_HEADER_NAME) && $request->headers->get(self::PASSWORD_HEADER_NAME) == hash('sha256', $form->password);
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use App\Http\Middleware\Form\PasswordProtectedForm;
|
use App\Http\Middleware\Form\ProtectedForm;
|
||||||
use App\Http\Resources\UserResource;
|
use App\Http\Resources\UserResource;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
@ -20,8 +20,8 @@ class FormResource extends JsonResource
|
||||||
*/
|
*/
|
||||||
public function toArray($request)
|
public function toArray($request)
|
||||||
{
|
{
|
||||||
if(!$this->userIsFormOwner() && $this->doesMissPassword($request)){
|
if(!$this->userIsFormOwner() && ProtectedForm::isProtected($request, $this->resource)){
|
||||||
return $this->getPasswordProtectedForm();
|
return $this->getProtectedForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
$ownerData = $this->userIsFormOwner() ? [
|
$ownerData = $this->userIsFormOwner() ? [
|
||||||
|
@ -96,14 +96,7 @@ class FormResource extends JsonResource
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function doesMissPassword(Request $request)
|
private function getProtectedForm()
|
||||||
{
|
|
||||||
if (!$this->has_password) return false;
|
|
||||||
|
|
||||||
return !PasswordProtectedForm::hasCorrectPassword($request, $this->resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPasswordProtectedForm()
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
|
@ -131,8 +124,7 @@ class FormResource extends JsonResource
|
||||||
private function userIsFormOwner() {
|
private function userIsFormOwner() {
|
||||||
return $this->extra?->userIsOwner ??
|
return $this->extra?->userIsOwner ??
|
||||||
(
|
(
|
||||||
Auth::check()
|
Auth::check() && Auth::user()->ownsForm($this->resource)
|
||||||
&& Auth::user()->workspaces()->find($this->workspace_id) !== null
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,11 @@ class User extends Authenticatable implements JWTSubject
|
||||||
|
|
||||||
protected $withCount = ['workspaces'];
|
protected $withCount = ['workspaces'];
|
||||||
|
|
||||||
|
public function ownsForm(Form $form)
|
||||||
|
{
|
||||||
|
return $this->workspaces()->find($form->workspace_id) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the profile photo URL attribute.
|
* Get the profile photo URL attribute.
|
||||||
*
|
*
|
||||||
|
|
|
@ -139,7 +139,7 @@ Route::group(['prefix' => 'appsumo'], function () {
|
||||||
* Public Forms related routes
|
* Public Forms related routes
|
||||||
*/
|
*/
|
||||||
Route::prefix('forms')->name('forms.')->group(function () {
|
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');
|
Route::post('{slug}/answer', [PublicFormController::class, 'answer'])->name('answer');
|
||||||
|
|
||||||
// Form content endpoints (user lists, relation lists etc.)
|
// Form content endpoints (user lists, relation lists etc.)
|
||||||
|
|
|
@ -54,7 +54,7 @@ it('can not submit form without password for guest user', function () {
|
||||||
->assertStatus(403)
|
->assertStatus(403)
|
||||||
->assertJson([
|
->assertJson([
|
||||||
'status' => 'Unauthorized',
|
'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)
|
->assertStatus(403)
|
||||||
->assertJson([
|
->assertJson([
|
||||||
'status' => 'Unauthorized',
|
'status' => 'Unauthorized',
|
||||||
'message' => 'Form is password protected.'
|
'message' => 'Form is protected.'
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue