diff options
-rw-r--r-- | users/config/initializers/warden.rb | 61 | ||||
-rw-r--r-- | users/lib/leap_web_users/engine.rb | 3 | ||||
-rw-r--r-- | users/lib/warden/session_serializer.rb | 13 | ||||
-rw-r--r-- | users/lib/warden/strategies/secure_remote_password.rb | 57 | ||||
-rw-r--r-- | users/test/functional/sessions_controller_test.rb | 29 |
5 files changed, 89 insertions, 74 deletions
diff --git a/users/config/initializers/warden.rb b/users/config/initializers/warden.rb index 11b950f..45feb6c 100644 --- a/users/config/initializers/warden.rb +++ b/users/config/initializers/warden.rb @@ -5,64 +5,3 @@ end RailsWarden.unauthenticated_action = :new -# Setup Session Serialization -class Warden::SessionSerializer - def serialize(record) - [record.class.name, record.id] - end - - def deserialize(keys) - klass, id = keys - klass.constantize.find(id) - end -end - -Warden::Strategies.add(:secure_remote_password) do - - def valid? - handshake? || authentication? - end - - def authenticate! - if authentication? - validate! - else # handshake - initialize! - end - end - - protected - - def handshake? - params['A'] && params['login'] - end - - def authentication? - params['client_auth'] && session[:handshake] - end - - def validate! - user = session[:handshake].authenticate(params['client_auth'].hex) - user ? success!(user) : fail!(:password => "Could not log in") - end - - def initialize! - user = User.find_by_param(id) - session[:handshake] = user.initialize_auth(params['A'].hex) - custom! json_response(session[:handshake]) - rescue RECORD_NOT_FOUND - fail! :login => "User not found!" - end - - def json_response(object) - [ 200, - {"Content-Type" => "application/json; charset=utf-8"}, - [object.to_json] - ] - end - - def id - params["id"] || params["login"] - end -end - diff --git a/users/lib/leap_web_users/engine.rb b/users/lib/leap_web_users/engine.rb index 42ca072..7033576 100644 --- a/users/lib/leap_web_users/engine.rb +++ b/users/lib/leap_web_users/engine.rb @@ -4,6 +4,9 @@ require "leap_web_core/ui_dependencies" require "rails_warden" require "ruby-srp" +require "warden/session_serializer" +require "warden/strategies/secure_remote_password" + module LeapWebUsers class Engine < ::Rails::Engine diff --git a/users/lib/warden/session_serializer.rb b/users/lib/warden/session_serializer.rb new file mode 100644 index 0000000..81d7076 --- /dev/null +++ b/users/lib/warden/session_serializer.rb @@ -0,0 +1,13 @@ +module Warden + # Setup Session Serialization + class SessionSerializer + def serialize(record) + [record.class.name, record.id] + end + + def deserialize(keys) + klass, id = keys + klass.constantize.find(id) + end + end +end diff --git a/users/lib/warden/strategies/secure_remote_password.rb b/users/lib/warden/strategies/secure_remote_password.rb new file mode 100644 index 0000000..8266e2d --- /dev/null +++ b/users/lib/warden/strategies/secure_remote_password.rb @@ -0,0 +1,57 @@ +module Warden + module Strategies + class SecureRemotePassword < Warden::Strategies::Base + + def valid? + handshake? || authentication? + end + + def authenticate! + if authentication? + validate! + else # handshake + initialize! + end + end + + protected + + def handshake? + params['A'] && params['login'] + end + + def authentication? + params['client_auth'] && session[:handshake] + end + + def validate! + user = session[:handshake].authenticate(params['client_auth'].hex) + user ? success!(user) : fail!(:password => "Could not log in") + end + + def initialize! + user = User.find_by_param(id) + session[:handshake] = user.initialize_auth(params['A'].hex) + custom! json_response(session[:handshake]) + rescue RECORD_NOT_FOUND + fail! :login => "User not found!" + end + + def json_response(object) + [ 200, + {"Content-Type" => "application/json; charset=utf-8"}, + [object.to_json] + ] + end + + def id + params["id"] || params["login"] + end + end + end + Warden::Strategies.add :secure_remote_password, + Warden::Strategies::SecureRemotePassword + +end + + diff --git a/users/test/functional/sessions_controller_test.rb b/users/test/functional/sessions_controller_test.rb index 4bad12f..8f2d95c 100644 --- a/users/test/functional/sessions_controller_test.rb +++ b/users/test/functional/sessions_controller_test.rb @@ -1,5 +1,8 @@ require 'test_helper' +# This is a simple controller unit test. +# We're stubbing out both warden and srp. +# There's an integration test testing the full rack stack and srp class SessionsControllerTest < ActionController::TestCase setup do @@ -30,23 +33,23 @@ class SessionsControllerTest < ActionController::TestCase assert_json_response :errors => strategy.message end + # Warden takes care of parsing the params and + # rendering the response. So not much to test here. test "should perform handshake" do - assert_raises ActionView::MissingTemplate do - request.env['warden'].expects(:authenticate!) - post :create, :login => @user.login, 'A' => @client_hex - assert params['A'] - assert params['login'] - end + request.env['warden'].expects(:authenticate!) + # make sure we don't get a template missing error: + @controller.stubs(:render) + post :create, :login => @user.login, 'A' => @client_hex end test "should authorize" do - assert_raises ActionView::MissingTemplate do - request.env['warden'].expects(:authenticate!) - session[:handshake] = stub - post :update, :id => @user.login, :client_auth => @client_hex - assert params['client_auth'] - assert session[:handshake] - end + request.env['warden'].expects(:authenticate!) + handshake = stub(:to_json => "JSON") + session[:handshake] = handshake + post :update, :id => @user.login, :client_auth => @client_hex + assert_nil session[:handshake] + assert_response :success + assert_equal handshake.to_json, @response.body end test "logout should reset warden user" do |