This action is unauthorized

72 Views Asked by At

I'm using Policy for all of the models. All is fine until I add policy to my ProjectData model. The index and store function are fine, but the other don't work (This action is unauthorized). I tried to set the return to true but still same error message.

Here are my codes.

ProjectDataController:

<?php

namespace App\Http\Controllers\Api\v1;

use App\Http\Controllers\Controller;
use App\Http\Requests\ProjectData\StoreProjectDataRequest;
use App\Http\Requests\ProjectData\UpdateProjectDataRequest;
use App\Models\ProjectData;
use App\Utils\JsendFormatter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;
use Str;

class ProjectDataController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(ProjectData::class, 'project_data');
    }

    public function index(Request $request): JsonResponse
    {
        $projectData = QueryBuilder::for(ProjectData::class)
            ->allowedFilters(['value', AllowedFilter::exact('team_id'), AllowedFilter::exact('project_data_scheme_id')])
            ->allowedSorts(['id', 'team_id', 'project_data_scheme_id', 'created_at', 'updated_at'])
            ->paginate($request->query('per_page', 10));

        return JsendFormatter::success_paginated('projectData', $projectData);
    }

    public function show(ProjectData $projectData): JsonResponse
    {
        return JsendFormatter::success_singleton('projectData', $projectData);
    }

    public function store(StoreProjectDataRequest $request): JsonResponse
    {
        if ($request->hasFile('value')) {
            $disk = 'local';
            $path = 'project_data';
            $file = $request->file('value');
            $file_name = Str::ulid()->toRfc4122() . '.' . $file->extension();

            $file->storeAs($path, $file_name, $disk);

            $projectData = ProjectData::create(
                array_replace(
                    $request->validated(),
                    ['value' => implode(';', [$disk, $path, $file_name])]
                )
            );
        } else {
            $projectData = ProjectData::create($request->validated());
        }

        return JsendFormatter::success_singleton('projectData', $projectData, 201);
    }

    public function update(UpdateProjectDataRequest $request, ProjectData $projectData): JsonResponse
    {
        if ($request->hasFile('value')) {
            $disk = 'local';
            $path = 'project_data';
            $file = $request->file('value');
            $file_name = Str::ulid()->toRfc4122() . '.' . $file->extension();

            $file->storeAs($path, $file_name, $disk);

            $projectData->update(
                array_replace(
                    $request->validated(),
                    ['value' => implode(';', [$disk, $path, $file_name])]
                )
            );
        } else {
            $projectData->update($request->validated());
        }

        return JsendFormatter::success_singleton('projectData', $projectData);
    }

    public function destroy(ProjectData $projectData): JsonResponse
    {
        $projectData->delete();

        return JsendFormatter::success_singleton('projectData', $projectData);
    }
}

ProjectDataPolicy:

<?php

namespace App\Policies;

use App\Models\ProjectData;
use App\Models\User;

class ProjectDataPolicy
{
    public function viewAny(User $user): bool
    {
        return true;
    }

    public function view(User $user, ProjectData $projectData): bool
    {
        return $user->is_admin || $projectData->team->reviewers->contains($user->id) || $user->id == $projectData->team->leader_id || $user->teams->contains($projectData->team_id);
    }

    public function create(User $user): bool
    {
        return ! $user->is_reviewer;
    }

    public function update(User $user, ProjectData $projectData): bool
    {
        return $user->is_admin || $user->id == $projectData->team->leader_id || $user->teams->contains($projectData->team_id);
    }

    public function delete(User $user, ProjectData $projectData): bool
    {
        return $user->is_admin || $user->teams->contains($projectData->team_id);
    }
}

ProjectData Model:

<?php

namespace App\Models;

use DateTimeInterface;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class ProjectData extends Model
{
    use HasFactory;

    protected $fillable = ['team_id', 'project_data_scheme_id', 'value'];

    protected $dateFormat = DATE_ATOM;

    protected function serializeDate(DateTimeInterface $date): string
    {
        return $date->format(DATE_ATOM);
    }

    public function team()
    {
        return $this->belongsTo(Team::class);
    }

    public function projectDataScheme()
    {
        return $this->belongsTo(ProjectDataScheme::class);
    }
}

I already add to the AuthServiceProvider also: ProjectData::class => ProjectDataPolicy::class,

It works without:

    public function __construct()
    {
        $this->authorizeResource(ProjectData::class, 'project_data');
    }

But, I need the policy. How to make it works fine like the other Controller

1

There are 1 best solutions below

0
Dwi Arfian On

[SOLVED]. I change singular variable to project_datum and it works.