-
-
Notifications
You must be signed in to change notification settings - Fork 90
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
Add option to disable authorization context memoization #217
Comments
All helper methods ( I see several possible solutions to the problem:
@post = authorized_scope(Post.all).find(params[:post_id])
authorization_context[:post] = @post I would prefer the latter one. Adding 1) could be also useful. The 2) doesn't look good to me. |
Thanks for the consideration. I feel like a configuration option may be even better. config.action_policy.memoize_authorization_context = false |
I think, we can proceed with one of the application-level options:
class ApplicationController
def authorization_context
{
user: current_user
}
end
end
class Posts::CommentsController < ApplicationController
def authorization_context
super.merge(post: post)
end
end We already have at least two pure Ruby options, hence adding configuration/API complexity to the library is not necessary. |
Those solutions are fine, and seem to work. I think That behavior was not expected and took awhile to debug, having to dig into the internals of Active Policy to figure out what was going on. I'd expect any changes to the authorization context and its records be reflected in future authorizations. Just curious — is there a particular reason the I looked through the method's history and I see it's always been this way, but I'm kind of curious if there's a reasoning here. To me, it seems like the memoization here wouldn't do much for performance. |
The library was designed with the assumption that the context is defined once and never changes during the execution of a request (or another unit of work). Which doesn't seem to cover all the use cases. "A great abstraction will be used in ways you never anticipated" 🙂 I think, getting rid of the memoization could be added to the v1 backlog. For now, I suggest the following: split the current |
I totally understand that assumption. For my app, sometimes it has intermediary authorization contexts that build up to a final authorization context (i.e. when scoping nested resources), so that assumption doesn't always hold true. I'm fine using the monkey patch for now. No rush. Just wanted to start a discussion. p.s. I really dig this gem! I was on my way to implement a similar system on top of Pundit when I stumbed upon Action Policy. Rather than continue adding abstractions on top of Pundit ( p.p.s. Sponsored the gem on behalf of @keygen-sh. 🙂 |
Sounds great! Please, let me know if you some ideas of what could be great to have in the library itself. P.S. Thanks for sponsoring |
@palkan this actually breaks our builds because we use |
@corroded Oh, that's interesting. Could you provide more details? Sure, we can make |
Should I provide this here or in another issue? Anyway, we have an ActiveSupport concern that includes ActionPolicy::Controller:
module API::Concerns::Authorization
extend ActiveSupport::Concern
include ActionPolicy::Controller
... this is then included in all controllers via: class API::SomeController < ApplicationController
include API::Concerns::Authorization I think the THAT SAID, I can just add it to our ignore file (which I have done). Just thought it would be a good idea to make the method private since it is not a public API? WDYT? Additionally, we also have another failing test that is related to this change that broke: this one that checks if ActiveRecord is being hit 🤔 interesting though as I don't see the specific change affecting this but maybe you might have a clue.
|
Oh, that's bad. Fixed (and added a missing test so I won't break it again 🙂).
Made private. Both released in 0.6.3. |
many thanks! |
Tell us about your environment
Ruby Version: 3.1.2p20
Framework Version (Rails, whatever): 7.0.3.1
Action Policy Version: 0.6.1
Reproduction Script: https://gist.github.com/ezekg/fa8eb565cf9867a288c8f8c699507baf
What did you do?
Calling
authorized_scope
beforeauthorize!
results in a memoized authorization context, so even if the context changes, the changes are not picked up. This is problematic when different policies are used for scoping and authorizing nested resources. A more in-depth example is linked above, but as a quick example:Unintuitively,
authorized_scope
memoizes the authorization context, so the call toauthorize! comments
fails because it doesn't pick up the new:post
authorization context without explicitly providing it viacontext: { post: }
.Having to explicitly provide contexts is cumbersome, and the memoization by
authorized_scope
is rather unexpected and took awhile to debug. As far as I can tell, this behavior byauthorized_scope
isn't documented.The idea here being that we want to respond with a 404 if the current user is not allowed to read the parent record (in this case, a
Post
), rather than a 403. Responding with a 403 leaks information. For example, GitHub responds with a 404, not a 403, when an unauthorized user attempts to access a private repository, even if it exists.What did you expect to happen?
The
authorize!
call to succeed and the:post
authorization context picked up.What actually happened?
The
authorize!
call fails with the following error:What workarounds have you tried?
The following monkey patch resolves the problem:
What do you suggest?
Add an option to disable authorization context memoization.
The text was updated successfully, but these errors were encountered: