lib/roda/plugins/http_auth.rb in roda-http-auth-0.1.2 vs lib/roda/plugins/http_auth.rb in roda-http-auth-0.2.0
- old
+ new
@@ -3,70 +3,64 @@
module Roda::RodaPlugins
module HttpAuth
DEFAULTS = {
realm: "Restricted Area",
- unauthorized_headers: proc do |opts|
- {'Content-Type' => 'text/plain',
- 'Content-Length' => '0',
- 'WWW-Authenticate' => ('Basic realm="%s"' % opts[:realm])}
+ unauthorized_headers: ->(opts) do
+ { 'WWW-Authenticate' => ('Basic realm="%s"' % opts[:realm]) }
end,
- bad_request_headers: proc do |opts|
- {'Content-Type' => 'text/plain', 'Content-Length' => '0'}
- end,
+ unauthorized: ->(r) {},
schemes: %w[basic]
}
def self.configure(app, opts={})
plugin_opts = (app.opts[:http_auth] ||= DEFAULTS)
app.opts[:http_auth] = plugin_opts.merge(opts)
app.opts[:http_auth].freeze
end
- module RequestMethods
+ module InstanceMethods
def http_auth(opts={}, &authenticator)
- auth_opts = roda_class.opts[:http_auth].merge(opts)
+ auth_opts = request.roda_class.opts[:http_auth].merge(opts)
authenticator ||= auth_opts[:authenticator]
raise "Must provide an authenticator block" if authenticator.nil?
- begin
- auth = Rack::Auth::Basic::Request.new(env)
+ auth = Rack::Auth::Basic::Request.new(env)
- unless auth.provided? && auth_opts[:schemes].include?(auth.scheme)
- auth_opts[:unauthorized].call(self) if auth_opts[:unauthorized]
- halt [401, auth_opts[:unauthorized_headers].call(auth_opts), []]
- end
+ unless auth.provided? && auth_opts[:schemes].include?(auth.scheme)
+ unauthorized(auth_opts)
+ end
- credentials = if auth.basic?
- auth.credentials
- elsif auth.scheme == 'bearer'
- [env['HTTP_AUTHORIZATION'].strip.split(' ').last]
- else
- [auth.scheme, _extract_credentials]
- end
+ credentials = if auth.basic?
+ auth.credentials
+ elsif auth.scheme == 'bearer'
+ [env['HTTP_AUTHORIZATION'].split(' ', 2).last]
+ else
+ http_auth = env['HTTP_AUTHORIZATION'].split(' ', 2)
+ .last
- if authenticator.call(*credentials)
- env['REMOTE_USER'] = auth.username
- else
- opts[:unauthorized].call(self) if auth_opts[:unauthorized]
- halt [401, auth_opts[:unauthorized_headers].call(auth_opts), []]
- end
- rescue StandardError
- halt [400, auth_opts[:bad_request_headers].call(auth_opts), []]
+ creds = !http_auth.include?('=') ? http_auth :
+ Rack::Auth::Digest::Params.parse(http_auth)
+
+ [auth.scheme, creds]
+ end
+
+ if authenticator.call(*credentials)
+ env['REMOTE_USER'] = auth.username
+ else
+ unauthorized(auth_opts)
end
end
- def _extract_credentials
- authorization = env['HTTP_AUTHORIZATION'].split(' ', 2).last
- parts = authorization.split(',')
+ private
- return parts.first if parts.one? && !parts.first.include?('=')
+ def unauthorized(opts)
+ response.status = 401
+ response.headers.merge!(opts[:unauthorized_headers].call(opts))
- key_values = parts.map {|p| p.strip.split(/\=\"?/) }
- .map {|k, v| [k, v.chomp('"').gsub(/\\\"/, '"')] }
-
- Hash[key_values]
+ request.block_result(instance_exec(request, &opts[:unauthorized]))
+ request.halt response.finish
end
end
end
register_plugin(:http_auth, HttpAuth)