Some of my laravel authorization abilities work and some don't.

Published 2 years ago by coderic

namespace App\Policies;

use App\User;
use App\Course;

class MyCoursesPolicy
{
    /**
     * Create a new policy instance.
     *
     * @return void
     */

    public function is_Admin(User $user){
        // abort(403);
        return $user;
        if( $user->isAdmin() ){
            return true;
        }
    }

    public function update_course_attributes(User $user, Course $course){
        if( ($user->hasRole('instructor') && $course->users->get($user->id) ) || $user->isAdmin() ){
            return true;
        }
    }

}

so update_course_attributes works but is_Admin does not work. I don't know how to troubleshoot this... I've tried to return the $user object in is_Admin but it doesn't work. I'm using it like this:


    if(Gate::check('is_Admin', $this->user)){
      return "you're an admin ";
    } else {
      return "you're no admin ";
    }
Best Answer (As Selected By coderic)
coderic

I've figured it out.

I had to move the isAdmin ability to AuthServiceProvider for it to work. Though I have no idea why it doesn't work if put in a policy.

RomainLanz

You can simplify your method by doing

public function is_Admin(User $user)
{
    return $user->isAdmin();
}

Can we see the isAdmin() method?

coderic
    public function isAdmin(){
        if($this->hasRole('admin')) {
            return true;
        }
    }
    public function hasRole($role) {
        $role = $this->roles()->where('type', '=', $role)->first();
        if ($role) {
            return true;
        }
        return false;
    }

All in the user model.

edit: I know isAdmin works because I can use that instead of the Gate check and it works fine... but this.. this ability is killing me here.

RomainLanz

Also

public function isAdmin()
{
    return $this->hasRole('admin');
}

How do you have register your policy?

coderic

Here is my policy:

namespace App\Providers;

use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Course;
use App\Policies\MyCoursesPolicy;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        'App\Course' => 'App\Policies\MyCoursesPolicy'
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */

    public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);
    }
}

Is there anything wrong here?

squigg

You don't need to pass the current User in manually for a policy method. The first argument is always the current user - this is automatic.

If you are wanting to check whether a different user to the current one is admin, then your policy method needs to be:

public function is_Admin(User $user, User $otherUserYouPassIn) {
    return $otherUserYouPassIn->isAdmin();
}

For debugging, rather than returning the user just dd($user);. Returning it will always be "truthy" therefore the policy will pass.

coderic

Hey squigg, thanks for your reply!

so I changed my isAdmin function to this:

    public function isAdmin(User $user){
        dd($user);
        return $us

and in my function that calls isAdmin:

public function listcourses(){
    return Gate::check('isAdmin');
}

however I get this error:

The Response content must be a string or object implementing __toString(), "boolean" given.

in chrome's network panel.

Any pointers on what to do from here on?

Edit:

Also.. I've changed the isAdmin function to only return true and it still doesn't work. There's no way it can be calling the wrong function because this is the only ability with that name. Help would be greatly appreciated!! This has been killing me for the past several days.

coderic

I've figured it out.

I had to move the isAdmin ability to AuthServiceProvider for it to work. Though I have no idea why it doesn't work if put in a policy.

Please sign in or create an account to participate in this conversation.