Authorization & Validation
Guard your Database at the class and method level...

Authorization

Komposers have different gates for authorizing rendering or handling incoming requests:

  1. Main Authorization
  2. Method-level authorizations.
  3. Route Middlewares.
  4. Boot Authorization.

Main Authorization

The main authorization gate handles incoming requests to the main action of a Komposer:

  • For `Forms`, this gate will protect form submissions (Eloquent or Self-handling Forms).
  • For `Querys`, this gate will protect browsing, filtering, sorting.

To authorize passing through the main gate, you may define an `authorize()` method, where you decide the security check for this action. For example, if you only want admins and the model's author to be able to perform the main action:

public function authorize()
{
  return \Auth::user()->isAdmin() || $this->model()->user_id == \Auth::user()->id;
}
By default, a Form has no `authorize()` method so it is unprotected (like controller actions). So make sure you do, if your specs require it!

Method-level Authorizations

Methods that handle incoming requests to Komposers perform Dependency injection. So to protect them, you simply need to add an extended `Illuminate\Foundation\Http\FormRequest` as a parameter. You may use:

  • The general purpose `KompoFormRequest`.
  • Or create your own custom `FormRequest` as we do in controller actions.

KompoFormRequest

Kompo has a general use `Kompo\Http\Requests\KompoFormRequest` that extends Laravel's FormRequest and uses the Komposer's main `authorize()` method and the main validation `rules()` method.

use Kompo\Http\Requests\KompoFormRequest;

class MyForm extends Form
{
   //... 

   //we protect this method by dependency injection of KompoFormRequest
   public function loadKomponents(KompoFormRequest $request)
   {
      return [
        _Textarea('Comment')
      ];
   }

   public function authorize() //KompoFormRequest will use this
   {
     //keeps the logic in the Komposer
   }

   public function rules() //KompoFormRequest will use this
   {
     //keeps the logic in the Komposer
   }
}
I prefer to use KompoFormRequest because it allows me to keep authorization and validation inside the Komposer class and not have to create a separate class.

Your custom FormRequest

You may also create and use a custom FormRequest as you usually do in Controller actions.

use App\Http\Requests\CustomFormRequest;

class MyForm extends Form
{
   //... 

   public function loadKomponents(CustomFormRequest $request)
   {
      return [
         _Textarea('Comment')
      ];
   }
}

And you control authorization and validation from you new class `App\Http\Requests\CustomFormRequest`:

Failed authorization message

By default, if the authorization fails - i.e. returns `false` - Laravel throws an `AuthorizationException` with a default message of 'This action is unauthorized'. If you wish to override this message, you may assign a value to the `$failedAuthorizationMessage` property in your Form:

public $failedAuthorizationMessage = 'A custom 403 message';

Or alternatively, if you want to customize the message with a variable, you may add a `failedAuthorization()` method to your Form:

public function failedAuthorization()
{
   return 'Sorry, you are not allowed to modify '.$this->model->name;
}

Route middlewares

To protect Komposers rendered by direct Route call, the best way is to protect them with middlewares:

Boot Authorization

The boot authorization is a gate at the very beginning of a Komposer's lifecycle. This gate has to return `true` to allow the code to continue processing, whether you are:

  • Trying to display a Komposer,
  • Or handling any incoming request to it.
public function authorizeBoot()
{
   return $some_condition ? true : false;
}
By default, the boot authorization is true! Because most of the time, we boot Komposers through routes or render them in Blade, and both are protected by middlewares.

Boot authorization is useful for displaying Komponents asynchronously. For example, you might create a Vue Component that displays the Komposer only when the user scrolls into view.

Validation

Main Validation

Validating the input is very easy and uses Laravel's request validation rules.
You just have to add the validation array to the `rules` method:

public function rules()
{
   return [
      'first_name' => 'min:2|max:100',
      'last_name' => 'min:2|max:100',
      'nick_name' => 'required_without_all:last_name,first_name',
      'avatar|*' => 'sometimes|mimes:jpeg,jpg,png,gif|size:10000'
   ];
}

After an invalid form submit, an error response (coded 422) will be sent and the error messages will be displayed under the relevant components.

The array syntax also works:

public function rules()
{
   return [
      'first_name' => ['min:2','max:100'],
      //...
   ];
}

Method-level Validation

Same as Method-level authorization, refer to that section for info.

Komponent rules

You may also assign validation rules directly to the Komponent.

Input::form('Title')->rules('required|min:3')

//or array syntax
Input::form('Title')->rules(['required','min:3'])

I only use this method for custom Komponents that I know will always require a certin set of rule. But for form submissions, I personnally prefer to keep all the rules grouped together in the Komposer's rule method.

Recursive rules

When your Komposer has other Komposers inside of it, the validation rules of child Komposers are transfered up to the parent when handling an incoming request.