I have a proof-of-concept app that does the following:
- In AuthTest::Schema it preloads authentication rules into an object var.
- In AuthTest::Model::DB uses WithCurrentUser trait to have the current user set on the schema object with every web request.
- On every DB query, it checks (by subclassing ResultSet) whether the current user is allowed to perform the requested action.
- In controller code, I also explicitly call
$user->isAccessAllowed()
(which chains to the internal access control check class AuthorizationResolver).
The problem is: some DB objects in the app seem to have been created via the Schema with WithCurrentUser not initialized, and some with it initialized. E.g. the $c->user
itself seems to have been created via the Schema without the trait WithCurrentUser.
I.e. when I call $user->isAccessAllowed()
, which in turn calls AuthorizationResolver with $user->result_source->schema
, this schema has current_user set to undef
. On the other hand, when AuthorizationResolver is called from within ResultSet that I have just created from $c->model('DB::Author')
, current_user
in the schema is correctly set to the current user.
I.e., it seems that the user object is created (by $c->find_user
or restored from session) from the old copy of schema that doesn't contain the WithCurrentUser trait. While any new calls to $c->model()
create objects from the new clone.
I work this around currently by explicitly supplying the AuthorizationResolver with the user object when $user->isAllowedAccess()
is called, but clearly the whole thing may break at another place when there are two copies of the Schema object.
Ideas welcome.