How to secure laravel-permission modules, file-manager or settings? - php

I created two roles: admin and editor. I can secure the menus of these modules directly into the resources/views/vendor/backpack/base/inc/sidebar.blade.php using
#role('admin')
<li class="header">{{ trans('backpack::base.administration') }}</li>
<!-- ================================================ -->
<!-- ==== Recommended place for admin menu items ==== -->
<!-- ================================================ -->
<li><i class="fa fa-dashboard"></i> <span>{{ trans('backpack::base.dashboard') }}</span></li>
<li><i class="fa fa-files-o"></i> <span>File manager</span></li>
<li><i class="fa fa-hdd-o"></i> <span>Backups</span></li>
<li><i class="fa fa-terminal"></i> <span>Logs</span></li>
<li><i class="fa fa-cog"></i> <span>Settings</span></li>
<!-- ======================================= -->
<li class="header">{{ trans('backpack::base.user') }}</li>
<!-- Users, Roles Permissions -->
<li class="treeview">
<i class="fa fa-group"></i> <span>Users, Roles, Permissions</span> <i class="fa fa-angle-left pull-right"></i>
<ul class="treeview-menu">
<li><i class="fa fa-user"></i> <span>Users</span></li>
<li><i class="fa fa-group"></i> <span>Roles</span></li>
<li><i class="fa fa-key"></i> <span>Permissions</span></li>
</ul>
</li>
#endrole
<li><i class="fa fa-sign-out"></i> <span>{{ trans('backpack::base.logout') }}</span></li>
</ul>
Of course, this is not the end, as you still have to secure access to the module for the editor by entering the URL. in vendor/backpack/permissionmanager/src/app/Http/Controllers/PermissionCrudController.php method setup can use
Auth::user()->hasRole('admin')
and throw error or redirect but ...
This is not a good solution (writing in modules in vendor). What should I do? How to secure editor access to the mentioned modules. Sorry if it's too easy for you, I'm just starting to have fun with Laravel
PS. https://github.com/spatie/laravel-permission/issues/507

I'd recommend creating middleware to check for a permission or a role, and lock people out using role:admin or permission:admin, something like this:
PermissionMiddleware.php:
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class PermissionMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $permission)
{
if (Auth::guest()) {
return redirect('login');
}
if (! $request->user()->can($permission)) {
abort(403);
}
return $next($request);
}
}
RoleMiddleware.php:
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $role)
{
if (Auth::guest()) {
return redirect('login');
}
if (! $request->user()->hasRole($role)) {
abort(403);
}
return $next($request);
}
}
You should then be able to use these when you write the routes to your CRUDs. If you want to overwrite the routes created in Backpack\Base, you should be able to easily do that by creating a file routes/backpack/base.php. Backpack will then load that file, instead of the one in the package. See https://github.com/laravel-backpack/base#overwriting-functionality for more details.
Hope it helps!

Related

Too few arguments to function App\Http\Controllers\ProduitController::show()

I wants to show users list into my dashboard pannel but it shows me this problem :
Too few arguments to function App\Http\Controllers\ProduitController::show(), 0 passed in C:\wamp64\www\Ecommerce\vendor\laravel\framework\src\Illuminate\Routing\Controller.php on line 54 and exactly 1 expected
Controller File :
public function show($id)
{
$produit = Produit::find($id);
return view('produits', compact('produit'));
}
blade file :
#foreach($produits as $produit)
<div class="product__item__pic set-bg" data-setbg="{{ asset('img/uploads/'.$produit->image)}}">
<ul class="product__item__pic__hover">
<li><i class="fa fa-heart"></i></li>
<li><i class="fa fa-retweet"></i></li>
<li><i class="fa fa-shopping-cart"></i></li>
</ul>
</div>
<div class="product__item__text">
<h6>{{ $produit->designation }}</h6>
<h5>{{ $produit->prix_uni }} Mad</h5>
</div>
#endforeach
Route :
Route::get('/produits','ProduitController#show');
If you have an id in your function definition, this should also be there in route definition. Route variables is defined with {id}.
Route::get('/produits/{id}','ProduitController#show');
For a best practice, use model binding, if you call your route variable the same as the model, you can automatically load it by typehinting it.
Route::get('/produits/{produit}','ProduitController#show');
public function show(Produit $produit)

How to display notifications in Laravel?

I'm having a weird issue.
I have two notification classes InterviewRequestReceived.php and SendJobSeekerResume.php.
I'm trying to display the total number of notifications using count() next to a little bell icon and then a message related to the respective notification class. The messages are simple, they are located in /layouts/partials/notification.
1. interview_request_received.blade.php
<div>
<span class="font-weight-bold">You've been sent an Interview request!</span>
</div>
2. send_job_seeker_resume.blade.php
<div>
<span class="font-weight-bold">You've been sent a new Job Profile!</span>
</div>
in my admin file I have 2 roles, depending on if the user is logged in as a jobseeker or employer.
admin.blade.php:
<!-- Nav Item - Alerts -->
<li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" href="#" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Notifications<i class="fas fa-bell fa-fw"></i>
#if(Auth::user()->role_id === 1)
<!-- Counter - Alerts -->
<span class="badge badge-danger badge-counter">{{ $jobSeekerProfile->unreadNotifications->where('type', 'App\Notifications\InterviewRequestReceived')->count() > 0 ? $jobSeekerProfile->unreadNotifications->count() : '' }}</span>
#endif
#if(Auth::user()->role_id === 2)
<!-- Counter - Alerts -->
<span class="badge badge-danger badge-counter">{{ Auth::user()->unreadNotifications->where('type', 'App\Notifications\SendJobSeekerResume')->count() }}</span>
#endif
</a>
<!-- Dropdown - Alerts -->
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="alertsDropdown">
<h6 class="dropdown-header">
Notifications
</h6>
#if(Auth::user()->role_id === 1)
#foreach($jobSeekerProfile->unreadNotifications as $notification)
<a class="dropdown-item d-flex align-items-center" href="#">
#include('layouts.partials.notification.'. Str::snake(class_basename($notification->type)))
</a>
#endforeach
#endif
#if(Auth::user()->role_id === 2)
#foreach(Auth::user()->unreadNotifications as $notification)
<a class="dropdown-item d-flex align-items-center" href="#">
#include('layouts.partials.notification.'. Str::snake(class_basename($notification->type)))
</a>
#endforeach
#endif
<a class="dropdown-item text-center small text-gray-500" href="#">Show All Alerts</a>
</div>
</li>
Both items with role_id === 1 are working, I get the count and the item with the message,
but the items where role_id === 2 I get count 0 and no item with message, it is very strange. Of course I'm viewing and testing with 2 accounts where I either have role_id set to 1 or role_id set to 2.
Here is a screenshot of my Notifications Table:
When I login with the user_id 12 (also role_id is set to 2) it should display all of the notifications where notifiable_id is set to 12.
I die and dumped my two models to see if the notifications are there,
employerProfile and jobSeekerProfile models like this, and I can see that there are no notifications in my employerProfile model, it is just an empty array. Below are screenshots.
dd($employerProfile->notifications);
dd($jobSeekerProfile->notifications);
EmployerProfile.php model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
class EmployerProfile extends Model
{
use Notifiable;
protected $fillable = [
'user_id',
'company_name',
'company_phone',
'immediate_contact',
'email',
'company_address',
'number_of_employees'
];
public function user(){
return $this->belongsTo('App\User');
}
}
JobSeekerProfile.php model:
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
class JobSeekerProfile extends Model
{
use Notifiable;
protected $fillable = [
'user_id',
'photo_id',
'resume_id',
'video_one_id',
'video_two_id',
'video_three_id',
'first_name',
'last_name',
'email',
'date_of_birth',
'full_or_part_time',
'experience',
'additional_skills',
'file'
];
public function user(){
return $this->belongsTo('App\User');
}
public function resume(){
return $this->belongsTo('App\Resume');
}
public function video(){
return $this->belongsTo('App\Video');
}
}
Can anyone help?
You are getting notifications from wrong Model.
According to your code and database structure,
assume login user id is 3,employer_profile_user_id is 12
$user->unreadNotifications get records from notifications table where notifiable_type is App\User and notifiable_id is 3;
$user->employerProfile->unreadNotifications get records from notifications table where notifiable_type is App\EmployerProfile and notifiable_id is 12;
so try this for count
#if(Auth::user()->role_id === 2)
<!-- Counter - Alerts -->
<span class="badge badge-danger badge-counter">{{ Auth::user()->employerProfile->unreadNotifications->where('type', 'App\Notifications\SendJobSeekerResume')->count() }}</span>
#endif
and this for detail
#if(Auth::user()->role_id === 2)
#foreach(Auth::user()->employerProfile->unreadNotifications as $notification)
<a class="dropdown-item d-flex align-items-center" href="#">
#include('layouts.partials.notification.'. Str::snake(class_basename($notification->type)))
</a>
#endforeach
#endif

Laravel 5.8 Trying to get property 'unreadNotifications' of non-object

Working on my friend's code, it seems all features like Post, Tag, Category, etc are working fine. I want to add a feature to upload a pdf and download it from front end. After adding DownloadController and Downloads model, It shows varies errors. Most irritating error is
Trying to get property 'unreadNotifications' of non-object(View: /var/www/html/tes/resources/views/admin/layouts/header.blade.php)
Routes:
//Admin Routes
Route::group(['namespace'=>'Admin'], function (){
Route::get('admin/home','HomeController#index')->name('admin.index');
//Users Routes
Route::resource('admin/user','UserController');
//Roles Routes
Route::resource('admin/role','RoleController');
//permissions Routes
Route::resource('admin/permission','PermissionController');
//Download Manager Routes - CV
Route::resource('admin/cv','Downloadcontroller');
//Post Routes
Route::DELETE('postDeleteSelected','PostController#deleteSelected')->name('deleteSelected');
Route::get('admin/post/remove/{post}','PostController#remove')->name('posts.remove');
Route::get('admin/post/trash','PostController#trashed')->name('posts.trashed');
Route::get('admin/post/recover/{id}','PostController#recover')->name('posts.recover');
Route::get('markAsRead','PostController#markRead')->name('markRead');
Route::resource('admin/post','PostController');
//Tag Routes
Route::resource('admin/tag','TagController');
//Category Routes
Route::resource('admin/category','CategoryController');
//Admin Auth Routes
Route::get('admin-login','Auth\LoginController#showLoginForm')->name('admin.login');
Route::post('admin-login','Auth\LoginController#login');
});
Controller:
namespace App\Http\Controllers\Admin;
use App\Model\admin\admin;
use App\Model\user\Downloads;
use App\Http\Controllers\Controller;
use App\Notifications\TaskCompleted;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Notification;
class Downloadcontroller extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
return view('admin.cv.show');
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$data = new Downloads;
if ($request->file('file')){
$file = $request->file('file');
$filename = time().'.'.$file->getClientOriginalExtension();
$request->file->move('storage/'.$filename);
$data->file = $filename;
}
$data->title = $request->title;
$data->description = $request->description;
$data->uploader = Auth::user()->name;
$data->save();
$users = admin::where('id','3')->get();
Notification::send($users, new TaskCompleted($data));
return redirect(route('cv.index'))->with('toast_success','Post Created Successfully');
}
View: in admin.cv.show, the template extends the admin.layouts.app. and the problematic view is here.
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="far fa-bell"></i>
#if (Auth::check())
#if(auth()->user()->unreadNotifications->count())
<span class="badge badge-warning navbar-badge">{{auth()->user()->unreadNotifications->count()}}</span>
#endif
#endif
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<span class="dropdown-item dropdown-header">
Mark All as Read
</span>
#foreach(auth()->user()->unreadNotifications as $notification)
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item" style="background-color: lightgrey">
<p><i class="fas fa-envelope mr-2"></i>{{$notification->data['data']}}
<span class="float-right text-muted text-sm">{{$notification->created_at->diffForHumans()}}</span>
</p>
</a>
#endforeach
#foreach(auth()->user()->readNotifications->take(5) as $notification)
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item">
<p><i class="fas fa-envelope mr-2"></i>{{$notification->data['data']}}
<span class="float-right text-muted text-sm">3 mins</span>
</p>
</a>
#endforeach
<div class="dropdown-divider"></div>
See All Notifications
</div>
</li>

Route Laravel Error

this is my routes
Route::get('/', 'frontcontroller#index');
Route::get('/index.html', 'frontcontroller#index');
Route::get('/checkout.html', 'frontcontroller#checkout');
Route::get('/furniture.html', 'frontcontroller#furniture');
Route::get('/login.html', 'frontcontroller#login');
Route::get('/products.html', 'frontcontroller#products');
Route::get('/register.html', 'frontcontroller#register');
Route::get('/single.html', 'frontcontroller#single');
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::group(['prefix' => 'admin','middleware'=>'auth'], function () {
Route::get('/', function () {
return view('admin.index');
})->name('admin.index');
});
this is a side navigation:
{{-- Side Navigation --}}
<div class="col-md-2">
<div class="sidebar content-box" style="display: block;">
<ul class="nav">
<!-- Main menu -->
<li class="current"><a href="{{route('admin.index')}}"><i class="glyphicon glyphicon-home"></i>
Dashboard</a></li>
<li class="submenu">
<a href="#">
<i class="glyphicon glyphicon-list"></i> Products
<span class="caret pull-right"></span>
</a>
<!-- Sub menu -->
<ul>
<li>Add Product</li>
</ul>
</li>
</ul>
</div>
</div> <!-- ADMIN SIDE NAV-->
This is the route function
/**
* Get the URL to a named route.
*
* #param string $name
* #param mixed $parameters
* #param bool $absolute
* #return string
*
* #throws \InvalidArgumentException
*/
public function route($name, $parameters = [], $absolute = true)
{
if (! is_null($route = $this->routes->getByName($name))) {
return $this->toRoute($route, $parameters, $absolute);
}
throw new InvalidArgumentException("Route [{$name}] not defined.");
}
Why I have this problem?
Route [product.index] not defined.
(View:C:\Users\Antonio\Desktop\uni\musicshop\resources\views\admin\layout\includes\sidenav.blade.php)
(View:C:\Users\Antonio\Desktop\uni\musicshop\resources\views\admin\layout\includes\sidenav.blade.php)
(View:C:\Users\Antonio\Desktop\uni\musicshop\resources\views\admin\layout\includes\sidenav.blade.php)
This is the code of the problem:
enter image description here
you should set name route
Route::get('/products.html', 'frontcontroller#products')->name('product.index');

i created notification function and getting this error "Undefined index: user" how to solve it?

im creating notification function,and when the user replied to a post it should send notification to the owner of the post. But there was an error showing
Undefined index: question. may i know how to solve it.
app.blade
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria- expanded="false">
<span class="glyphicon glyphicon-globe"> </span> notification <span
class="badge">{{count(auth()->user()->unreadNotifications)}}</span>
</a>
<ul class="dropdown-menu" role="menu">
<li>
#foreach(auth()->user()->unreadNotifications as $notification)
#include('layouts.partials.notification.'.snake_case(class_basename($notification->type)))
#endforeach
</li>
</ul>
model
class RepliedToPost extends Notification
{
use Queueable;
protected $postqs;
public function __construct($postqs)
{
$this->postqs=$postqs;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'postqs'=>$this->postqs,
'user'=>$notifiable
];
}
}
notification blade file
{{$notification->data['user']['name']}} commmented on
{{$notification>data['postqs']['question']}}
"question" is not present in data['postqs'] array

Categories