diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2017-07-31 15:21:22 -0400 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2017-07-31 15:21:22 -0400 |
commit | 9330d01ada9ce6768d14c59b99cd3860e209737a (patch) | |
tree | e4328b4e59b52dae35241f835f786641d1ff8595 /activestorage/app/controllers | |
parent | 0d58e7e478e79c2d6b2a39a4444d2a17a903b2a6 (diff) | |
parent | 3f4a7218a4a4923a0e7ce1b2eb0d2888ce30da58 (diff) | |
download | rails-9330d01ada9ce6768d14c59b99cd3860e209737a.tar.gz rails-9330d01ada9ce6768d14c59b99cd3860e209737a.tar.bz2 rails-9330d01ada9ce6768d14c59b99cd3860e209737a.zip |
Add 'activestorage/' from commit '3f4a7218a4a4923a0e7ce1b2eb0d2888ce30da58'
git-subtree-dir: activestorage
git-subtree-mainline: 0d58e7e478e79c2d6b2a39a4444d2a17a903b2a6
git-subtree-split: 3f4a7218a4a4923a0e7ce1b2eb0d2888ce30da58
Diffstat (limited to 'activestorage/app/controllers')
4 files changed, 122 insertions, 0 deletions
diff --git a/activestorage/app/controllers/active_storage/blobs_controller.rb b/activestorage/app/controllers/active_storage/blobs_controller.rb new file mode 100644 index 0000000000..05af29f8b2 --- /dev/null +++ b/activestorage/app/controllers/active_storage/blobs_controller.rb @@ -0,0 +1,22 @@ +# Take a signed permanent reference for a blob and turn it into an expiring service URL for download. +# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the +# security-through-obscurity factor of the signed blob references, you'll need to implement your own +# authenticated redirection controller. +class ActiveStorage::BlobsController < ActionController::Base + def show + if blob = find_signed_blob + redirect_to blob.service_url(disposition: disposition_param) + else + head :not_found + end + end + + private + def find_signed_blob + ActiveStorage::Blob.find_signed(params[:signed_id]) + end + + def disposition_param + params[:disposition].presence_in(%w( inline attachment )) || "inline" + end +end diff --git a/activestorage/app/controllers/active_storage/direct_uploads_controller.rb b/activestorage/app/controllers/active_storage/direct_uploads_controller.rb new file mode 100644 index 0000000000..0d93985897 --- /dev/null +++ b/activestorage/app/controllers/active_storage/direct_uploads_controller.rb @@ -0,0 +1,21 @@ +# Creates a new blob on the server side in anticipation of a direct-to-service upload from the client side. +# When the client-side upload is completed, the signed_blob_id can be submitted as part of the form to reference +# the blob that was created up front. +class ActiveStorage::DirectUploadsController < ActionController::Base + def create + blob = ActiveStorage::Blob.create_before_direct_upload!(blob_args) + render json: direct_upload_json(blob) + end + + private + def blob_args + params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, :metadata).to_h.symbolize_keys + end + + def direct_upload_json(blob) + blob.as_json(methods: :signed_id).merge(direct_upload: { + url: blob.service_url_for_direct_upload, + headers: blob.service_headers_for_direct_upload + }) + end +end diff --git a/activestorage/app/controllers/active_storage/disk_controller.rb b/activestorage/app/controllers/active_storage/disk_controller.rb new file mode 100644 index 0000000000..76377a0f20 --- /dev/null +++ b/activestorage/app/controllers/active_storage/disk_controller.rb @@ -0,0 +1,51 @@ +# Serves files stored with the disk service in the same way that the cloud services do. +# This means using expiring, signed URLs that are meant for immediate access, not permanent linking. +# Always go through the BlobsController, or your own authenticated controller, rather than directly +# to the service url. +class ActiveStorage::DiskController < ActionController::Base + def show + if key = decode_verified_key + send_data disk_service.download(key), + filename: params[:filename], disposition: disposition_param, content_type: params[:content_type] + else + head :not_found + end + end + + def update + if token = decode_verified_token + if acceptable_content?(token) + disk_service.upload token[:key], request.body, checksum: token[:checksum] + else + head :unprocessable_entity + end + else + head :not_found + end + rescue ActiveStorage::IntegrityError + head :unprocessable_entity + end + + private + def disk_service + ActiveStorage::Blob.service + end + + + def decode_verified_key + ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key) + end + + def disposition_param + params[:disposition].presence_in(%w( inline attachment )) || "inline" + end + + + def decode_verified_token + ActiveStorage.verifier.verified(params[:encoded_token], purpose: :blob_token) + end + + def acceptable_content?(token) + token[:content_type] == request.content_type && token[:content_length] == request.content_length + end +end diff --git a/activestorage/app/controllers/active_storage/variants_controller.rb b/activestorage/app/controllers/active_storage/variants_controller.rb new file mode 100644 index 0000000000..aa38f8e928 --- /dev/null +++ b/activestorage/app/controllers/active_storage/variants_controller.rb @@ -0,0 +1,28 @@ +require "active_storage/variant" + +# Take a signed permanent reference for a variant and turn it into an expiring service URL for download. +# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the +# security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own +# authenticated redirection controller. +class ActiveStorage::VariantsController < ActionController::Base + def show + if blob = find_signed_blob + redirect_to ActiveStorage::Variant.new(blob, decoded_variation).processed.service_url(disposition: disposition_param) + else + head :not_found + end + end + + private + def find_signed_blob + ActiveStorage::Blob.find_signed(params[:signed_blob_id]) + end + + def decoded_variation + ActiveStorage::Variation.decode(params[:variation_key]) + end + + def disposition_param + params[:disposition].presence_in(%w( inline attachment )) || "inline" + end +end |