-
Notifications
You must be signed in to change notification settings - Fork 22k
Active Storage - Direct Upload Validation #41178
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
Conversation
921fb6e
to
892f685
Compare
return true if klass_name.nil? | ||
return true unless defined?(ActiveRecord::Base) | ||
|
||
model = ActiveRecord::Base.const_get(klass_name) rescue nil |
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.
I don't love this, but can't think of a safer way to get the model here.
Hey @ghiculescu, See here how to setup the commit(s) with co-authoring. In your case, that would mean adding: |
@louim done - thanks! |
2e99dda
to
c1a0e81
Compare
912f87d
to
c898d46
Compare
Hey @ghiculescu , just stopping by to say thanks for including me as an author on the commit. That's nice of you! If I find time between work and personal life I'll try to weigh in here, but those two things are keeping me pretty busy at the moment :) |
@georgeclaghorn I would love to include this in Rails 7. Do you have any feedback on the direction taken here or anything else you'd like to see included? (let me know if there's a better person to direct this question to) |
c898d46
to
72b9109
Compare
72b9109
to
15426e6
Compare
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
af9cb12
to
fbe8adf
Compare
Co-authored-by: Abhishek Chandrasekhar <me@abhchand.me>
fbe8adf
to
280397c
Compare
Any news on this? I would love to have it in rails 7 |
@ghiculescu can you also add other validators? like presence: true
limit: { min: 1, max: 3 } |
Anything I can do to help get this PR moving along? We would love to see this get merged into Rails and are happy to commit resources to help! |
@tomrossi7 if you're interested in fixing up the conflicts and trying to move this forward, I can give you access to my fork? |
attachment presence validator
if options[:direct_upload_model] | ||
options["data-direct-upload-model"] = options.delete(:direct_upload_model) | ||
elsif options[:object] | ||
options["data-direct-upload-model"] = options[:object].class.name |
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.
Could this be a signed reference (like what Turbo Rails does for Stream names) to prevent tampering?
Similarly, could the model: Post
option be signed in the same way?
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.
Would also need a helper method for when not using FormBuilder
:
<input type=file data-direct-upload-url="<%= rails_direct_uploads_url %>" data-direct-upload-model="<%= rails_direct_uploads_signed_model('Post') %>" />
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.
I also don't see how just the model
is sufficient. Shouldn't it be model.attribute
as models can have more than one attached attribute:
class User < ApplicationRecord
has_one_attached :avatar
has_one_attached :cover_photo
has_many_attached :highlights
end
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.
Could this be a signed reference (like what Turbo Rails does for Stream names) to prevent tampering?
Similarly, could the
model: Post
option be signed in the same way?
Yes, it could use ActiveStorage.verifier
.
Could do something like:
if options[:direct_upload_model_and_attribute] # Note change in name from direct_upload_model to direct_upload_model_and_attribute
options["data-direct-upload-model-and-attribute"] = ActiveStorage.verifier.generate(options.delete(:direct_upload_model_and_attribute))
ActiveStorage.verifier.generate("User.avatar")
=> "BAhJIhBVc2VyLmF2YXRhcgY6BkVU--a6f0ee7e289bbf19f91634986e33c15298a6f408"
ActiveStorage.verifier.verified("BAhJIhBVc2VyLmF2YXRhcgY6BkVU--a6f0ee7e289bbf19f91634986e33c15298a6f408")
=> "User.avatar"
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
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.
Let's see if we can make some progress on this.
validates :avatar, attachment_byte_content_type: { in: %w[image/jpeg image/png] } | ||
validates :avatar, attachment_byte_content_type: { not: %w[application/pdf] } |
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.
Should this be:
validates :avatar, attachment_content_type: { in: %w[image/jpeg image/png] }
validates :avatar, attachment_content_type: { not: %w[application/pdf] }
?
validates :avatar, attachment_byte_content_type: %w[image/jpeg image/png] | ||
validates :avatar, attachment_byte_content_type: "image/jpeg" |
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.
validates :avatar, attachment_content_type: %w[image/jpeg image/png]
validates :avatar, attachment_content_type: "image/jpeg"
?
if options[:direct_upload_model] | ||
options["data-direct-upload-model"] = options.delete(:direct_upload_model) | ||
elsif options[:object] | ||
options["data-direct-upload-model"] = options[:object].class.name |
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.
Would also need a helper method for when not using FormBuilder
:
<input type=file data-direct-upload-url="<%= rails_direct_uploads_url %>" data-direct-upload-model="<%= rails_direct_uploads_signed_model('Post') %>" />
if options[:direct_upload_model] | ||
options["data-direct-upload-model"] = options.delete(:direct_upload_model) | ||
elsif options[:object] | ||
options["data-direct-upload-model"] = options[:object].class.name |
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.
I also don't see how just the model
is sufficient. Shouldn't it be model.attribute
as models can have more than one attached attribute:
class User < ApplicationRecord
has_one_attached :avatar
has_one_attached :cover_photo
has_many_attached :highlights
end
@seanabrahams i don’t have much capacity to work on this at the moment, would you like to take it over? |
@ghiculescu I'll see what I can do 👍 |
This PR is a proposed architecture for validation in Active Storage. It builds on @georgeclaghorn's proposed architecture here: #35390 (comment)
It leans heavily on #35390 - most of the code from that PR is included in it, with some light refactoring.
How it works
There were four high level points in the proposed architecture:
I included the validators in #35390 mostly unchanged.
To do this, Active Storage needs to know the model to run validations for. This is passed as a new data attribute,
data-direct-upload-model
. It's handled automatically if you useFormBuilder#file_field
, or you can add it manually.This attribute eventually makes its way to
ActiveStorage::Blob#valid_with?
, which returns true if:A validator is an "Active Storage validator" if it's a subclass of
ActiveStorage::Validations::BaseValidator
.Tests for this are here.
I haven't explicitly tested for this yet but I believe #35390 handles it.
If the validator is defined, we validate it :)
I'm adding @abhchand as a co-author since I used so much of #35390
Co-authored-by: Abhishek Chandrasekhar me@abhchand.me