how to add category for laravel permissions? - laravel

I created an application using the spatie permission package.
And I want to categorize the permissions as shown below, without using the package

Open config/permission.php and define all of the permission in it using nested array:
'default_permissions' => [
'product_management' => [
'view_own_pro',
'view_pro',
'mng_own_pro',
'mng_pro',
'force_delete_pro',
'restore_pro',
],
'role_management' => [],
'category_management' => [],
'order_management'=> [],
'user_management'=> [],
],
Edit answer:
Or use it more simply:
'default_permissions' => [
// role_management
'view_role',
// category_management
'view_own_category',
'force_delete_category',
// user_management
'view_user',
'create_user',
// pro_management
'view_own_pro',
'view_pro',
'mng_own_pro',
'mng_pro',
'force_delete_pro',
'restore_pro',
],
And in routing:
Route::group(['middleware' => ['permission:view_user|view_role']], function () {
//
});
Or in blade:
#can('view_user')
//
#endcan
Check spatie-docs for more info.

Related

Laravel and Spatie Permissions plugin update not working

I've performed a long-overdue update on a Laravel project from v5.7 (with Spatie Permissions 2.21) to v9 with Spatie 5.5.0. I'm not getting any error but the hasRole() function no longer ever returns true for users who definitely have the role. Echoing Auth::user()->getRoleNames() for the user just returns an empty array. Any guidance would be greatly appreciated.
Looking at my old commits, it seems that aside from the composer.json additions and database migrations, that only things I needed to do were a User model edit:
...
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
...
And this config/permission.php (comments stripped):
<?php
return [
'models' => [
'permission' => Spatie\Permission\Models\Permission::class,
'role' => Spatie\Permission\Models\Role::class,
],
'table_names' => [
'roles' => 'roles',
'permissions' => 'permissions',
'model_has_permissions' => 'model_has_permissions',
'model_has_roles' => 'model_has_roles',
'role_has_permissions' => 'role_has_permissions',
],
'column_names' => [
'role_pivot_key' => null, //default 'role_id',
'permission_pivot_key' => null, //default 'permission_id',
'model_morph_key' => 'model_id',
'team_foreign_key' => 'team_id',
],
'register_permission_check_method' => true,
'teams' => false,
'display_permission_in_exception' => false,
'display_role_in_exception' => false,
'enable_wildcard_permission' => false,
'cache' => [
'expiration_time' => \DateInterval::createFromDateString('24 hours'),
'key' => 'spatie.permission.cache',
'store' => 'default',
],
];
Below few things i would like to try
$user->assignRole($this->roles)
Try echo below line just after assign
echo $user()->getRoleNames()
Also try fetch with relations
Dump($user->with('roles')->get()
It will tell you atleast roles assignment is working.
So it turns out this was connected to another problem I was having that fortunately I was trying to fix at the same time:
Laravel upgrade broke model paths
The cause of this permissions issue was in the database but not table / field names, but actually the field contents.
In the model_has_roles table, the old App\User namespace was used (hopefully I'm using "namespace" correctly there!) and should have been App\Models\User in line with the new namespace. Then it all worked fine.

The POST method is not supported for this route. Supported methods: GET, HEAD, How to solve this error ? Im using vue js and laravel 7

This is my my vue component
export default {
data(){
return{
form:new Form({
district: '',
province: '',
name: '',
})
}
},
methods: {
createHousehold(){
this.form.post('api/household');
}
},
mounted() {
console.log('Component mounted.')
}
}
This is the api route.
Route::apiResource('household','APIController/HouseholdController');
When I check the route list 'api/household' has get for index and post for storing, but I get this error and not able to figure out where do I specify the post method other than in the vue method. Also I tried adding csrf in the head section of my master blade
Explanation
You will need to set the Access-Control-Allow-Methods header the specifies the method or methods allowed when accessing the resource in response to a preflight request.
Ref URL - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
you can add cors package in server-side by using the following package(in laravel or PHP)
URL - https://packagist.org/packages/barryvdh/laravel-cors
composer require barryvdh/laravel-cors
Add in the middleware group under the app/Http/Kernel.php file.
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1',
'bindings',
\Barryvdh\Cors\HandleCors::class,
],
...
]
and run the following command.
php artisan vendor:publish --tag="cors"
update the config with the following content(config/cors.php)
return [
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedOriginsPatterns' => [],
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'], // this is the solution of your problem
'exposedHeaders' => [],
'maxAge' => 0,
]

How to set different auth guard in laravel with auth0

I am work on laravel with auth0 project (package is auth0/login).
My project has local auth users.
I am going to add auth method with auth0, so I have set auth config for auth0.
This is my /config/auth.php code
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'auth0web'=>[
'driver' => 'session',
'provider' => 'auth0_users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'auth0_users'=>[
'driver' => 'auth0'
],
],
this is my callback route's controller function.
public function auth0SigninCallback()
{
//return response()->json(Auth:: guard('auth0web)->user());
$service = \App::make('auth0');
// Try to get the user information
$profile = $service->getUser();
$userRepo = new Auth0UserRepository();
$auth0User = $userRepo->getUserByUserInfo($profile);
return response()->json($auth0User);
}
Auth::guard('auth0web)->user();
At this code I am getting null for auth user.
$profile is correctly getting for now.
how can I get different guard(Auth::guard('auth0web')->user()) for auth
Thanks for your advance.
PS
This is my session data maybe that is correctly
{
"_token": "OAmhhYKWeO0tK6E5FN3DHaRvVYx6PP7z0YPMAPrz",
"_previous": {
"url": "http://xxxxx.dev/login"
},
"_flash": {
"old": [],
"new": []
},
"auth0__user": {
"sub": "auth0|xxxxxxxxxxx",
"nickname": "xxxxxxxx",
"name": "xxxxx#xxxxx.com",
"picture": "https://s.gravatar.com/avatar/xxxx.png",
"updated_at": "2019-03-26T17:28:53.981Z",
"email": "xxxxxx#ixxx.com",
"email_verified": true
}
}
I have try override callback route controller
this is code
// Get a handle of the Auth0 service (we don't know if it has an alias)
$service = \App::make('auth0');
// Try to get the user information
$profile = $service->getUser();
// Get the user related to the profile
$auth0User = $this->userRepository->getUserByUserInfo($profile);
if ($auth0User) {
// If we have a user, we are going to log them in, but if
// there is an onLogin defined we need to allow the Laravel developer
// to implement the user as they want an also let them store it.
if ($service->hasOnLogin()) {
$user = $service->callOnLogin($auth0User);
} else {
// If not, the user will be fine
$user = $auth0User;
}
Auth::guard('auth0web')->login($user, $service->rememberUser());
}
// dd(auth());
// \Log::info(auth()->user());
return \Redirect::intended('/home');
}
at this time auth() is correctly working
but while redirecting to home Auth is initialized
this is my custom middleware.
public function handle($request, Closure $next)
{
// \Log::info('------------here---------');
// dd(auth());
$auth = Auth::user() ?? Auth::guard('ldap')->user();
// dd(auth());
// \Log::info(auth()->user());
if (!isset($auth->id)) {
return redirect('login');
} else {
return $next($request);
}
}
At this part I'm getting null from auth()->user()

hiding an index of array laravel

I want to ask, how to hidden a name in role login.
So I have a output in laravel like this:
{
"npp":"822345",
"nama":"Handra Pratama",
"bus_pergi":1,
"bus_pulang":4,
"hotel":null,
"kamar":"K1",
"teman_kamar":[
{
"nama":"Handra Pratama"
},
{
"nama":"Louis Vernando"
},
{
"nama":"Hallo Budi"
}
]
}
I want to hide role handra (because I'm login with handra username) in teman_kamar, and if i login role louis, i want to hide louis in teman_kamar, what should i do?
Your output is in JS, so you can use a filter function in JS. But if you want to do it in PHP here is an example that I ran and it works per your case, because you always have the name that you want to hide under the first name key.
<?php
$obj = [
"npp" => "822345",
"nama" => "Handra Pratama",
"bus_pergi" => 1,
"bus_pulang" => 4,
"hotel" => null,
"kamar" => "K1",
"teman_kamar" => [
[
"nama" => "Handra Pratama"
],
[
"nama" => "Louis Vernando"
],
[
"nama" => "Hallo Budi"
]
]
];
$obj['teman_kamar'] = array_filter($obj['teman_kamar'], function($val) use ($obj) {
return $val['nama'] !== $obj['nama'];
});
print_r($obj);

Yii2 PageCache invalidation

Is there any possibility to invalidate or delete PageCache for a particular action.
Consider this:
class SiteController extends Controller
{
public function behaviors()
{
return [
'pageCache' => [
'class' => PageCache::className(),
'duration' => Yii::$app->params['cacheTime'], // seconds
'variations' => [
Yii::$app->language,
Yii::$app->request->get('id'),
],
],
];
}
public function actionIndex( $id )
{
// action code
}
}
And now I want to remove/invalidate cache for
action en/site/index?id=1
Currently I am thinking to write some code in a console app but do not know how to achieve this.
EDIT1: I try to rebuild-invalidate cache manually for a specific action. The code can't relay on 'dependency' because it is almost impossible to implement for that action.
EDIT2: The task is to rebuild cache only for the specific action (page) leave other cache intact.
You can use TagDependency for more granular invalidation:
public function behaviors()
{
return [
'pageCache' => [
'class' => PageCache::className(),
'duration' => Yii::$app->params['cacheTime'], // seconds
'variations' => [
Yii::$app->language,
Yii::$app->request->get('id'),
],
'dependency' => new \yii\caching\TagDependency([
'tags' => [
Yii::$app->requestedRoute,
Yii::$app->request->get('id'),
],
]),
],
];
}
To invalidate cache:
TagDependency::invalidate(Yii::$app->cache, [
'site/index', // route of action
123, // ID of page
]);
If someone else needs ...
Yii2 does not provide a native function to invalidate the cache of a specific page, however there is the delete function of the cache component. It would however be necessary to know the generated key for the requested page but the function that generates this key is protected (calculateCacheKey ()). In this way, the best way would be to create your own class extending \yii\filters\PageCache.
'pageCache' => function () {
return new class extends \yii\filters\PageCache{
public function init(){
parent::init();
$this->except = ['index'];
$this->duration = Yii::$app->params['cacheTime'], // seconds;
$this->variations = [
Yii::$app->language,
Yii::$app->request->get('id'),
];
if(Yii::$app->request->get('IC') == 1)
Yii::$app->cache->delete($this->calculateCacheKey());
}
public function beforeCacheResponse(){
return Yii::$app->request->get('IC') != 1;
}
};
},
In the provided code, for simplicity, I am using an anonymous class (PHP 7).
Instead you can create your class as you wish and inform its path as the 'class' parameter, as seen in the configuration displayed in the question.
Note that I am using a simple logic to invalidate the cache, checking if there is a GET parameter IC == 1, you can use whatever logic you want.
If after invalidating the cache you do not want a new cache to be created, simply return false in beforeCacheResponse, it is from \yii\filters\PageCache.
You can invalidate the cache by using dependencies
'pageCache' => [
...
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT COUNT(*) FROM post',
],
http://www.yiiframework.com/doc-2.0/yii-filters-pagecache.html#$dependency-detail
If I understand correctly you are trying to disable caching only for a specific action and according to the DOCS you can use the following options to explicitly identify which action IDs to apply the cache filter OR which action IDs it should not.
$except array List of action IDs that this filter should not apply to. yii\base\ActionFilter
$only array List of action IDs that this filter should apply to.
The following should work for you
return [
'pageCache' => [
'class' => PageCache::className(),
'except'=>['index']
'duration' => Yii::$app->params['cacheTime'], // seconds
'variations' => [
Yii::$app->language,
Yii::$app->request->get('id'),
],
],
];

Resources