Laravel 4 - Reuse controllers and views using routes - laravel

I'm building a blog application with Laravel 4 which has two types of users, the administrator and the regular user.
When users create their accounts or when they log in all of their routes have the "user" prefix , like this:
GET user/posts = PostsController#index
For administrators all of their routes have the "admin" prefix , like so:
GET admin/users = UsersController#index
To view all the posts from a user as an administrator I do this:
GET admin/users/($id)/posts = PostsController#index
So if a regular user is logged then I get his ID from session, but if the user is an administrator then I get the regular user ID from the url.
I also have to update the links inside the views, like this:
As a regular user: link_to("user/posts/create", "Create Post")
As an administrator: link_to("admin/users/1/posts/create", "Create Post")
Is there a better approach this?

Yeah, all users are users.
Anything that requires you to be an administrator should have a filter for that on the route.
So for example, if an administrator was only allowed to go to user/posts/delete/{id}, that route would look something like...
Route::post('user/posts/delete/{id}', array('before' => 'adminFilter', 'uses' => 'PostController#deletePost');
I'm not sure how you figure out if a user is an admin or regular user, but your filter could look something like...
Route::filter('adminFilter', function()
{
if (!Auth::user()->isAdmin())
{
return Redirect::to('home')->with('message', 'You aren't an admin!');
}
});
And you would simply put an isAdmin() function in your User model which describes how to tell if a user is admin and returns true or false.

Related

Laravel Nova show Dashboard based on Role

Within my users Table I have different roles. I have two different Dashboards and want to show the Dashboard based on thier roles. But I dont understand how the canSeeWhen method from laravel works?
https://nova.laravel.com/docs/4.0/customization/dashboards.html#defining-dashboards
Lets say I have the roles Admin and editor and trader.
I have the Admin Dashboard, this should be available for the admins and editors and I have the trader dashboard, this should be available for the traders.
You have multiple options, you can use the canSee method and the canSeeWhen method.
The canSee method accepts a callback and based on the return true or false it will show the dashboard.
example:
public function dashboards()
{
return [
.....
ExampleDashboard::make()->canSee(function ($request) {
return $request->user()->role == 'admin'
}),
];
}
In the above example, when the user role property is equal to 'admin' they see the dashboard.
When using the canSeeWhen it actually uses the policy system from laravel, maybe you are making a dashboard based on all user data then you want to know that the user that is viewing the data is also authorized to viewany user.
Then you could do something like this:
public function dashboards()
{
return [
...
ExampleDashboard::make()->canSeeWhen('viewAny', \App\Models\User::class),
];
}
Read more about the policies

Getting all Sentinel user related to roles

How can I get all users related to user roles by Sentinel? And how can I get all users in Sentinel? This does not work:
Sentinel::all()
You can try this to get all users related to a specific role.
$role = Sentinel::findRoleById(1);
// or findRoleBySlug('admin'); for example
$users = $role->users()->with('roles')->get();
and you can access the first user (and so on and so forth like this)
dd($users[0]['attributes']);
and to get all users you can do this:
$test = Sentinel::getUserRepository();
dd($test);

Workflow of role/permission based content filtering using Entrust Laravel

I am using laravel 5 and added Entrust for roles and permissions.
I don't know how to use the permissions. If I have a permission create-post means what will it do?
create option in the Post controller will be permit? Or we need to assign a permission name to the page?
Please suggest an example. Even I don't know where to check permissions...
The workflow of Entrust is as follows
Create roles
Role::create(['name' => $role]);
e.g admin, reader etc
Create permissions
Permission::create($permission);
e.g can_read_post, can_edit_post, can_delete_post
Assign permissions to roles
$role = Role::where('admin)->first();
$role->perms()->sync($ids); //here the ids are ids of permissons which you want to assign
e.g admin has permissions (can_read_post, ca_edit_post, can_delete_post) and reader has permissions (ca_read_post)
Assign roles to users
You can assign a role to many users.
$user->roles()->attach($roleId);
Filter content based on Role or Permission
The basic setup has been completed. Now you can filter the content of your website using different methods. Here I will discuss a few
Define a filter in filters.php and apply on route
filters.php
Route::filter('admin', function()
{
if(!Entrust::hasRole('Administrator'))
{
return Redirect::to('/');
}
});
routes.php
Route::group(['before' => ['admin']], function(){
//add some routes which will require admin role
//any user which has not admin role will be redirected to home page
}
In your views
#if(Entrust::can('can_edit_post'))
//add some html which will only be visible to users who has such a role which has this permission
#endif
In your controllers/models/repos
Similarly you can filter content in models/controllers/repos etc.
So I guess you have got the basic idea. Now you can use Entrust functions almost anywhere. Hope this helps.
Briefly what we need to done to implement Entrust Laravel Package for role based permission is as below.
Install the package as per per the instructions given in
https://github.com/Zizaco/entrust
After all, done with the above Package(GitHub) like database table creation, Middleware, Controllers and all.
When a user login in the system, then there is an array provided by Auth, that contains all the actions user can (actions ability logged in user can) take.
Let a suppose we have a Controller named as CategoryController as below.
class CategoryController extends Controller
{
public function __construct()
{
$this->middleware('permission:category_index', ['only' => ['index']]);
$this->middleware('permission:category_create', ['only' => ['create', 'store']]);
$this->middleware('permission:category_edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:category_delete', ['only' => ['delete']]);
$this->middleware('permission:category_view', ['only' => ['show']]);
}
}
We generally have 5 actions in a Controller, If we have a single route (called as resource route) in our routers/web.php file for all CRUD actions of single controller.
In this example, suppose we have all these 5 methods. So we also have entry in permission for these in permission table.. like I have
Permission Table
id display_name name
5 Delete Category category_delete
4 Edit Category category_edit
3 Create Category category_create
2 List Category category_index
We just need to add these permission names in our controllers as I have done in the CategoryController, If you use hyphon in permission table's name filed, then use like
$this->middleware('permission:category-create', ['only' => ['create', 'store']]);
Write all permissions in the controller constructor.
that' it!!
It will automatically check the logged-in user ability and according to the database entry in permission_role (relation table of role and permission), It will either show the page or access denied for that user.
Hope this works !!

In sailsjs / passport.js: How to get logged in user as object in a view?

I want to output the Username in a view, so I need to get the user object.
In
req.session.passport.user
there is only the user id (numeric), and
req.user
is undefined. Isn't use user stored as object in the session?
You should have something like this somewhere (in the connect & register function of service/protocols/local.js if you used sails-generate-auth)
Passport.create({
protocol : 'local'
, password : password
, user : user.id
}, function (err, passport) {
...
So just add the username here
You need to configure your policy.
I got this working by making a change in APP_ROOT/config/policies.js
UserController: {
me: ['passport']
},
HomeController: {
'*': ['passport']
}
After this for all views under User and Home controller can access user object.
Example:
<p>Hi <%=res.locals.user.username%></p>

How to forward argument for redirect::route->with when hitting an auth filter using Laravel?

I have the following problem:
After a user is created and the user has confirmed her email.
I would like the user to login,
I use the following code to do that:
Redirect::route('login-forward')->with('alert_message', ...)
the alert messages simply states that everything went well, and I would like her to login.
login-forward is protected with an before filter, that runs the actual login form,
When the user then logs in sucesfully, she is brought back to login-forward, whic then puts the user at her personal landing page.
the code for the route 'login-forward is:
Route::get('my-login', array(
'as' => 'login-forward',
'before' => 'auth',
function ()
{
$user = Auth::user();
switch ($user->role)
{
case 'Administrator':
return Redirect::route('admin_dashboard');
case 'FreeUser':
return Redirect::route('cs-dashboard');
default:
return Redirect::route('/');
}}));
the problem is, the ->with('alert_message',...) is not seen by the real login route called by the before filter.
How do I solve this?
The best approach is to let the user logs in automatically when the email is confirmed, if the user confirms the account creation then when you find that user is valid then you may log in that user using something like:
// $user = Get the user object
Auth::login($user);
Also you may use:
Session::put('alert_message', ...);
Redirect::route('login-forward');
Then when the user logs in for the first time, just get the message from Session using:
// Get and show the alert_message
// from session and forget it
#if (Session::has('alert_message'))
{{ Session::pull('alert_message') }}
#endif
So, when you pull the message from the Session to show it, the message will no longer be available in the Session or you may use Session::reflash() to flash the flashed session data for another subsequent request until you get in the page where you want to show the message.
The best choice is - you can make forward to login form without redirect from method of controller for url of personal page.
return Route::dispatch(Request::create('login'))->getOriginalContent();

Resources