Roles and permissions issues in laravel project - laravel-5

I am working on a laravel project. I have a side menu that is persistent across all pages. However the menu items to be shown is dependent on the role assigned to the user. I achieved that by doing this:
<?php
/**$links = Session::get('links'); **/
use Illuminate\Support\Facades\DB;
$id_hr_employee= Auth::user()->id_hr_employee;
$links = DB::select("select a.link as links from sys_menu_links as a a.id_hr_employee = $id_hr_employee)
");
?>
#if(isset($links))
#foreach($links as $link)
<li><hr class="light-grey-hr mb-10"/></li>
#include("$link->links")
#endforeach
#endif
This works quite alright. However, if someone enters a route to a menu (that he is not assigned to) on the address bar, he sees that page.
Please how do I prevent this?

i would highly recommend you using laratrust: https://laratrust.readthedocs.io/en/4.0/.
And to secure your sides: 1.option work with middelware to Block your admin views 2. Option Check for permission in the Controller files.
As a guidance you could look up this tutorial: http://itsolutionstuff.com/post/laravel-52-user-acl-roles-and-permissions-with-middleware-using-entrust-from-scratch-tutorialexample.html
greetings

Related

Laravel 8: How to share a PHP variable with different pages (using same layout) and components?

I am working on this web app (Laravel 8) in which users can choose their color themes. Basically, to make it simple, let's say each user can choose their primary_color.
On home page (which does not need authentication), the primary_color will come from config (whether user is authenticated or not). On authenticated pages, the primary_color comes from the users table (for the authenticated user). I also have a bunch of pages that use the guest layout if user is not authenticated, and the app layout if user is authenticated. Those would use the primary_color from config if user is not authenticated, and the primary_color chosen by the user if they are authenticated.
All those pages use some components (buttons, nav-links, etc) that need to know the primary_color.
I currently have this line on top of EACH php file that needs to know the primary_color:
$primary_color = (Auth::user() && Route::current()->getName() !== 'home') ? Auth::user()->config->color_theme : "yellow";
(Color "yellow" is hard coded here, just ignore it.)
I would love to avoid that much code replication, but i can't seem to find a way to share this variable from the layout (guest.blade.php or app.blade.php) to the page. I can't seem to be able to include a style.blade.php view that contains the variable, either. The variables declared in this included view do not exist in the rest of the page. I managed to pass the variable to components using a prop. It's not so nice, but it works fine. But it's not so nice, i'd rather use a cleaner solution.
But most importantly, how do i avoid having to copy the same bit of code on top of each page?
Thank you!
You can use view composers. Under the boot method of AppServiceProvider add the folowing code.
\Illuminate\Support\Facades\View::composer('*',function($view){
$userPrimaryColor = (Auth::user() && ! Route::is('home')) ? Auth::user()->config->color_theme : "yellow";
$view->with('primary_color', $userPrimaryColor);
});
The first argument * indicates that it needs to be shared to all the views. If you need those in few pages you can pass the list of pages as array
If you want to share data with all the views you can use laravel's view composer.
it can attach data to all view or multiple views simultaneously.
source: https://laravel.com/docs/5.0/views#view-composers
alternately: see here
https://www.digitalocean.com/community/tutorials/sharing-data-between-views-using-laravel-view-composers

Centralize user role verification in laravel

I'm working on an e-commerce website and i need to display certain data based on the user role. Basically the page can be viewed by three types of people: normal people who enters the page and by a client user or an admin who have their accounts but they see different buttons/data according to their role.
I'm working with jetstream authenticaton system and what i do is simply verify the user role on my views like this:
#if (Auth::user()->role->name == 'admin')
//display button only the admin can see
#else
//display button only a client user can see
#endif
My question is, can i implement something like a gate to centralize the condition?, i mean, in case i need to change it only doing it in one file and avoid to do it in all the lines where i implented it.
Any help is welcome. Thanks!
Yes. Just define gates or use a model policy. Using gates, you can do something like (using a Post model as an example):
Gate::define('edit-post', function (User $user, Post $post) {
return $user->role->name == 'admin' || $user->id == $post->user_id;
});
Gate::define('delete-post', function (User $user, Post $post) {
return $user->role->name == 'admin';
});
And use it in your .blade.php files using the #can blade directives.
#can('edit-post')
// show an edit button
#endcan
#can('delete-post')
// show a delete button
#endcan
Here we are basically creating two controls for editing and deleting a post. To edit a post (or rather see the edit button), you either have to be an admin or the user must have created the post. To delete it, you have to be an admin.
References: Laravel Documentation on Authorization

Assign a non-registered user to a user group (under a generic user) with a button click

I have three buttons: Member (of the organisation, not site), Former Member and Companies.
I would like to change the group of the non-registered guest on the site to the group which they click on. In other words, with one button click log the guest into (a random/pre-made account in) a certain group. I do not want to make them have to log in manually in order to assign them to a certain group.
However, I am unsure how to approach this problem. Could anyone give me some pointers?
I dont think you should mix joomla user groups into this mix, it does not really make sense as long as you do not actually intend to log in your users with user and password. If your question is how to present different content to users based on which button they click, here is how I would approach the problem:
In your template, in the index.php - file, check to get the type of user:
<?php
$app=JFactory::getApplication();
$membertype=$app->getUserStateFromRequest('com_content.membertype',
'membertype','member');
?>
Make your three buttons links like this: index.php?membertype=member , index.php?membertype=former , index.php?membertype=companies
( You can have the links point directly to the start menu item for the different member types, just remember to add the membertype= - for the different types. )
Now, also in the template index.php, load menu modules depending on the member type:
<?php
switch($membertype){
case 'member':
case 'former':
case 'companies':
?>
<jdoc:include type="modules" name="membermenu_<?php echo $membertype; ?>"
style="xhtml" />
<?php
break;
}
?>
You can load other modules this way, depending on how much of your content should differ depending on the member type.
In templatedetails.xml, you can add the new module-positions membermenu_member, membermenu_former, membermenu_companies in the positions-section. This will allow you to select the dynamic module positions from the module administration area.
Finally make different menus for the different menu types, and display the menus in different menu modules and module-positions as described above.
regards Jonas

Zend_Acl For Specific Parts Of The Page

I know how to use Zend_Acl to allow certain resources to certain usergroups but how do i use it to allow only specific parts of the page to be shown? For example
I have a button to delete a post via AJAX on the page but i only want to show the button to Admins only. I can use Zend_Acl to block access to the controller post/delete but i can't use it to block the button from showing.
// in controller
$this->view->allow_delete_post = $acl->isAllowed($role, 'delete_post');
.
// in template
<? if ($this->allow_delete_post): ?>[button html]<? endif; ?>
Would that not do it?
You can also write a custom static ACL class which you can then call directly from within your view script.
Since ACL is normally handled at plugin level it means that if your visitor is seeing the view then ACL has already allowed the resource, therefor inside your view you can now do something like this...
if(My_Custom_Acl::getIsAllowed('some_resource', 'delete_post_action'){
I did not specify the role name in the custom getIsAllowed() method, because at this point ACL is already suppose to know the user's Identity and the Role.
Hope this helps
Although Christof gave a good solution, an alternative is to split the views. Although this starts to violate DRY, when you have about 200 different admin things/controls, it's getting heavy in the view - thus splitting the view with $this->render('view') and $this->render('edit') for permissions from the controller is sometimes easier. Then only the edit view script has the edit links. But again, it's DRY, so not optimal, but an alternative. I guess you have to weigh it up, which one is more DRY, repeating the ACL check or the stuff in 2 views...

How do you configure Codeigniter routing to ignore a specific segment string in the url

I'm not sure I'm going down the right path with this - and I am pretty new to routing, so if this is way off base, I apologize.
What I'm trying to accomplish is having a link at the bottom of the page where the site visitor can select mobile or full screen. I want them to be able to do this from any page. When they select either one, there could be any number of things happen - depending on where they are on the site (i.e. different views, functionality, etc).
Right now, I don't have Codeigniter configured to allow querystrings, which is the default behavior. So in order to pass a preference in a link, I need to do it using a url segment.
I was hoping to do something like:
<? if ($in_mobile_view): ?>
Mobile | Full Site
<? else: ?>
Mobile | Full Site
<? endif ?>
This works great when I am navigating to: /welcome/index/m or /calendar/view/m, etc. However, if I'm just at: /welcome/m or /m - where the index method of the controller should kick in, I get a 404 because it can't find the method - since it doesn't exist.
My thought was that via routing, I could configure Codeigniter to ignore the "m" and "f" strings and just operate as if they aren't in the url at all.
Is that a good way to go about this? If not, I'd love to hear other suggestions. If this is a decent way to go, I'd really appreciate if someone could point me in the right direction for routing.
Thanks for your time.
Why select this with the URL?
You can detect basic "is mobile" with the User Agent library. Take that value and set the session to whichever the User Agent suggests, then simply link to a controller that switches the user between mobile and full versions when clicked.
Run this in global code somewhere as a hook or a Base Controller.
if($this->user_agent->is_mobile() && ! $this->session->userdata('site_mode'))
{
$this->session->set_userdata('site_mode', $this->user_agent->is_mobile() ? 'mobile' : 'full');
}
Then you controller can just set the session to whatever based on what they have clicked.
/switch/mobile
/switch/full

Resources