Call to undefined method Auth::user()->can() in laravel 8 error - laravel

I have a problem with determining the permission with Auth::user()->can().
For example Auth::user()->can('trunk.index) returns always error;
But I have a problem.
If I dump $user->getPermissionsViaRoles(); ,I will get a large result.
I'm using different table user_view table.
And according to it I have changed in Auth.php file. and login is working fine.
'providers' => [
'users' => [
'driver' => 'self-eloquent',
'model' => App\Models\UserView::class,
]
],
But when I try to check permission the via Auth::user()->can('trunk.index) then it gives error below error.
Call to undefined method App\\Models\\UserView::can()
Below is my UserView model code.
<?php
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Traits\HasRoles;
use Laravel\Lumen\Auth\Authorizable;
use Laravel\Sanctum\HasApiTokens;
class UserView extends Model implements AuthenticatableContract
{
use Authenticatable;
use HasFactory;
use HasRoles;
use HasApiTokens;
protected $table = 'user_view';
protected $primaryKey = "user_id";
protected $fillable = [
'username', 'password',
];
protected $guarded = [];
public function getAuthPassword()
{
return ['password' => $this->attributes['user_password']];
}
// public function can($abilities, $arguments = []) {
// }
}
help me if I'm missing something. Thank you.

You are using a custom User model which does not implement the \Illuminate\Contracts\Auth\Access\Authorizable interface and \Illuminate\Contracts\Auth\Access\Gate\Authorizable trait. You do actually have an import for this interface, but it is not used anywhere.
Also be careful about the existing import Laravel\Lumen\Auth\Authorizable. I'm not familiar with Lumen, but this might be a different implementation / wrong import.
You essentially need to update your model with the following two lines:
<?php
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Foundation\Auth\Access\Authorizable; // <-- add import
use Spatie\Permission\Traits\HasRoles;
use Laravel\Sanctum\HasApiTokens;
class UserView extends Model implements AuthenticatableContract,
AuthorizableContract // <-- add interface
{
use Authenticatable;
use Authorizable; // <-- add trait
use HasFactory;
use HasRoles;
use HasApiTokens;
// ... other code ...
}

Related

Voyager get records from another database and show in table. (customized view)

There are two databse one is used for voyager and another is exiting database which filled data, I have to show in table form same as voyager do, I am newby and searched about to connect another database in voyager.
Customized controller to show listinf of domains
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
// use Illuminate\Routing\Controller as BaseController;
use TCG\Voyager\Http\Controllers\VoyagerBaseController as BaseController;
use TCG\Voyager\Facades\Voyager;
use App\Models\Domain;
class DomainController extends BaseController {
//
public function domainListing(){
dd(Domain::limit(5)->get()->toArray());
$data['abc'] = 'test';
return view('domain-list');
}
}
Routing file where I have wrote routing which is showing correctly,
Route::group(['prefix' => 'admin'], function () {
Voyager::routes();
Route::get('domains', ['uses' => 'App\Http\Controllers\DomainController#domainListing', 'as' => 'domains']);
});
Domain Model from another database
<?php
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Domain extends Model {
protected $connection = 'mysql-connection2';
protected $table = 'domain';
protected $guarded=[];
public $timestamps = true;

Laravel 5.5 Spatie Permission doesn't create role

I'm using laravel 5.5 and spatie / laravel-permission ":" ^ 2.38 ". I created a simple controller for creating a role, but laravel returns the error:
Illuminate \ Database \ Eloquent \ MassAssignmentException
"name"
My simple controller is:
<?php
namespace App;
namespace App\Http\Controllers\UserRole;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Model;
use App\Role;
use App\Permission;
use DB;
class RolePermission extends Controller
{
public function create_role(){
Role::create(['name' => 'noc']);
}
}
The problem is not related to Spatie. You must allow the Role object to be mass-assignable. In your case, you must put:
protected $fillable = ['name'];
to your Role model, or:
protected $guarded = [];
See more here

ORM not working in Default UserController & User Model in laravel

I want to get User wise Role. here is I'm facing error ....
UserController.php ( user controller file )
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\UserRequest;
use App\Employee;
use App\Role;
use App\User;
use App\Site;
use App\Client;
use App\ProjectType;
use App\UserPermission;
use Auth;
use DB;
use App\Project;
class UsersController extends BaseController {
public function __construct() {
$this->isSetClientAndProjectType();
$data = User::with('Role')->first();
echo "<pre>";print_r(json_decode($data)); die;
}
}
User.php ( user model file )
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable {
use SoftDeletes;
use Notifiable;
protected $fillable = [
'name', 'role_id', 'password', 'siteid', 'email', 'status', 'allowed_to_bypass_pm', 'allowed_to_bypass_admin'
];
protected $hidden = [
'password', 'remember_token',
];
// Get users roles
public function Role() {
return $this->hasMany('App\Role', 'role_id', 'id');
}
}
Error is
How can i solve this error?
Help me guys.
Thank You.
If a user has many "roles" it should be public function roles().
You have defined:
A single user has a role_id
Therefore you need:
If a user has a single role it would be:
public function role() {
return $this->belongsTo('App\Role');
}
The reverse on the Role model would be:
public function users() {
return $this->belongsToMany('App\User');
}
Since many users can have the same role.
Hope this helps.
You need to add belongsTo relationship
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable {
use SoftDeletes, Notifiable;
protected $fillable = [
'name', 'role_id', 'password', 'siteid', 'email', 'status', 'allowed_to_bypass_pm', 'allowed_to_bypass_admin'
];
protected $hidden = [
'password', 'remember_token',
];
// Get user's role
public function role() {
return $this->belongsTo('App\Role');
}
}
Now fetch data
$user = User::with('role')->find(1);
$role = $user->role;
You need to make sure your table structure and foreign key references are compatible with the model relationship methods used.
For example, you have used "HasMany" relationship on User model. For that, you will have to make sure that each record/row in users table(User model) "has many" associated records/rows in roles table(Role model).
Here HasMany method assumes a foreign key "role_id" on roles table(Role Model). On not finding of which, it throws error.
You first need to take in consideration the table structure of roles and users table(User and Role model) as per your requirement, and than add model relationship methods accordingly.
It can be a bit tricky if you are using the methods for the first time, you can refer the laravel documentation for the same:
eloquent-relationships

how to extend Builder class in laravel 5.2

I tried to extend Illuminate\Database\Query\Builder to override various functions, but i cant make it.
I created a custom builder (CustomBuilder.php)
<?php
use Closure;
use Illuminate\Support\Collection;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Query\Grammars\Grammar;
use Illuminate\Database\Query\Processors\Processor;
class CustomBuilder extends Illuminate\Database\Query\Builder {
public function get($columns = ['*'])
{
$builder = $this->applyScopes();
$models = $builder->getModels($columns);
if (count($models) > 0) {
$models = $builder->eagerLoadRelations($models);
}
return $builder->getModel()->newCollection($models);
}
}
And a custom model (CustomModel.php)
<?php
use DateTime;
use ArrayAccess;
use Carbon\Carbon;
use LogicException;
use Illuminate\Events\Dispatcher;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Contracts\JsonableInterface;
use Illuminate\Support\Contracts\ArrayableInterface;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
// use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\ConnectionResolverInterface as Resolver;
use CustomBuilder as QueryBuilder; // MyModel should now use your MyQueryBuilder instead of the default which I commented out above
abstract class CustomModel extends Illuminate\Database\Eloquent\Model
{
}
?>
What is the correct folder to put these files, and how to call it from my models?
I tried in app/Extensions, in vendor, but i get the same error.
Class CustomModel cannot be found.
Thanks

Can't validate user attempt

I'm using laravel 5.0 and I can't validate the login.
If I type a wrong match of email/pass, it redirects me perfect.
But when I type a correct email/pass then it returns me this:
Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\User given ...
I'm following the documentation and it looks like everything is allright.
Model:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
}
Controller
public function postsignin(Request $request)
{
if( Auth::attempt( ['email' => $request['email'], 'password' => $request['password'] ] ) )
return redirect()->route('dashboard');
return redirect()->back();
}
No idea what it is.
try to implement the AuthenticatableContract and Authenticatable trait
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class User extends Model implements AuthenticatableContract{
use Authenticatable
}

Resources