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
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!
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(){
}
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.
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.
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.