require 'rack/utils' require 'rack/cerberus/version' module Rack class Cerberus class NoSessionError < RuntimeError; end def self.new(*); ::Rack::MethodOverride.new(super); end def initialize app, options={}, &block @app = app defaults = { company_name: 'Cerberus', bg_color: '#93a1a1', fg_color: '#002b36', text_color: '#fdf6e3', session_key: 'cerberus_user' } @options = defaults.merge(options) @options[:icon] = @options[:icon_url].nil? ? '' : "
" @options[:css] = @options[:css_location].nil? ? '' : "" @block = block end def call env dup._call(env) end def _call env ensure_session env req = Rack::Request.new env if (logged?(req) and !logging_out?(req)) or authorized?(req) ensure_logged! req if logging_out? req logout_response req else @app.call env end else form_response req end end private def ensure_session env if env['rack.session'].nil? raise(NoSessionError, 'Cerberus cannot work without Session') end end def h text Rack::Utils.escape_html text end def login req req.params['cerberus_login'] end def pass req req.params['cerberus_pass'] end def logged? req req.env['rack.session'][@options[:session_key]]!=nil end def provided_fields? req login(req) and pass(req) end def authorized? req provided_fields?(req) and @block.call login(req), pass(req), req end def ensure_logged! req req.env['rack.session'][@options[:session_key]] ||= login(req) end def ensure_logged_out! req req.env['rack.session'].delete @options[:session_key] end def logging_out? req req.path_info=='/logout' end def logout_response req res = Rack::Response.new res.redirect(req.script_name=='' ? '/' : req.script_name) res.finish end def form_response req if provided_fields? req error = "

Wrong login or password

" end ensure_logged_out! req [ 401, {'Content-Type' => 'text/html'}, [AUTH_PAGE % @options.merge({ error: error, submit_path: req.env['REQUEST_URI'], request_method: req.request_method, login: h(login(req)), pass: h(pass(req)) })] ] end AUTH_PAGE = <<-PAGE %{company_name} Authentication %{css}

%{company_name}

%{icon} %{error}

Please Sign In


PAGE end end