Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setPermissionsTeamId() function not preserving team_id when set anywhere but from the middleware #2756

Open
mohamedds-12 opened this issue Nov 7, 2024 · 7 comments

Comments

@mohamedds-12
Copy link

Description

Using teams feature, the docs says that I can set the team_id from anywhere but better from the middleware, I did set up the middleware to set the team id, but in some areas of my code I set the team_id in the controller, but noticed after setting it then checking permissions against the user returns false though he has that permission.
Then I set a breakpoint in the permissions middleware (before setting the team_id) and checked getPermissionsTeamId() found that it returns null, though I have set it in the controller before the redirect.

Steps To Reproduce

...

Example Application

No response

Version of spatie/laravel-permission package:

6.9.0

Version of laravel/framework package:

8

PHP version:

8.1

Database engine and version:

mysql 8

OS: Windows/Mac/Linux version:

10

@parallels999
Copy link
Contributor

I imagine that you forgot to reload the relationships already preloaded after changing the team_id

@mohamedds-12
Copy link
Author

I imagine that you forgot to reload the relationships already preloaded after changing the team_id

Nope, I made sure to reload the new relations after team change, when debugging the user has the permission of accessing the new team is loaded, but when excuting hasPermissionTo() or can(), returns false.

@parallels999
Copy link
Contributor

I made sure to reload the new relations after team change

You should give an code/repo example, everything is working as expected on my side and in the tests.

@drbyte
Copy link
Collaborator

drbyte commented Nov 11, 2024

Yes, it would seem to be an order-of-operations issue, in which wherever you're setting it gets executed in a different timing than how you're expecting it, or has been cleared out/reset by your app.

Example code will be needed in order to provide assistance.

@mohamedds-12
Copy link
Author

mohamedds-12 commented Nov 12, 2024

@drbyte @parallels999 Sorry for not responding earlier,

First the request points to controller method access :

Controller

/**
     *  Access the event's session
     */
    public function access(Request $request, Event $event)
    {
        // Code ....

        $this->teamService->setTeamSession($event);

        return redirect($this->userService->getUserMainRoute($request->user()));
    }

The setTeamSession method sets the new team_id session

TeamService

public function setTeamSession(Organization|Event $teamable): void
    {

        Session::put('team', $teamable->team);

        // Unsetting old loaded relations
        request()->user()->unsetRelation('roles')->unsetRelation('permissions');

        // Spatie's team session
        setPermissionsTeamId($teamable->team->id);

       
    }

then the getUserMainRoute gets the approperiate route for user based on their access permissions, here the user always doesn't have permission to those permissions no matter what, though when I check their loaded list of permission I find that it includes one of those that I'm checking for !!

UserService

/**
     * Get the main route for a given user based on their permissions.
     *
     * @param User $user The user object.
     * @return string The main route for the user.
     */
    public function getUserMainRoute(User $user): string
    {
        $route = null;

        if ($user->can('view-dashboard')) {
            $route = route('backend.event.dashboard');

        } elseif ($user->can('participants.view')) {
            $route = route('backend.event.participants.index');

        } elseif ($user->can('abstracts.view')) {
            $route = route('backend.event.abstracts.index');

        } elseif ($user->can('questions.manage')) {
            $route = route('backend.event.questions.index');
        }

        if (!$route) {
            alert("Vous n'avez pas l'accés", type: 'info')->persistent();
        }

        return $route ?? route('home');
    }
}

Note : But if put a break point on the next redirected route to and check his permissions it works, why cuz the team_id was set from the team permissions middleware.
And if I set a break point in the middleware after I have set the teamPermissionsId in the service, in the middleware it shows the permissionsTeamId it's not set, so it's not perserving it when I set it from the service, but after it gets set from the middleware it preserves it that's why after the redirect the user has the permission to access the route, but before it doesn't as if the team_id is not set.

@parallels999
Copy link
Contributor

so, have you TeamService class and teams middleware?? They are not overlapping in execution, one removes the other changes

@mohamedds-12
Copy link
Author

so, have you TeamService class and teams middleware?? They are not overlapping in execution, one removes the other changes

I think not, tried to remove the middleware and the user always doesn't have permission,

Tried testing in tinker :

  1. Checked user permission -> false :
    User::find(102)->can('participants.view')

  2. set permissions team id :
    > setPermissionsTeamId(37)

  3. Check permissions team id :
    > getPermissionsTeamId() = 37

  4. Listed users permissions via roles, the permission exists :
    [ "participants.create", "participants.edit", "participants.view", "participants.change-type", "participants.confirm-payment", "participants.attach", "participants.cancel-payment", "payment-transactions.view-own", "participation-attestations.manage", "communication-attestations.manage", ]

  5. Checked the permission's role's team_id, same team :
    model_id: 102, role_id: 8, model_type: "App\Models\User", team_id: 37,

  6. Check user's permission again, false :
    User::find(102)->hasPermissionTo('participants.view')

I think when I set the teams permission id it still not taking it in considiration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants