Created
February 17, 2024 22:32
-
-
Save darrenboyd/6f77557ad799913c44aa3b3984b38089 to your computer and use it in GitHub Desktop.
Example of overriding ActiveStorage controllers for authentication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Storage::DirectUploadsController < ActiveStorage::DirectUploadsController | |
include AuthenticationSupport | |
include Pundit::Authorization | |
before_action :authenticate_user! | |
before_action :require_admin | |
protected | |
def require_admin | |
unless current_user.is_admin? | |
raise Pundit::NotAuthorizedError | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class Storage::Blobs::RedirectController < ActiveStorage::Blobs::RedirectController | |
include AuthenticationSupport | |
include Pundit::Authorization | |
# maybe, or maybe not, depending on the context of the blob? | |
before_action :authenticate_user! | |
def show | |
# grab whatever relationship is important from the blob... | |
content = @blob.attachments.first.record.content | |
unless current_user.is_admin? | |
authorize # ... something, depending on your models and context | |
end | |
super | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rails.application.routes.draw do | |
# ... all your routes... | |
# ============================================== | |
# ============= ActiveStorage ================== | |
# ============================================== | |
# Largely copied these out of the active-storage source, | |
# to point them at our own set of controllers when needed. | |
scope ActiveStorage.routes_prefix do | |
get "/blobs/redirect/:signed_id/*filename" => "storage/blobs/redirect#show", as: :rails_service_blob | |
get "/blobs/:signed_id/*filename" => "storage/blobs/redirect#show" | |
# get "/representations/redirect/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirect#show", as: :rails_blob_representation | |
# get "/representations/:signed_blob_id/:variation_key/*filename" => "active_storage/representations/redirect#show" | |
# These two can stay, as the disk service is only used in development | |
get "/disk/:encoded_key/*filename" => "active_storage/disk#show", as: :rails_disk_service | |
put "/disk/:encoded_token" => "active_storage/disk#update", as: :update_rails_disk_service | |
post "/direct_uploads" => "storage/direct_uploads#create", as: :rails_direct_uploads | |
end | |
# direct :rails_representation do |representation, options| | |
# route_for(ActiveStorage.resolve_model_to_route, representation, options) | |
# end | |
resolve("ActiveStorage::Variant") { |variant, options| route_for(ActiveStorage.resolve_model_to_route, variant, options) } | |
resolve("ActiveStorage::VariantWithRecord") { |variant, options| route_for(ActiveStorage.resolve_model_to_route, variant, options) } | |
resolve("ActiveStorage::Preview") { |preview, options| route_for(ActiveStorage.resolve_model_to_route, preview, options) } | |
direct :rails_blob do |blob, options| | |
route_for(ActiveStorage.resolve_model_to_route, blob, options) | |
end | |
resolve("ActiveStorage::Blob") { |blob, options| route_for(ActiveStorage.resolve_model_to_route, blob, options) } | |
resolve("ActiveStorage::Attachment") { |attachment, options| route_for(ActiveStorage.resolve_model_to_route, attachment.blob, options) } | |
direct :rails_storage_redirect do |model, options| | |
expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in } | |
expires_at = options.delete(:expires_at) | |
if model.respond_to?(:signed_id) | |
route_for( | |
:rails_service_blob, | |
model.signed_id(expires_in: expires_in, expires_at: expires_at), | |
model.filename, | |
options | |
) | |
else | |
signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at) | |
variation_key = model.variation.key | |
filename = model.blob.filename | |
route_for( | |
:rails_blob_representation, | |
signed_blob_id, | |
variation_key, | |
filename, | |
options | |
) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment