How do I protect properties from certain users in a FormRequest?

54 Views Asked by At

I have several models in a Laravel/Backpack app where write access to certain properties is restricted to certain user roles.

Say I have a model Client with the properties

  • name
  • phone
  • active
  • viewCount

I want users with regular user privileges to be able to edit the name and phone properties but not active and viewCount. However, administrators should be able to edit active, and super duper administrators should have full access to viewCount.

I have this sorted out on the UI level and now want to implement basic security in the backend.

I would like to silently filter out (unset) properties that the current user is not allowed to edit, but may have maliciously set in the request.

I've been pointed to a custom FormRequest class being the place for this, but am a little lost how to implement it.

Should I take the pre-generated

public function rules()
{
    return [
        'name' => 'nullable|string',
        'address' => 'required|string',
        .....

and return a different array of validation rules depending on the current user's permissions? Is there a validation rule that unsets a field?

Or is there a more elegant way to handle this inside the FormRequest class?

1

There are 1 best solutions below

1
silver On

You can simply pass in additional rule for different user role, and as long as you use the validated inputs, all should be good and any inputs not specified in the rules will not in the the validated result, e.i. for using Form validation

public function rules() {
    $rules = [
        'name' => 'nullable|string',
        'address' => 'required|string',
    ];

    // Additional rule only for administrator or super admin
    if ( $this->user()->howEverYouFilterTheRole() )
        $rules['active'] = 'nullable';

    // additional rule only for superAdmin
    if ( $this->user()->howEverYouFilterTheRole() )
        $rules['viewCount'] = 'nullable';

    return $rules;
}

then just the call in the validated method of the request

public function store( WhatEverFormRequest $request ) {

    // Only contains field input specific in the rules;
    $validated = $request->validated();
}

OR apply the rule directly on request

public function store( Request $request ) {

    $rules = [
        'name' => 'nullable|string',
        'address' => 'required|string',
    ];

    // Additional rule only for administrator or super admin
    if ( $request->user()->howEverYouFilterTheRole() )
        $rules['active'] = 'nullable';

    // additional rule only for superAdmin
    if ( $request->user()->howEverYouFilterTheRole() )
        $rules['viewCount'] = 'nullable';

    // Only contains inputs specified in rules
    $validated =  $request->validate( $rules );


}

Another options you could use would be the rules; prohibited-if, prohibited-unless, exclude-if, exclude-unless