Spatie Laravel Permission assign a role did not work - laravel-8

I'm using Laravel 8 with Jetstream. My site has users. These users are related to many institutions, so here they have different roles inside the site, So I made a seeder where I create the Roles and the User and the institutions; everything is fine. I use the directives #can in the blade view to show and hide information to different roles. Still, here it does not show anything. Despite the fact I am with an administrator, it does not show what it is supposed to show.
Model
class UserInstitutions extends Model
{
use HasFactory;
use HasRoles;
protected $primaryKey = 'user_id';
public $incrementing = false;
protected $guard_name = 'web';
public function user() {
return $this->belongsTo(User::class);
}
public function institution() {
return $this->belongsTo(Institution::class,'institution_id_f');
}
}
Seeder
class RoleSeeder extends Seeder
{
public function run()
{
$admin = Role::create(['name' => 'Administrador']);
$titular = Role::create(['name' => 'Titular']);
$coor = Role::create(['name' => 'Coordinador']);
$subcoor = Role::create(['name' => 'SubCoordinador']);
$int = Role::create(['name' => 'Integrante']);
Permission::create(['name' => 'home.dashboard']);
Permission::create(['name' => 'dashboard']);
Permission::create(['name' => 'institution.index']);
Permission::create(['name' => 'institution.create']);
Permission::create(['name' => 'institution.update']);
Permission::create(['name' => 'institution.delete']);
$admin->syncPermissions(Permission::all());
$coor->givePermissionTo('institution.index');
$coor->givePermissionTo('institution.create');
}
}
The seeder where I assign the role
class UserInstitutionSeeder extends Seeder
{
public function run()
{
$institution = Institution::all()->random();
$user = User::all()->random();
UserInstitutions::create([
'user_id' => $user->id,
'institution_id_f' => $institution->id,
'institution_id' => $institution->institution_id,
'email' => 'pcoordinador#gob.sv',
'landline_phone_number' => '74859632',
'start_date' => now(),
'active' => 'S',
])->assignRole('Administrador');
UserInstitutions::factory(5)->create();
}
}
And if I check the data in the table, the role is being assigned
enter image description here

You may have a cache issue, you can add this line at your seeder class within the run() method
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
If you already have a session for that user, you can clear the cache from the command line:
php artisan permission:cache-reset
Or
php artisan cache:clear
https://spatie.be/docs/laravel-permission/v5/basic-usage/artisan#content-resetting-the-cache

Related

Can't authenticate with different table

I've changed the auth.php file in order to authenticate my users according to authors table. But I keep getting No account for you when I'm running test route.
auth.php
<?php
return array(
'driver' => 'eloquent',
'model' => 'Author',
'table' => 'authors',
'reminder' => array(
'email' => 'emails.auth.reminder', 'table' => 'password_reminders',
),
);
routes.php
Route::get('test', function() {
$credentials = array('username' => 'giannis',
'password' => Hash::make('giannis'));
if (Auth::attempt($credentials)) {
return "You are a user.";
}
return "No account for you";
});
AuthorsTableSeeder.php
<?php
class AuthorsTableSeeder extends Seeder {
public function run()
{
// Uncomment the below to wipe the table clean before populating
DB::table('authors')->delete();
$authors = array(
[
'username' => 'giannis',
'password' => Hash::make('giannis'),
'name' => 'giannis',
'lastname' => 'christofakis'],
[
'username' => 'antonis',
'password' => Hash::make('antonis'),
'name' => 'antonis',
'lastname' => 'antonopoulos']
);
// Uncomment the below to run the seeder
DB::table('authors')->insert($authors);
}
}
Addendum
I saw in another post that you have to implement the UserInterface RemindableInterface interfaces. But the result was the same.
Author.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Author extends Eloquent implements UserInterface, RemindableInterface {
protected $guarded = array();
public static $rules = array();
public function posts() {
return $this->hasMany('Post');
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return "giannis#hotmail.com";
}
}
You don't need to Hash your password when you are using Auth::attempt(); so remove Hash::make from routes
Route::get('test', function() {
$credentials = array('username' => 'giannis',
'password' => 'giannis');
if (Auth::attempt($credentials)) {
return "You are a user.";
}
return "No account for you";
});
and it will work like a charm!

Different name fields user table?

I have a form with 2 fields (username, password) and a mysql table with those 2 same fields (username, password), and I authentication system working properly :)
But, I can not make it work if my table fields have different names, for example: (my_user, my_pass).
If you just change the username field on the other also works for me, that gives me problems is the password field.
My config auth.php
'driver' => 'eloquent'
Update
Already found the solution in my controller, the password name can not change.
Before (WRONG):
What I've done in first place was wrong
$userdata = array(
'my_user' => Input::get('my_user'),
'my_pass' => Input::get('my_pass')
);
it should be
$userdata = array(
'my_user' => Input::get('my_user'),
'password' => Input::get('my_pass')
);
You can define you own username and password field in the auth.php inside the config folder.
return array(
'driver' => 'eloquent',
'username' => 'my_user',
'password' => 'my_pass',
'model' => 'User',
'table' => 'users',
);
I hope this can be of some help.
I ran into this same problem. You need to extend your model:
// User.php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $fillable = array('name','passwd','email','status','timezone','language','notify');
protected $hidden = array('passwd');
protected $table = "users_t";
protected $primaryKey = "uid";
public static $rules = array(
'name' => 'required',
'passwd' => 'required',
'email' => 'required'
);
public function getAuthIdentifier() {
return $this->getKey();
}
public function getAuthPassword() {
return $this->passwd;
}
public function getReminderEmail() {
return $this->email;
}
public static function validate($data) {
return Validator::make($data,static::$rules);
}
}
You need to implements this methods too:
public function getRememberToken(){
}
public function setRememberToken($value){
}
public function getRememberTokenName(){
}

How to call a custom service on the service locator object from Module#getViewHelperConfig() in Zend Framewok 2?

I have a ViewHelper and want to initialize it in Module#getViewHelperConfig():
<?php
namespace Search;
use statements...
class Module implements
ConfigProviderInterface,
ServiceProviderInterface,
AutoloaderProviderInterface,
ViewHelperProviderInterface {
public function getConfig() ...
public function getAutoloaderConfig() ...
public function getServiceConfig() {
$breakpoint = null;
try {
return array (
'factories' => array(
...
'SearchFormCourseSearchForm' => function ($serviceManager) {
$cacheService = $serviceManager->get('Cache\Model\CityStorage');
$cities = $cacheService->getCities();
$searchForm = new Form\CourseSearchForm($cities);
return $searchForm;
},
)
);
} ...
}
public function getViewHelperConfig() {
$breakpoint = null;
return array(
'factories' => array(
'searhForm' => function($serviceManager) {
$helper = new View\Helper\SearchForm(array('render' => true, 'redirect' => false));
$helper->setViewTemplate('search/search/search-courses');
$searchForm = $serviceManager->get('SearchFormCourseSearchForm');
$helper->setSearchForm($searchForm);
return $helper;
}
)
);
}
But ZF doesn't call my factory. Instead of this it tries to create a new SearchFormCourseSearchForm instance:
Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for SearchFormCourseSearchForm' in /var/www/bar/foo/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 456
How should I use service factories got from Module#getServiceConfig() creating a ViewHelper in Module#getViewHelperConfig()?
You need to get the main service locator. The $serviceManager in getViewHelperConfig() is the View Helper service locator.
To get the main service locator in your getViewHelperConfig() function, do the following:
$maimSm = $serviceManager->getServiceLocator();
Therefore:
public function getViewHelperConfig() {
return array(
'factories' => array(
'searhForm' => function($serviceManager) {
$helper = new View\Helper\SearchForm(array('render' => true, 'redirect' => false));
$helper->setViewTemplate('search/search/search-courses');
$maimSm = $serviceManager->getServiceLocator();
$searchForm = $maimSm->get('SearchFormCourseSearchForm');
$helper->setSearchForm($searchForm);
return $helper;
}
)
);
}
There are quite a few posts explaining this strategy in a bit more details, I'll go hunt for them.
Edit
See Using Zend Framework service managers in your application for a nice description of service managers/locators in ZF2.

yii. can't logout from module

I have admin module and different CWebUser(adminuser) for that module. It works good for login. So I can login in main app and in module by different users. But when I call logout method in module
Yii::app()->getModule('admin')->adminuser->logout();
it log me out from module and from main app as well.
how can I fix it?
thanks beforehand.
I think the key is stateKeyPrefix which can be used to tell different modules to use different session keys.
I will put main config file user section.
'user' => [
'allowAutoLogin' => true,
**'stateKeyPrefix' => 'YOUR-DEFAULT_',**
'loginUrl' => array('/login'),
'class' => 'application.wsi.auth.WSIWebUser',
'authTimeout' => 3600 * 24 // 1 hour
],
I have Admin module and I will put my AdminModule.php for you.
class AdminModule extends \CWebModule
{
public $defaultController = 'index';
public function init()
{
$this->setImport(array(
'admin.components.*',
));
$this->layout = 'main';
\Yii::app()->setComponents(array(
'authManager' => array(
'class' => 'CPhpAuthManager',
'authFile' => \Yii::getPathOfAlias('admin.data.auth') .'php',
'showErrors' => true,
),
'user' => array(
'stateKeyPrefix' => 'admin_',
'loginUrl' => \Yii::app()->createUrl('/admin/index/login'),
'class' => 'AdminWebUser',
'authTimeout' => 3600 * 24 // 1 day
),
), false);
}
}
I have components folder in admin module with AdminWebUser class in it as well.
class AdminWebUser extends \CWebUser {
public function getId() {
return Yii::app ()->user->getState ( 'id' );
}
public function getName() {
return Yii::app ()->user->getState ( 'name' );
}
public function getRole() {
return Yii::app ()->user->getState ( 'role' );
}
public function getEmail() {
return Yii::app ()->user->getState ( 'email' );
}
}
The rest of login and logout controller codes are same.
Hope it helps. If not please let me know.

Authorization adapter was not found in cakePHP

I'm trying to move my code from local to server
when i try to login into the application
Here is my AppController
class AppController extends Controller{
/* Determines what logged-in users access to */
var $components = array('Auth','Session');
public function isAuthorized($user){
return true;
}
public function beforeFilter(){
$userdetails = array();
$this->Auth->autoRedirect = false;
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'matches', 'action' => 'index');
$this->Auth->authorize = 'controller';
$this->Auth->authError= 'You need permissions to access this page';
$this->Auth->allow('users');
$this->set('Auth',$this->Auth);
$userdetails = $this->Auth->user();
$this->set('myUser', $userdetails['username']);
$this->set('myRole', $userdetails['user_role_id']);
$this->set('pStatus', $userdetails['password_status']);
}
}
Here is my Login Action in UsersController
public function login(){
$this->Auth->autoRedirect = false;
$id = $this->Auth->user('id');
if(empty($id)){
if($this->request->is('post')){
if($this->Auth->login()){
$this->redirect($this->Auth->redirect());
}else{
$this->Session->setFlash('Invalid Username or password');
}
}
}else{
$this->redirect(array('action'=>'index'));
}
}
Thanks for the help
The part where you authorise controllers in your beforeFilter should be capitalised properly:
So:
$this->Auth->authorize = 'Controller';
Instead of:
$this->Auth->authorize = 'controller';
That particular statement tries to find controllerAuthorize.php and should be looking for ControllerAuthorize.php. This doesn't cause a problem on Windows, but it does on Unix systems.