Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for generating policies #614

Merged
merged 2 commits into from
May 6, 2023
Merged

Add support for generating policies #614

merged 2 commits into from
May 6, 2023

Conversation

faustbrian
Copy link
Contributor

@faustbrian faustbrian commented May 5, 2023

Resolves #42

Questions

Description

Examples

authorizeResource

Input

models:
  Ticket:
    team_id: id foreign
    type: string nullable
    subtype: string nullable
    name: string
    slug: string

controllers:
  Ticket:
    index:
      query: all:tickets
      render: ticket.index with:tickets
    create:
      render: ticket.create
    store:
      validate: title, content
      save: ticket
      send: ReviewNotification to:ticket.author with:ticket
      dispatch: SyncMedia with:ticket
      fire: NewTicket with:ticket
      flash: ticket.id
      redirect: ticket.index
    show:
      render: ticket.show with:ticket
    edit:
      render: ticket.edit with:ticket
    update:
      validate: ticket
      update: ticket
      flash: ticket.id
      redirect: ticket.index
    destroy:
      delete: ticket
      flash: ticket.id
      redirect: ticket.index
    meta:
      policies: true

Output

<?php

namespace App\Http\Controllers;

use App\Events\NewTicket;
use App\Http\Requests\TicketStoreRequest;
use App\Http\Requests\TicketUpdateRequest;
use App\Jobs\SyncMedia;
use App\Models\Ticket;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class TicketController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(Ticket::class, 'ticket');
    }

    public function index(Request $request): View
    {
        $tickets = Ticket::all();

        return view('ticket.index', compact('tickets'));
    }

    public function create(Request $request): View
    {
        return view('ticket.create');
    }

    public function store(TicketStoreRequest $request): RedirectResponse
    {
        $ticket = Ticket::create($request->validated());


        SyncMedia::dispatch($ticket);

        event(new NewTicket($ticket));

        $request->session()->flash('ticket.id', $ticket->id);

        return redirect()->route('ticket.index');
    }

    public function show(Request $request, Ticket $ticket): View
    {
        return view('ticket.show', compact('ticket'));
    }

    public function edit(Request $request, Ticket $ticket): View
    {
        return view('ticket.edit', compact('ticket'));
    }

    public function update(TicketUpdateRequest $request, Ticket $ticket): RedirectResponse
    {
        $ticket->update($request->validated());

        $request->session()->flash('ticket.id', $ticket->id);

        return redirect()->route('ticket.index');
    }

    public function destroy(Request $request, Ticket $ticket): RedirectResponse
    {
        $ticket->delete();

        $request->session()->flash('ticket.id', $ticket->id);

        return redirect()->route('ticket.index');
    }
}
policies

Input

models:
  Ticket:
    team_id: id foreign
    type: string nullable
    subtype: string nullable
    name: string
    slug: string

controllers:
  Ticket:
    index:
      query: all:tickets
      render: ticket.index with:tickets
    create:
      render: ticket.create
    store:
      validate: title, content
      save: ticket
      send: ReviewNotification to:ticket.author with:ticket
      dispatch: SyncMedia with:ticket
      fire: NewTicket with:ticket
      flash: ticket.id
      redirect: ticket.index
    show:
      render: ticket.show with:ticket
    edit:
      render: ticket.edit with:ticket
    update:
      validate: ticket
      update: ticket
      flash: ticket.id
      redirect: ticket.index
    destroy:
      delete: ticket
      flash: ticket.id
      redirect: ticket.index
    meta:
      policies: index,create,store,show,edit,update,destroy

Output

<?php

namespace App\Http\Controllers;

use App\Events\NewTicket;
use App\Http\Requests\TicketStoreRequest;
use App\Http\Requests\TicketUpdateRequest;
use App\Jobs\SyncMedia;
use App\Models\Ticket;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class TicketController extends Controller
{
    public function index(Request $request): View
    {
        $this->authorize('index', Ticket::class);

        $tickets = Ticket::all();

        return view('ticket.index', compact('tickets'));
    }

    public function create(Request $request): View
    {
        $this->authorize('create', Ticket::class);

        return view('ticket.create');
    }

    public function store(TicketStoreRequest $request): RedirectResponse
    {
        $this->authorize('store', Ticket::class);


        $ticket = Ticket::create($request->validated());


        SyncMedia::dispatch($ticket);

        event(new NewTicket($ticket));

        $request->session()->flash('ticket.id', $ticket->id);

        return redirect()->route('ticket.index');
    }

    public function show(Request $request, Ticket $ticket): View
    {
        $this->authorize('show', Ticket::class);

        return view('ticket.show', compact('ticket'));
    }

    public function edit(Request $request, Ticket $ticket): View
    {
        $this->authorize('edit', $ticket);

        return view('ticket.edit', compact('ticket'));
    }

    public function update(TicketUpdateRequest $request, Ticket $ticket): RedirectResponse
    {
        $this->authorize('update', $ticket);


        $ticket->update($request->validated());

        $request->session()->flash('ticket.id', $ticket->id);

        return redirect()->route('ticket.index');
    }

    public function destroy(Request $request, Ticket $ticket): RedirectResponse
    {
        $this->authorize('destroy', $ticket);

        $ticket->delete();

        $request->session()->flash('ticket.id', $ticket->id);

        return redirect()->route('ticket.index');
    }
}

@faustbrian faustbrian changed the title [WIP] Add support for generating controller policies Add support for generating controller policies May 5, 2023
@faustbrian faustbrian marked this pull request as ready for review May 5, 2023 05:04
@faustbrian faustbrian marked this pull request as draft May 5, 2023 06:16
@faustbrian faustbrian changed the title Add support for generating controller policies Add support for generating policies May 5, 2023
@jasonmccreary
Copy link
Collaborator

I really don't like adding more config. Can these be packed down into one config? For example, the default is to use controller authorization unless meta.policies is true? Or vice-versa.

@faustbrian
Copy link
Contributor Author

faustbrian commented May 5, 2023

Sure. Do you have a list of possible values for the meta.policies property or should it just be true results in authorizeResource being used and otherwise the specified methods are used?

Edit: Updated the OP with the new syntax.

@jasonmccreary
Copy link
Collaborator

Nice. I'll need to update the docs once this is tagged. But I like the syntax.

@faustbrian faustbrian marked this pull request as ready for review May 6, 2023 02:41
@faustbrian
Copy link
Contributor Author

Added tests for all the new lexers and generators.

Copy link
Collaborator

@jasonmccreary jasonmccreary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment.

@faustbrian
Copy link
Contributor Author

@jasonmccreary think I made all requested changes

@jasonmccreary jasonmccreary merged commit 1a62e81 into laravel-shift:master May 6, 2023
@faustbrian faustbrian deleted the feat/controller-policies branch May 6, 2023 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Idea: Policy generation & Authorisation
2 participants