juanborras's avatar

Jetstream Teams spatie/laravel-permissions

Dear All

I'm kind of lost here. I'm developing a teacher management system with filament. There are the management team, the teacher team and a few others... can each team has its own roles?? What would you recommend?

Thank you very much for your time Juan

0 likes
5 replies
LaryAI's avatar
Level 58

Certainly, Juan! You can achieve this by combining Laravel Jetstream's team functionality with Spatie's Laravel Permissions package. Here's a step-by-step guide to help you set up roles and permissions for each team:

Step 1: Install Spatie Laravel Permissions

First, you need to install the Spatie Laravel Permissions package if you haven't already.

composer require spatie/laravel-permission

Then, publish the configuration file and run the migrations:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate

Step 2: Set Up Models

Ensure your User and Team models use the HasRoles trait provided by Spatie.

// app/Models/User.php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // Other model methods and properties
}

Step 3: Define Roles and Permissions

You can define roles and permissions in a seeder or directly in your code. For example, you might have roles like teacher, management, etc.

// database/seeders/RolesAndPermissionsSeeder.php
namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

class RolesAndPermissionsSeeder extends Seeder
{
    public function run()
    {
        // Create permissions
        Permission::create(['name' => 'manage team']);
        Permission::create(['name' => 'teach class']);

        // Create roles and assign existing permissions
        $role = Role::create(['name' => 'management']);
        $role->givePermissionTo('manage team');

        $role = Role::create(['name' => 'teacher']);
        $role->givePermissionTo('teach class');
    }
}

Run the seeder:

php artisan db:seed --class=RolesAndPermissionsSeeder

Step 4: Assign Roles to Users in Teams

You can assign roles to users within the context of a team. This can be done in your controllers or services.

// ExampleController.php
use App\Models\User;
use App\Models\Team;
use Spatie\Permission\Models\Role;

class ExampleController extends Controller
{
    public function assignRoleToUserInTeam(User $user, Team $team, $roleName)
    {
        // Ensure the user is part of the team
        if ($user->belongsToTeam($team)) {
            // Assign the role within the team context
            $user->assignRole($roleName, $team);
        }
    }
}

Step 5: Check Permissions

When checking permissions, you can specify the team context.

// In a controller or middleware
if ($user->hasPermissionTo('manage team', $team)) {
    // The user has the permission within the specified team
}

Conclusion

By following these steps, you can set up a system where each team has its own roles and permissions. This allows for a flexible and scalable permission system tailored to your teacher management application.

Feel free to ask if you have any further questions or need additional clarification!

Snapey's avatar

Sounds like you just described distinct roles.

1 like
juanborras's avatar

@Snapey Yeah... sounds like it... it is more a role description than a teams thing... I look into it...

Thanks!!

MotionPhix's avatar

@juanborras Let's assume you have control over teams creation (I mean you create the teams yourself, not Jetstream at registration of any new user) you can do it in two ways: each will still need you to enable the teams feature in config/permissions.php.

// config/permission.php 'teams' => true,

The you have to work out a way for your application to know which team is the currently logged in-user on. (It's a bit frustrating if a user can belong to multiple teams, that way you also have to work out a way of switching the user to the team they want to view by then — but Jetstream already has this functionality, so you'll have to add a code for Spatie to be aware that you have switched to a different team). The recommended way is via a middleware (or you could possibly send the currently active team to a session, like:

session(['team_id' => $team->team_id]); // it will still work and spatie will pick it up from there

With a middleware you would do something like:

namespace App\Http\Middleware;

class TeamsPermission {

public function handle($request, \Closure $next){
    if(!empty(auth()->user())){
        // session value set on login
        setPermissionsTeamId(session('team_id'));
    }
    return $next($request);
}

}

Now, the roles will be team-dependent: Instead of Role::craete('role name'), you now have to specify a team that this role will apply to. So something like:

Role::create(['name' => 'management', 'team_id' => 1]);

Or if you want to create a role that will be available globally (not bound to a team) you would do something like:

Role::create(['name' => 'teacher', 'team_id' => null]);

And assigning roles and permissions to a user no-longer works. Users inherit the role and permissions applied to a team they are in. You can't do:

$teacher->assignRole('teach-class'): It will not work....You have to give that teach-class permission to the teacher/teach role: Like

$teacherRole = Role::create(['name' => 'teacher', 'team_id' => 1]); $permissions = ['teach-class'];

foreach ($permissions as $permission) { Permission::firstOrCreate(['name' => $permission, $team_id => 1]); }

$teacherRole->syncPermissions(['teach-class']);

Something like that.

In Providers/JetstreamServiceProvider.php, you have to add the roles and permissions you have added with Spatie, so that you can be able to assign roles to users from the interface. Somehting like:

Jetstream::role('techer', 'Teacher', [ 'teach-class-a', 'host-a-meeting', 'grade-students', ])->description('Will be teaching class A only, among other things');

2 likes

Please or to participate in this conversation.