-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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 caching? helper method #42365
Add caching? helper method #42365
Conversation
I've been thinking about this PR and I'm not entirely convinced it's necessary or useful to other apps. If the problem is that we don't want to cache sensitive data then we shouldn't add caching blocks for that. Am I missing a piece of how this is used that results in sensitive data getting cached accidentally? The code author would still need to know what data is considered sensitive and need to know to raise if there was sensitive data they didn't want cached. |
I think one of the problem is that something people don't know they are inside a cached template/partial but this would still be true even if we add this method. People would still accidentally add sensitive data inside cached blocks. This helper only makes easy to opt-out of the cache fragment and instead of having two different templates for a cached partial and an uncached partial, you only have one. I'm not sure it is worth a fiber-local. |
@eileencodes @rafaelfranca thanks for taking the time to review. I'll provide a more detailed example to explain why I think this feature is generally useful. We have a custom form helper (let's call it # Build a button that is a form
#
# Returns an HTML String.
def button_form(name, options = {}, html_options = {})
# Ensure that we aren't caching CSRF tokens.
raise NoCachingError if caching?
# build the form, including CSRF tokens
end At least in our application, it can be difficult to reason about the render stack to be certain that a given line of code won't execute inside a |
We don't use much fragment cache for me to care about this solution, but if others think it is fine it is ok to me. About the implementation, I'd prefer if we add a Runtime Registry in Action View using |
Could also consider adding an |
b5d9a54
to
b4429f0
Compare
@rafaelfranca @kaspth thanks for the reviews. I rewrote this PR to use @kaspth what do you think about having both |
@kaspth friendly bump 😄 |
Sorry I wasn't clear, I meant that we'd have both yeah. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet, getting there!
Let's just define the CachingRegistry
inline in CacheHelper
right below the private
marker. It doesn't warrant being a top-level file at the action_view/lib/*
root.
# frozen_string_literal: true | ||
|
||
module ActionView | ||
# = Action View Caching registry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this comment when the registry is nodoc'ed?
ce8fcd9
to
faf1aa2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the changelog entry just needs to be moved and then we could ship this now — we can also tackle the uncachable!
method here if you'd want.
3a14362
to
e920dec
Compare
Caching something that shouldn't be cached is a potential source of bugs and security vulnerabilities. For example, one could write a form helper that outputs a request-specific auth token, only for the helper to be used inside of a `cache` block. In the GitHub application, we implemented a caching? method and used it to raise an error if a specific code path is being cached that we don't want to be cached. I've credited its original author, @btoews. Co-authored-by: Ben Toews <mastahyeti@gmail.com> Co-authored-by: John Hawthorn <jhawthorn@github.com> Co-authored-by: Kasper Timm Hansen <kaspth@gmail.com>
e920dec
to
fd5792f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rad!
@@ -0,0 +1,3 @@ | |||
<%= cache "uhoh" do %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uhoh indeed, love it 😂
I know it was marked as a draft PR, but I couldn't see anything else that was missing, so I went ahead. If that was erroneous, I'll be around so we can tackle it in a follow up PR. Thanks for working on this, I'm really happy with how it turned out! ❤️ |
@kaspth Ha! I was just waiting for CI to pass before moving it out of draft. Thanks for your help landing this PR, I really appreciate your thoughtful feedback ❤️ |
Problem
Caching something that shouldn't be cached is a potential source of bugs and security vulnerabilities. For example, one could write a form helper that outputs a request-specific auth token, only for the helper to be used inside of a
cache
block.Proposed solution
In the GitHub application, we implemented a caching? method and used it to raise an error if a specific code path is being cached that we don't want to be cached.
I've credited its original author, @btoews.
Co-authored-by: Ben Toews mastahyeti@gmail.com
Co-authored-by: John Hawthorn jhawthorn@github.com