'Laravel Gates using model and returns "Using $this when not in object context" Line 28 of AzureUser model

Im trying to create a Gate in Laravel. The idea is to check if one of the roles is present on an AzureAD access token.

So far I have this

Gate::define('admin_cml', function () {
   $roles = AzureUser::roles();
   return in_array(config('app-roles.cml_admin'),$roles);
});

So far the response is "Using $this when not in object context".

Error of Gate and Model

Here is the full code

AuthServiceProvider -> Path app\Providers

<?php

namespace App\Providers;
use App\Models\AzureUser;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array<class-string, class-string>
     */
    protected $policies = [
        // 'App\Models\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        Gate::define('admin_cml', function () {
            $roles = AzureUser::roles();
            return in_array(config('app-roles.cml_admin'),$roles);
        });
    }
}

AzureUser Model -> app\Models

<?php
namespace App\Models;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Database\Eloquent\Model;

class AzureUser extends Model
{
 
        protected $id_token;
        protected $access_token;
        protected $user;
    
        public function __construct($access_token, $id_token)
        {
            $this->access_token = $access_token;
            $this->id_token = $id_token;
    
            $this->user = Socialite::driver('azure-oauth')->userFromToken($access_token);
        }
    
        public function get()
        {
            return $this->user;
        }
    
        public function roles()
        {
            $tokens = explode('.', $this->id_token);
    
            return json_decode(static::urlsafeB64Decode($tokens[1]))->roles;
        }
    
        public static function urlsafeB64Decode($input)
        {
            $remainder = strlen($input) % 4;
    
            if ($remainder) {
                $padlen = 4 - $remainder;
                $input .= str_repeat('=', $padlen);
            }
    
            return base64_decode(strtr($input, '-_', '+/'));
        }
    
}

Routes

<?php
use App\Http\Controllers\loginController;
use Illuminate\Support\Facades\Route;
use Laravel\Socialite\Facades\Socialite;

Route::get('/', function () {
    if(Auth::check()){
        return redirect()->route('app');
    }
    return view('welcome');
})->name('home');

Route::get('/app',function(){
    return view('layouts.app');
})->name('app')->middleware('auth');

// user routes
Route::prefix('user')->group(function () {
    Route::get('/login', [loginController::class,'login'])->name('login');

    Route::get('/logout', [loginController::class,'logout'])->name('logout');
});

Route::group(['middelware'=>['auth'],'prefix'=>'adminmm','as'=>'adminmm.'],function () {
    Route::get('/carros', function(){
        return "carros";
    })->name('carros');

    Route::get('/companias', function(){
        return "companias";
    })->name('companias');
});

// Here is the error. When going to admincml/mecanicos is when the error is showing up
Route::group(['middelware'=>['auth'],'prefix'=>'admincml','as'=>'admincml.'],function () {
    Route::get('/mecanicos', function(){
        if (! Gate::allows('admin_cml')) {
            abort(403);
        }
        return "mecanicos";
    })->name('mecanicos');
});

Any ideas why is not detecting the model? Thanks!



Solution 1:[1]

The error comes from AuthServiceProvider where you use static call to method, but it's not a static one...

AzureUser::roles();

It appears that you want to use $this instance variable there, so you have to make an instance to it like this in AuthServiceProvider.php:

use App\AzureUser;

$azure = new AzureUser();
$roles = $azure->role();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1