-
Notifications
You must be signed in to change notification settings - Fork 244
Example: Authentication
Mark Evans edited this page Apr 29, 2015
·
1 revision
the user checking logick requires Devise / Warden
basic config:
class Media < ActiveRecord::Base
belongs_to :user
dragonfly_accessor :file, app: :private
end
Dragonfly.app(:private).configure do
secret "..."
url_format "/private/:job/:sha/:name"
# prevent users from getting cached responses without authentication.
# warning: this will cause processing to occur every time the file is requested
response_header 'Cache-Control', 'private'
datastore :file,
root_path: Rails.root.join('private/dragonfly', Rails.env),
server_root: nil # disable remote urls
end
if only downloading with no processing is required one of the following snippets can be used
Dragonfly.app(:private).configure do
define_url do |app, job, opts|
if job.step_types == [:fetch]
"/download/#{job.uid}"
else
app.server.url_for(job, opts)
end
end
end
MyApp::Application.routes.draw do
get "/download/*uid", format: false, to: Dragonfly.app(:private).endpoint { |params, app, env|
user = env['warden'].user :user
file = Media.where(file_uid: params[:uid]).first
if file and user and file.user_id == user.id
app.fetch params[:uid]
end
}
end
MyApp::Application.routes.draw do
get "/private/:job/:sha/*name", to: Dragonfly.app(:private).endpoint { |params, app, env|
job = Dragonfly::Job.deserialize params[:job], app
app.server.instance_eval { validate_job! job }
job.validate_sha!(params[:sha]) if app.server.verify_urls
if job.fetch_step
user = env['warden'].user :user
file = Media.where(file_uid: job.fetch_step.uid).first
if file and user and file.user_id == user.id
app.fetch job.fetch_step.uid
end
end
}
end
to allow complete jobs job
can be returned instead of app.fetch uid
. but then using the before_serve
block instead of a custom route is probaby a better.
Dragonfly.app(:private).configure do
before_serve do |job, env|
user = env['warden'].user :user # get devise user from scope 'user'
throw :halt, [401, {"Content-Type" => "text/plain"}, ["Unauthorized"]] unless user
# throw :halt, [400, {"Content-Type" => "text/plain"}, ["Bad Request"]] if job.step_types != [:fetch] # only allow download
# get Media Object the uid belongs to to check authorization.
# warning: if processors are present which allow multiple fetches authorization is performed only for one of them
if job.fetch_step
file = Media.where(file_uid: job.fetch_step.uid).first
if file
if file.user_id == user.id
# allow if user_id matches
else
throw :halt, [403, {"Content-Type" => "text/plain"}, ["Forbidden"]]
end
else
# explicitly 404 here to avoid sending files which are no longer in the database but still exist on disk
throw :halt, [404, {"Content-Type" => "text/plain"}, ["Not Found"]]
end
else
# allow fetch_file, fetch_url and generate
end
end
end
Rails.application.middleware.use Dragonfly::Middleware, :private