diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Gemfile.lock | 189 | ||||
-rw-r--r-- | core/lib/extensions/testing.rb | 13 | ||||
-rw-r--r-- | help/test/functional/tickets_controller_test.rb | 36 | ||||
-rw-r--r-- | users/app/controllers/controller_extension/authentication.rb | 4 | ||||
-rw-r--r-- | users/app/controllers/sessions_controller.rb | 18 | ||||
-rw-r--r-- | users/app/views/sessions/new.json.erb | 3 | ||||
-rw-r--r-- | users/config/initializers/warden.rb | 7 | ||||
-rw-r--r-- | users/leap_web_users.gemspec | 1 | ||||
-rw-r--r-- | users/lib/leap_web_users/engine.rb | 4 | ||||
-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/application_controller_test.rb | 7 | ||||
-rw-r--r-- | users/test/functional/helper_methods_test.rb | 15 | ||||
-rw-r--r-- | users/test/functional/sessions_controller_test.rb | 84 | ||||
-rw-r--r-- | users/test/integration/api/account_flow_test.rb | 32 | ||||
-rw-r--r-- | users/test/support/auth_test_helper.rb | 22 | ||||
-rw-r--r-- | users/test/unit/warden_strategy_secure_remote_password_test.rb | 63 |
18 files changed, 269 insertions, 301 deletions
@@ -22,4 +22,4 @@ test/dummy/log/* test/dummy/tmp/* # Ignore configuration file. -config/config.yml
\ No newline at end of file +config/config.ymlGemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 6792476..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,189 +0,0 @@ -PATH - remote: certs - specs: - leap_web_certs (0.1.0) - leap_web_core (= 0.1.0) - -PATH - remote: core - specs: - leap_web_core (0.1.0) - couchrest (~> 1.1.3) - couchrest_model (~> 2.0.0.beta2) - couchrest_session_store (~> 0.0.1) - json - rails (~> 3.2.8) - -PATH - remote: help - specs: - leap_web_help (0.1.0) - leap_web_core (= 0.1.0) - -PATH - remote: users - specs: - leap_web_users (0.1.0) - leap_web_core (= 0.1.0) - ruby-srp (~> 0.1.4) - -GEM - remote: https://rubygems.org/ - remote: http://rubygems.org/ - specs: - actionmailer (3.2.8) - actionpack (= 3.2.8) - mail (~> 2.4.4) - actionpack (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) - builder (~> 3.0.0) - erubis (~> 2.7.0) - journey (~> 1.0.4) - rack (~> 1.4.0) - rack-cache (~> 1.2) - rack-test (~> 0.6.1) - sprockets (~> 2.1.3) - activemodel (3.2.8) - activesupport (= 3.2.8) - builder (~> 3.0.0) - activerecord (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activeresource (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) - activesupport (3.2.8) - i18n (~> 0.6) - multi_json (~> 1.0) - arel (3.0.2) - bootstrap-sass (2.1.0.0) - builder (3.0.3) - coffee-rails (3.2.2) - coffee-script (>= 2.2.0) - railties (~> 3.2.0) - coffee-script (2.2.0) - coffee-script-source - execjs - coffee-script-source (1.3.3) - columnize (0.3.6) - couchrest (1.1.3) - mime-types (~> 1.15) - multi_json (~> 1.0) - rest-client (~> 1.6.1) - couchrest_model (2.0.0.beta2) - activemodel (~> 3.0) - couchrest (~> 1.1.3) - mime-types (~> 1.15) - tzinfo (~> 0.3.22) - couchrest_session_store (0.0.1) - couchrest - couchrest_model - erubis (2.7.0) - execjs (1.4.0) - multi_json (~> 1.0) - haml (3.1.7) - haml-rails (0.3.5) - actionpack (>= 3.1, < 4.1) - activesupport (>= 3.1, < 4.1) - haml (~> 3.1) - railties (>= 3.1, < 4.1) - hike (1.2.1) - i18n (0.6.1) - journey (1.0.4) - jquery-rails (2.1.3) - railties (>= 3.1.0, < 5.0) - thor (~> 0.14) - json (1.7.5) - libv8 (3.3.10.4) - linecache (0.46) - rbx-require-relative (> 0.0.4) - mail (2.4.4) - i18n (>= 0.4.0) - mime-types (~> 1.16) - treetop (~> 1.4.8) - metaclass (0.0.1) - mime-types (1.19) - mocha (0.12.6) - metaclass (~> 0.0.1) - multi_json (1.3.6) - polyglot (0.3.3) - rack (1.4.1) - rack-cache (1.2) - rack (>= 0.4) - rack-ssl (1.3.2) - rack - rack-test (0.6.2) - rack (>= 1.0) - rails (3.2.8) - actionmailer (= 3.2.8) - actionpack (= 3.2.8) - activerecord (= 3.2.8) - activeresource (= 3.2.8) - activesupport (= 3.2.8) - bundler (~> 1.0) - railties (= 3.2.8) - railties (3.2.8) - actionpack (= 3.2.8) - activesupport (= 3.2.8) - rack-ssl (~> 1.3.2) - rake (>= 0.8.7) - rdoc (~> 3.4) - thor (>= 0.14.6, < 2.0) - rake (0.9.2.2) - rbx-require-relative (0.0.9) - rdoc (3.12) - json (~> 1.4) - rest-client (1.6.7) - mime-types (>= 1.16) - ruby-debug (0.10.4) - columnize (>= 0.1) - ruby-debug-base (~> 0.10.4.0) - ruby-debug-base (0.10.4) - linecache (>= 0.3) - ruby-srp (0.1.4) - sass (3.2.1) - sass-rails (3.2.5) - railties (~> 3.2.0) - sass (>= 3.1.10) - tilt (~> 1.3) - simple_form (2.0.4) - actionpack (~> 3.0) - activemodel (~> 3.0) - sprockets (2.1.3) - hike (~> 1.2) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - therubyracer (0.10.2) - libv8 (~> 3.3.10) - thor (0.16.0) - tilt (1.3.3) - treetop (1.4.10) - polyglot - polyglot (>= 0.3.1) - tzinfo (0.3.33) - uglifier (1.2.7) - execjs (>= 0.3.0) - multi_json (~> 1.3) - -PLATFORMS - ruby - -DEPENDENCIES - bootstrap-sass (~> 2.1.0) - coffee-rails (~> 3.2.2) - haml (~> 3.1.7) - haml-rails (~> 0.3.4) - jquery-rails - leap_web_certs! - leap_web_core! - leap_web_help! - leap_web_users! - mocha - ruby-debug - sass-rails (~> 3.2.5) - simple_form - therubyracer - uglifier (~> 1.2.7) diff --git a/core/lib/extensions/testing.rb b/core/lib/extensions/testing.rb index 14a5698..86a059f 100644 --- a/core/lib/extensions/testing.rb +++ b/core/lib/extensions/testing.rb @@ -1,15 +1,22 @@ module LeapWebCore module AssertResponses + # response that works with different TestCases: + # ActionController::TestCase has @response + # ActionDispatch::IntegrationTest has @response + # Rack::Test::Methods defines last_response + def get_response + @response || last_response + end + def assert_attachement_filename(name) assert_equal %Q(attachment; filename="#{name}"), - @response.headers["Content-Disposition"] + get_response.headers["Content-Disposition"] end - def assert_json_response(object) object.stringify_keys! if object.respond_to? :stringify_keys! - assert_equal object, JSON.parse(@response.body) + assert_equal object, JSON.parse(get_response.body) end end diff --git a/help/test/functional/tickets_controller_test.rb b/help/test/functional/tickets_controller_test.rb index 8fae44c..bb17acc 100644 --- a/help/test/functional/tickets_controller_test.rb +++ b/help/test/functional/tickets_controller_test.rb @@ -24,14 +24,15 @@ class TicketsControllerTest < ActionController::TestCase assert_difference('Ticket.count') do post :create, :ticket => params end - + assert_response :redirect #assert_equal assigns(:ticket).email, User.current.email #assert_equal User.find(assigns(:ticket).created_by).login, User.current.login assert_nil assigns(:ticket).created_by - assert_equal assigns(:ticket).comments.count, 1 + assert_equal 1, assigns(:ticket).comments.count assigns(:ticket).destroy # destroys without checking permission. is that okay? + end @@ -39,33 +40,36 @@ class TicketsControllerTest < ActionController::TestCase params = {:title => "ticket test title", :comments_attributes => {"0" => {"body" =>"body of test ticket"}}} - #todo: should redo this and actually authorize - user = User.last - session[:user_id] = user.id + login User.last assert_difference('Ticket.count') do post :create, :ticket => params end assert_response :redirect - assert_equal assigns(:ticket).created_by, user.id - assert_equal assigns(:ticket).email, user.email - - assert_equal assigns(:ticket).comments.count, 1 + ticket = assigns(:ticket) + assert ticket + assert_equal @current_user.id, ticket.created_by + assert_equal @current_user.email, ticket.email + assert_equal 1, assigns(:ticket).comments.count assigns(:ticket).destroy # ? end test "add comment to unauthenticated ticket" do - t = Ticket.last - t.created_by = nil # TODO: hacky, but this makes sure this ticket is an unauthenticated one - t.save - comment_count = t.comments.count - put :update, :id => t.id, :ticket => {:comments_attributes => {"0" => {"body" =>"NEWER comment"}} } - assert_equal(comment_count + 1, assigns(:ticket).comments.count) + ticket = Ticket.last + ticket.created_by = nil # TODO: hacky, but this makes sure this ticket is an unauthenticated one + ticket.save +# comment_count = t.comments.count +# put :update, :id => t.id, :ticket => {:comments_attributes => {"0" => {"body" =>"NEWER comment"}} } +# assert_equal(comment_count + 1, assigns(:ticket).comments.count) #assert_difference block isn't working - end + assert_difference('Ticket.last.comments.count') do + put :update, :id => ticket.id, + :ticket => {:comments_attributes => {"0" => {"body" =>"NEWER comment"}} } + end + assert_equal ticket, assigns(:ticket) test "add comment to authenticated ticket" do diff --git a/users/app/controllers/controller_extension/authentication.rb b/users/app/controllers/controller_extension/authentication.rb index e27b4da..1726278 100644 --- a/users/app/controllers/controller_extension/authentication.rb +++ b/users/app/controllers/controller_extension/authentication.rb @@ -7,8 +7,8 @@ module ControllerExtension::Authentication helper_method :current_user, :logged_in?, :admin? end - def current_user - @current_user ||= User.find(session[:user_id]) if session[:user_id] + def authentication_error + warden.winning_strategy.try(:message) end def logged_in? diff --git a/users/app/controllers/sessions_controller.rb b/users/app/controllers/sessions_controller.rb index 4a1107d..486f67e 100644 --- a/users/app/controllers/sessions_controller.rb +++ b/users/app/controllers/sessions_controller.rb @@ -3,28 +3,20 @@ class SessionsController < ApplicationController skip_before_filter :verify_authenticity_token def new + @errors = authentication_error end def create - @user = User.find_by_param(params[:login]) - session[:handshake] = @user.initialize_auth(params['A'].hex) - render :json => session[:handshake] - rescue RECORD_NOT_FOUND - render :json => {:errors => {:login => ["unknown user"]}} + authenticate! end def update - @srp_session = session.delete(:handshake) - @user = @srp_session.authenticate!(params[:client_auth].hex) - session[:user_id] = @user.id - render :json => @srp_session - rescue WRONG_PASSWORD - session[:handshake] = nil - render :json => {:errors => {"password" => ["wrong password"]}} + authenticate! + render :json => session.delete(:handshake) end def destroy - session[:user_id] = nil + logout redirect_to root_path end end diff --git a/users/app/views/sessions/new.json.erb b/users/app/views/sessions/new.json.erb new file mode 100644 index 0000000..36154b8 --- /dev/null +++ b/users/app/views/sessions/new.json.erb @@ -0,0 +1,3 @@ +{ +"errors": <%= raw @errors.to_json %> +} diff --git a/users/config/initializers/warden.rb b/users/config/initializers/warden.rb new file mode 100644 index 0000000..45feb6c --- /dev/null +++ b/users/config/initializers/warden.rb @@ -0,0 +1,7 @@ +Rails.configuration.middleware.use RailsWarden::Manager do |config| + config.default_strategies :secure_remote_password + config.failure_app = SessionsController +end + +RailsWarden.unauthenticated_action = :new + diff --git a/users/leap_web_users.gemspec b/users/leap_web_users.gemspec index dec5a71..0682a99 100644 --- a/users/leap_web_users.gemspec +++ b/users/leap_web_users.gemspec @@ -18,4 +18,5 @@ Gem::Specification.new do |s| s.add_dependency "leap_web_core", LeapWeb::VERSION s.add_dependency "ruby-srp", "~> 0.1.4" + s.add_dependency "rails_warden" end diff --git a/users/lib/leap_web_users/engine.rb b/users/lib/leap_web_users/engine.rb index 9b7545e..7033576 100644 --- a/users/lib/leap_web_users/engine.rb +++ b/users/lib/leap_web_users/engine.rb @@ -1,8 +1,12 @@ # thou shall require all your dependencies in an engine. require "leap_web_core" 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/application_controller_test.rb b/users/test/functional/application_controller_test.rb index b228b1d..94b77bd 100644 --- a/users/test/functional/application_controller_test.rb +++ b/users/test/functional/application_controller_test.rb @@ -8,20 +8,19 @@ class ApplicationControllerTest < ActionController::TestCase end def test_authorize_redirect - stub_logged_out #broken? @controller.send(:authorize) assert_access_denied(true, false) end def test_authorized - @user = stub_logged_in + login @controller.send(:authorize) assert_access_denied(false) end def test_authorize_admin - @user = stub_logged_in - @user.expects(:is_admin?).returns(false) + login + @current_user.expects(:is_admin?).returns(false) @controller.send(:authorize_admin) assert_access_denied end diff --git a/users/test/functional/helper_methods_test.rb b/users/test/functional/helper_methods_test.rb index c0eaf61..2b2375c 100644 --- a/users/test/functional/helper_methods_test.rb +++ b/users/test/functional/helper_methods_test.rb @@ -16,26 +16,23 @@ class HelperMethodsTest < ActionController::TestCase @controller end - def test_current_user_with_caching - @user = stub_logged_in - assert_equal @user, current_user - assert_equal @user, current_user # tests caching + def test_current_user + login + assert_equal @current_user, current_user end def test_logged_in - @user = stub_logged_in + login assert logged_in? end def test_logged_out - stub_logged_out assert !logged_in? end def test_admin - bool = stub - @user = stub_logged_in - @user.expects(:is_admin?).returns(bool) + login + @current_user.expects(:is_admin?).returns(bool = stub) assert_equal bool, admin? end diff --git a/users/test/functional/sessions_controller_test.rb b/users/test/functional/sessions_controller_test.rb index 47d7052..8f2d95c 100644 --- a/users/test/functional/sessions_controller_test.rb +++ b/users/test/functional/sessions_controller_test.rb @@ -1,75 +1,71 @@ 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 - def setup + setup do @user = stub :login => "me", :id => 123 @client_hex = 'a123' - @client_rnd = @client_hex.hex - @server_hex = 'b123' - @server_rnd = @server_hex.hex - @server_rnd_exp = 'e123'.hex - @salt = 'stub user salt' - @server_handshake = stub :aa => @client_rnd, :bb => @server_rnd, :b => @server_rnd_exp - @server_auth = 'adfe' end test "should get login screen" do + request.env['warden'].expects(:winning_strategy) get :new assert_response :success + assert_equal "text/html", response.content_type + assert_template "sessions/new" end - test "should perform handshake" do - @user.expects(:initialize_auth). - with(@client_rnd). - returns(@server_handshake) - @server_handshake.expects(:to_json). - returns({'B' => @server_hex, 'salt' => @salt}.to_json) - User.expects(:find_by_param).with(@user.login).returns(@user) - post :create, :login => @user.login, 'A' => @client_hex - assert_equal @server_handshake, session[:handshake] + test "renders json" do + request.env['warden'].expects(:winning_strategy) + get :new, :format => :json assert_response :success - assert_json_response :B => @server_hex, :salt => @salt + assert_json_response :errors => nil end - test "should report user not found" do - unknown = "login_that_does_not_exist" - User.expects(:find_by_param).with(unknown).raises(RECORD_NOT_FOUND) - post :create, :login => unknown + test "renders warden errors" do + strategy = stub :message => "Warden auth did not work" + request.env['warden'].expects(:winning_strategy).returns(strategy) + get :new, :format => :json assert_response :success - assert_json_response :errors => {"login" => ["unknown user"]} + assert_json_response :errors => strategy.message end - test "should authorize" do - session[:handshake] = @server_handshake - @server_handshake.expects(:authenticate!). - with(@client_rnd). - returns(@user) - @server_handshake.expects(:to_json). - returns({:M2 => @server_auth}.to_json) - post :update, :id => @user.login, :client_auth => @client_hex - assert_nil session[:handshake] - assert_json_response :M2 => @server_auth - assert_equal @user.id, session[:user_id] + # Warden takes care of parsing the params and + # rendering the response. So not much to test here. + test "should perform handshake" do + 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 report wrong password" do - session[:handshake] = @server_handshake - @server_handshake.expects(:authenticate!). - with(@client_rnd). - raises(WRONG_PASSWORD) + test "should authorize" do + 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_nil session[:user_id] - assert_json_response :errors => {"password" => ["wrong password"]} + assert_response :success + assert_equal handshake.to_json, @response.body end - test "logout should reset sessions user_id" do - session[:user_id] = "set" + test "logout should reset warden user" do + expect_warden_logout delete :destroy - assert_nil session[:user_id] assert_response :redirect assert_redirected_to root_url end + def expect_warden_logout + raw = mock('raw session') do + expects(:inspect) + end + request.env['warden'].expects(:raw_session).returns(raw) + request.env['warden'].expects(:logout) + end + + end diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb index 5800d46..c9a7109 100644 --- a/users/test/integration/api/account_flow_test.rb +++ b/users/test/integration/api/account_flow_test.rb @@ -1,12 +1,26 @@ require 'test_helper' -class AccountFlowTest < ActionDispatch::IntegrationTest +CONFIG_RU = (Rails.root + 'config.ru').to_s +OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first + +class AccountFlowTest < ActiveSupport::TestCase + include Rack::Test::Methods + include Warden::Test::Helpers + include LeapWebCore::AssertResponses + + def app + OUTER_APP + end + + def teardown + Warden.test_reset! + end # this test wraps the api and implements the interface the ruby-srp client. def handshake(login, aa) - post "sessions", :login => login, 'A' => aa.to_s(16) - assert_response :success - response = JSON.parse(@response.body) + post "/sessions.json", :login => login, 'A' => aa.to_s(16), :format => :json + assert last_response.successful? + response = JSON.parse(last_response.body) if response['errors'] raise RECORD_NOT_FOUND.new(response['errors']) else @@ -15,9 +29,9 @@ class AccountFlowTest < ActionDispatch::IntegrationTest end def validate(m) - put "sessions/" + @login, :client_auth => m.to_s(16) - assert_response :success - return JSON.parse(@response.body) + put "/sessions/" + @login + '.json', :client_auth => m.to_s(16), :format => :json + assert last_response.successful? + return JSON.parse(last_response.body) end def setup @@ -40,7 +54,7 @@ class AccountFlowTest < ActionDispatch::IntegrationTest test "signup response" do assert_json_response :login => @login, :ok => true - assert_response :success + assert last_response.successful? end test "signup and login with srp via api" do @@ -52,7 +66,7 @@ class AccountFlowTest < ActionDispatch::IntegrationTest test "signup and wrong password login attempt" do srp = SRP::Client.new(@login, "wrong password") server_auth = srp.authenticate(self) - assert_equal ["wrong password"], server_auth["errors"]['password'] + assert_equal "Could not log in", server_auth["errors"]['password'] assert_nil server_auth["M2"] end diff --git a/users/test/support/auth_test_helper.rb b/users/test/support/auth_test_helper.rb index 37aef34..795a977 100644 --- a/users/test/support/auth_test_helper.rb +++ b/users/test/support/auth_test_helper.rb @@ -1,18 +1,18 @@ module AuthTestHelper + extend ActiveSupport::Concern - def stub_logged_in - @user_id = stub - @user = stub - session[:user_id] = @user_id - User.expects(:find).once.with(@user_id).returns(@user) - return @user + # Controller will fetch current user from warden. + # Make it pick up our current_user + included do + setup do + request.env['warden'] ||= stub :user => nil + end end - def stub_logged_out - #todo: this seems wrong. - @user_id = stub - session[:user_id] = @user_id - User.expects(:find).once.with(@user_id).returns(nil) + def login(user = nil) + @current_user = user || stub + request.env['warden'] = stub :user => @current_user + return @current_user end def assert_access_denied(denied = true, logged_in = true) diff --git a/users/test/unit/warden_strategy_secure_remote_password_test.rb b/users/test/unit/warden_strategy_secure_remote_password_test.rb new file mode 100644 index 0000000..79480f0 --- /dev/null +++ b/users/test/unit/warden_strategy_secure_remote_password_test.rb @@ -0,0 +1,63 @@ +class WardenStrategySecureRemotePasswordTest < ActiveSupport::TestCase + +# TODO : turn this into sth. real +=begin + setup do + @user = stub :login => "me", :id => 123 + @client_hex = 'a123' + @client_rnd = @client_hex.hex + @server_hex = 'b123' + @server_rnd = @server_hex.hex + @server_rnd_exp = 'e123'.hex + @salt = 'stub user salt' + @server_handshake = stub :aa => @client_rnd, :bb => @server_rnd, :b => @server_rnd_exp + @server_auth = 'adfe' + end + + + test "should perform handshake" do + @user.expects(:initialize_auth). + with(@client_rnd). + returns(@server_handshake) + @server_handshake.expects(:to_json). + returns({'B' => @server_hex, 'salt' => @salt}.to_json) + User.expects(:find_by_param).with(@user.login).returns(@user) + assert_equal @server_handshake, session[:handshake] + assert_response :success + assert_json_response :B => @server_hex, :salt => @salt + end + + test "should report user not found" do + unknown = "login_that_does_not_exist" + User.expects(:find_by_param).with(unknown).raises(RECORD_NOT_FOUND) + post :create, :login => unknown + assert_response :success + assert_json_response :errors => {"login" => ["unknown user"]} + end + + test "should authorize" do + session[:handshake] = @server_handshake + @server_handshake.expects(:authenticate!). + with(@client_rnd). + returns(@user) + @server_handshake.expects(:to_json). + returns({:M2 => @server_auth}.to_json) + post :update, :id => @user.login, :client_auth => @client_hex + assert_nil session[:handshake] + assert_json_response :M2 => @server_auth + assert_equal @user.id, session[:user_id] + end + + test "should report wrong password" do + session[:handshake] = @server_handshake + @server_handshake.expects(:authenticate!). + with(@client_rnd). + raises(WRONG_PASSWORD) + post :update, :id => @user.login, :client_auth => @client_hex + assert_nil session[:handshake] + assert_nil session[:user_id] + assert_json_response :errors => {"password" => ["wrong password"]} + end + +=end +end |