luffynando / adonis-lucid-permission

Associate lucid models with roles and permissions
MIT License
5 stars 0 forks source link

FEATURE REQUEST: Support teams #3

Open maukoese opened 5 months ago

maukoese commented 5 months ago

First of all thank you so much for this package, it's been a lifesaver.

It would be great if we could scope permissions to a team/company/organization (basically another model) - by supplying an extra pivot collumn to the table.

Perhaps during configuration we can ask if supports teams, then generate a team_id pivot column.

Also we'd need a way to scope the roles/permissions query to the team.

The application here is to assign users specific roles for the different teams they belong to. I could be the team lead on one team but just a developer on the other; or a manager in one org but simple staff on another.

luffynando commented 5 months ago

Currently you can add the HasAuthorizable, HasRoles, HasPermissions mixin to any Lucid model. To generate the pivot table you can use the command:

node ace permissions:pivot-table my_model_name

After this in your model add pivot table names like this:

//...
import { withAuthorizable } from 'adonis-lucid-permission';

const HasAuthorizable = withAuthorizable({
  rolesPivotTable: '{my_model_name}_has_roles',
  permissionsPivotTable: '{my_model_name}_has_permissions',
});

export default class MyModelName extends compose(BaseModel, HasAuthorizable) {
  // ...
}
maukoese commented 5 months ago

Hi, already did this.

What I'm looking at is having the team logic baked in, the way Spatie permissions package for Laravel does it.

Basically, once the team_id pivot column is added to the pivot table, you can set the value when assigning a role or permission.

So you have something like the following:

const user = await User.create({....})
const team = await Team.findOrFail(1);

// add team id to assignment
await user.assignRole('admin', team.id)
await user.assignPermission('create users', team.id)

Or if this is not possible add a helper function, so we end up with:

await user.syncRoles('admin', 'manager')->forTeam(team //or team.id)
luffynando commented 5 months ago

Ah now I understand, let me review the spatie-permissions code to be able to replicate the same behavior in adonisjs, i will release a new version after i complete

maukoese commented 5 months ago

You can start here https://spatie.be/docs/laravel-permission/v6/basic-usage/teams-permissions

Perhaps we can have a prompt during configure to ask if support teams, if yes ask for team_id column name, then if set when you generate the migration add the column. To maintain backward compatibility, we can have separate assignTeamRole and assignTeamPermission functions

So we have something like:

const user = await User.create({....})
const team = await Team.findOrFail(1);

// add team id to assignment
await user.assignTeamRole('admin', team.id)
await user.assignTeamPermission('create users', team.id)
luffynando commented 5 months ago

I think in the end it will be a major change, given that not only the teams part but also some other features are not right, I suppose that the base of verful/permissions is based on spatie v4, which is two versions behind the current one. @maukoese

osendev commented 5 months ago

Yes, but we can still be backward-compatible by making the fields optional and opt-in, so people who don't need teams can keep using the module as before without changing a thing.

The team_id collumn is set to null by default (.nullable()) and we have a 'use_teams' key in config which determines if teams middleware or rules are applied.

It doesn't have to be a breaking change. Let me know if I can help.