I have the below auth guards that is defined for my app admins, designers, customers and etc. the default guard is the designer guard.
I want every guard to have his own private channel.
So I am defining it in my channel.php with multiple entries for each like below
Broadcast::channel('private.admins.{id}', function ($admin, $id) {
Log::info($admin);
//logging the admin
});
But this is always binding with default guard class so my question is how do I tell that to use here Admin model.
I am unable to find it anywhere. So can you point me in to right direction
Actually I want every guard to have his own private channel.
Try changing in BroadcastServiceProvider file app\Providers\BroadcastServiceProvider.php
Different broadcast auth end point for each guards
public function boot()
{
//Broadcast::routes();
//match any of the 3 auth guards
Broadcast::routes(['middleware' => ['web','auth:admins,designers,customers']]);
require base_path('routes/channels.php');
}
Now in channels.php
Broadcast::channel('admins.channel.{id}', function ($model, $id) {
return $model->id === $id && get_class($model) === 'App\Admin';
});
Broadcast::channel('designers.channel.{id}', function ($model, $id) {
return $model->id === $id && get_class($model) === 'App\Designer';
});
Broadcast::channel('customers.channel.{id}', function ($model, $id) {
return $model->id === $id && get_class($model) === 'App\Customer';
});
I am Posting this answer, For every one who might face the problem no-days. I am using laravel 7 and beyondcode/laravel-websockets. As I dig in the source code specifying midllewares in BoradcastServiceProvider.php will not work. The only way to define a guard for a channel is by specifying options for the channel:
Broadcast::channel('messaging.organ.{id}', function ($organ , $id) {
return $organ->id == $id && get_class($organ) === "App\Organization";
} , ['guards' => ['organ']]);
Reason:
because I am using beyondcode/laravel-websockets so I dig in src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php and in this file the retrieveUser method will get the user. in this file if an option for the channel is provided the user in the specified guards will be returned. you can define one or multiple guards, however it will only returns one user who is logged in as a guard that comes first in the array.
protected function retrieveUser($request, $channel)
{
$options = $this->retrieveChannelOptions($channel);
$guards = $options['guards'] ?? null;
if (is_null($guards)) {
return $request->user();
}
foreach (Arr::wrap($guards) as $guard) {
if ($user = $request->user($guard)) {
return $user;
}
}
}
Related
I actually am not able to understand why I am getting the following error.
App\Models\User::team must return a relationship instance, but "null" was returned. Was the "return" keyword used?
I am basically creating test cases for simple orders for ecommerce.
User Modal
public function team(): BelongsTo|null
{
if (!empty($this->team_id)) {
return $this->belongsTo(Team::class);
}
return null;
}
Test case
public function test_order_status_update()
{
$order = $this->create_order($this->books->id, $this->appUser->id, $this->address->id);
$response = $this->actingAs($this->user)->put('orders/' . $order->json('order.id'), [
'order_status' => 'ordered',
]);
$response->assertRedirect('orders/' . $order->json('order.id'))->assertSessionHas('success');
}
In addition, I have another feature in my application called pages access control, which controls page access for multiple users (admin, developer, and users).
I have implemented this feature manually using middleware.
Middlware.php
public function handle(Request $request, Closure $next)
{
//teams 1-Developer 2-Admin 3-Management 4-Marketing 5-Audit 6-Sales 7-Bookstores 8-Delivery 9-User
$team = $request->user()->team;
if ($team->id == 1 || $team->id == 2) {
return $next($request);
}
$pages = auth()->user()->pages->merge(auth()->user()->team->pages);
$currentRouteName = $request->route()->getName();
$pages->contains('route_name', $currentRouteName) ?: abort(403);
return $next($request);
}
Based on the error above, I believe the actingAs function is unable to obtain authenticated user information, which is why my test failed.
How can I fix this?
Simply don't check your team_id:
public function team(): BelongsTo
{
return $this->belongsTo(Team::class);
}
Laravel tries to be smart. If team_id isn't set, it will just return null. However, if you don't return the BelongsTo, the magic code of Laravel will trip when you try to access user->team
I want to make a middleware to protect admin routes in laravel 5.2 app.
user_type isn't a field in users table in my db, but in a separate table :
Admin's user_type_id is 4
I made this middleware :
class AdminMiddleware
{
public function handle($request, Closure $next)
{
$authedUserID = Auth::id();
$user = User::query()
->leftjoin('users_user_types as uut', 'uut.user_id', '=', 'users.id')
->where('uut.user_id',"=","$authedUserID")
->get(['users.*',
'uut.user_type_id as userType'])->first();
if ($user['userType'] !=4)
{
return redirect('/home');
}
return $next($request);
}
}
and put this in $routeMiddleware array in kernel.php :
'admin' => \App\Http\Middleware\AdminMiddleware::class
and this is one of admin routes I want to apply my middleware on :
Route::get('ptyadmin', 'AdminController#show')->middleware('admin');
The Problem is that when I go to this route with admin user(user_type = 4) or normal user(user_type = 1) it redirects to /home in both cases !!
Why does this happen and how can I fix it ??
first method returns object
if ($user->userType !=4)
Also use selectinstead get
->select(['users.*','uut.user_type_id as userType'])->first();
It works when I put jwt.auth middleware in routes.php :
Route::get('ptyadmin', 'AdminController#show')
->middleware('jwt.auth')
->middleware('admin');
instead of putting it in AdminController :
public function __construct(User $user, JWTAuth $jwtauth)
{
$this->middleware('jwt.auth', ['except' => []]);
}
So I have created a policy and registered it in the AuthServicePRovider, but it always returns false. It is my first time working with policies so I am sure I am doing it wrong, but following a few examples, nothing has worked for me.
I am logged in with user that has an id of 1. I try to edit a label that has a user_id of 1, returns false, and also when trying to edit a label that has a user_id of 2. This last one works as expected, but f the user_id and label->user_id match, I should ave a form displayed. Instead, I get this each time:
This action is unauthorized.
Any ideas?
AuthServiceProvider: (Tried both but both don't work):
protected $policies = [
'App\Label' => 'App\Policies\LabelPolicy'
];
And this one also did not do the trick:
protected $policies = [
Label::class => LabelPolicy::class
];
LabelsController#edit:
public function edit(Label $label)
{
// $this->authorize('edit', $label); // This also returns false
if (auth()->user()->cannot('edit', $label)) {
dd('NO'); // This is always shown
}
}
LabelPolicy:
public function edit(Label $label)
{
dd('test'); // This is never shown anywhere
return auth()->user()->id === $label->user_id;
}
The policies expects actually two inputs, the first input is always the User class, the second input is the Model and defaults to the Model class. So in your case:
LabelPolicy
public function edit(User $user, Label $label)
{
return $user->id === $label->user_id;
}
LabelsController#edit:
public function edit(Label $label)
{
$this->authorize($label);
}
if your $this->authorize inside Controllers always returns false, then double check if your model and model policy namespace was imported in AuthServiceProvider and also your model has been imported into your controller.
I need to restrict the access to some parts of the application depending on the user logged in. I mean for example to let a user edit only its own posts on a blog application.
Is there a better approach than in every function of the controller, if the user is not the owner of the required post, redirect to some error page?
For example if my routes are /post/{post_id}/edit, /post/{post_id}/preview, /post/{post_id}/delete, can I somehow declare a general function in the PostController like:
if(Post::find($post_id)->user_id != Auth::user()->id){
return View::make('access-error');
}
Thanks!
In your controller you can do something like this:
public $check = ['edit', 'preview', 'delete'];
public function callAction($method, $parameters) {
if(in_array($method, $this->check, true) &&
$post_id = $parameters['post_id'] &&
Post::find($post_id)->user_id != Auth::user()->id) {
return View::make('access-error');
}
return parent::callAction($method, $parameters);
}
You could throw a 401 error and catch it elsewhere to display a custom page
App::abort(401);
http://laravel.com/docs/4.2/errors#handling-404-errors
What I basically want is user permissions.
I've got an table called 'accounts' in my database. There is a column called 'group_id'.
I want to set it when the 'group_id' = 3, then the user is admin. Then he can view special sites, buttons, and things like that. I've tried to implement something like that:
public function ($roleName) {
$role = $this->roles;
if ($role->name == $roleName) {
return true;
}
return false;
}
Also, I don't know what and how the model is needed, do I need an new one and things like that.
Old post, but maybe someone will find this useful
Add a method to your User model that returns true if the user is an admin. In our case here, it's simply "is our group_id equal to 3?"
// models/User.php
class User extends Eloquent
{
...
public function isAdmin()
{
return $this->group_id == 3;
}
}
Next add a filter that can be used to protect routes
// filters.php
Route::filter('admin', function($route, $request)
{
if ( ! Auth::user()->isAdmin())
{
return App::abort(401, 'You are not authorized.');
}
});
Finally use the filter to protect a group of routes. I this simplified case, only an admin user could access /admin
// routes.php
Route::group(array('before' => array('auth|admin')), function()
{
Route::get('/admin', function()
{
return Response::make("You're an admin!");
}
});
Based on this post:
http://laravelsnippets.com/snippets/admin-route-filter
I suggest Authority for Laravel 4
I personally use Verify package for user management.